2014-04-25 02:00 AM
All,
1.) I took 128, 16-bit data points and created a sine wave: const uint16_t Sine12bit[128] = { 2047, 2447, 2831, 3185, 3498, 3750, 3939, 4056, 4095, 4056, 3939, 3750, 3495, 3185, 2831, 2447, 2047, 1647, 1263, 909, 599, 344, 155, 38, .... 4095, 4056, 3939, 3750, 3495, 3185, 2831, 2447, 2047, 1647, 1263, 909, 599, 344, 155, 38, 0, 38, 155, 344, 599, 909, 1263, 1647}; 2.) I broke this into 256 bytes (8-bits) and wrote out to a page (1 page = 256 bytes) of my SPI based serial flash. 3.) I then wrote out this same data to all the other pages of my SPI based serial flash. There are a total of 16,384 pages. 4.) I am then reading each page at a time playing a tone (the waveform) out with the DAC. Using a combination of the DAC,Timer2, DMA, and interrupts. 5.) When I measure the frequency of the generated waveform, it looks nice an clean with a frequency of 6.25kHz. 6.) For the Timer2 configuration the period is setup usign the following line: Period = (SystemCoreClock / 200000); // 6.25 KHz Sine The SystemCoreClock is 48 MHz. 7.) When I play this tone reading for all the pages of memory it only lasts about 10 seconds. 8.) I am not clear on a few things: - I don't see how I can get 6.25 kHz based on the line above. 48MHz / 200000 = 240. 1/240 = 0.0041? - Based on the size of the pages of memory (256), total memory size (16,384 pages) and the timer2 settings above how long should it take to read through the entire memory? The 10 seconds seems too short. - For recording and playign back voice I want to be operating at a 16 kHz for the sample rate. If I am sampling 128 (16-bit) values from the ADC and write out 256 bytes to my SPI flash how should the timer be setup? What should the divider be? - How much recording time should I get with a sample rate of 16 kHz? - Any other suggestions to help my understanding? Thanks. -Mike2014-04-25 04:26 AM
6.) For the Timer2 configuration the period is setup using the following line:
Period = (SystemCoreClock / 200000); // 6.25 KHz Sine
The SystemCoreClock is 48 MHz.
7.) When I play this tone reading for all the pages of memory it only lasts about 10 seconds.
8.) I am not clear on a few things:
- I don't see how I can get 6.25 kHz based on the line above. 48MHz / 200000 = 240. 1/240 = 0.0041? The original example this was lifted from has a 200 KHz sample rate, and a 32 entry sine table. The line sets the period of the timer to 200 KHZ. 200000 / 32 = 6250 48000000 / 200000 = 240 Conversely 48000000 / 240 = 200000
2014-04-28 10:25 PM
Thanks for the post.
Okay so if I want a 16 kHz sampling this is a period of 6.25e^-5 seconds (0.0000625 seconds). Does this look correct?Period = (SystemCoreClock / 768000000000); // 16 kHz timing? 48,000,000 / 768000000000 = 0.0000625seconds. Thank you. -Mike2014-04-28 11:04 PM
2014-04-28 11:54 PM
Good grief
Period = (SystemCoreClock / (32 * 6250)); // 6.25 KHz Sine from 32 point table
Period = (SystemCoreClock / 200000); // 200 KHz Sample Rate
Period = (SystemCoreClock / 16000); // 16 KHz Sample Rate
You are attempting to compute the number of ticks in SystemCoreClock units that relate to the frequency you are trying to generate. Depending on the size of the timer in question this would need to fit in a 16-bit or 32-bit variable, where it cannot you'd need to factor the number between the Period and Prescaler.For 1 Hz the clock would need to tick SystemCoreClock units, perhaps expressed as 48000 * 1000For 16 KHz, we have 48000000 / 16000, or 3000, and the value is programmed into the TIM as an N-1 number as the counter will tick 0..2999 before updating, and triggering the ADC and/or DAC2014-04-29 12:16 AM
Thanks again for the post. ''Good grief'' - well how do you think I feel! Ha. :)
1.) To verify the frequency I went back to the following line for 200 kHz. Period = (SystemCoreClock / 200000); // 200 KHz timebase 2.) Added line to update the interrupt TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); 3.) Configure the NVIC to use the TIM2_IRQn. 4.) In the interrupt handler for TIM2 I take PA3 high and then low so I can measure this on my oscilloscope.void TIM2_IRQHandler()
{
int flag = 0;
GPIO_SetBits(GPIOA, GPIO_Pin_3); // set PA3 chip select high. for timing.
flag = 1;
GPIO_ResetBits(GPIOA, GPIO_Pin_3); // set PA3 chip select low for timing.
}
5.) I was expecting to see 200 kHz but I am measuring a frequency of 99 kHz instead.
Any ideas?
Thank you.
-Mike.
2014-04-29 12:27 AM
You'd want to clear the Update interrupt as you enter the service routine. The 925 KHz represents the saturation point of the CPU as it constantly re-enters the uncleared IRQ.
2014-04-29 12:32 AM
void TIM2_IRQHandler()
{
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) // Qualify (Optional but preferred)
{
TIM_ClearITPendingBit(TIM2, TIM_IT_Update); // Clear
GPIO_SetBits(GPIOA, GPIO_Pin_3); // set PA3 chip select high. for timing.
GPIO_ResetBits(GPIOA, GPIO_Pin_3); // set PA3 chip select low for timing.
}
}
2014-04-29 12:33 AM
Dang you are good! Thanks! I will do this!
-Mike