notes:
I originally wanted to use PWM to output audio, but no matter how I debugged it, the frequency of the PWM audio was always wrong. Later, I used DAC instead.
Configuration:
Chip: STM32F103VET
DAC: DAC channel 2 (8-bit right-aligned), timer TIM7 interrupt changes DAC value
WAVE data: stored on the chip in const form (8kHz sampling, 8bit, mono)
detour:
(1) Use TIM7 to control DAC output, use TRIG mode, and transfer data to DAC write register through DMA2 channel => No waveform output
(2) It is not necessary to use a timer that is consistent with the DAC channel as a driver, so TIM3 is used. TIM3 is set to work at 8K frequency, and IT_UPDATE is allowed. The DAC value is changed in the TIM3 timer interrupt. The DMA2 channel is not used. => There is a waveform signal output, but the frequency is too high. One second of audio is output in about 50ms.
(3) Do not use TIM3, use TIM7 corresponding to DAC channel 2. Configure TIM7 to 8K operating frequency, allow IT_UPDATE, change the DAC value in the TIM7 timer interrupt, and drive the DAC normally. It is estimated that detour (2) is caused by the fact that the operating frequency of TIM7 is not configured, resulting in abnormal DAC frequency, but it has not been confirmed.
(4) Use the timer in step (3) and DMA to transfer data => DAC cannot output audio normally [Due to time constraints, this problem will not be solved for the time being]
Routine:
void DACInit(void)
{
DAC_InitTypeDef DAC_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
// 1. Configure TIM7
TIM_DeInit(TIM7);
/* Time base configuration */
TIM_TimeBaseStructure.TIM_Period = GetARRValue(8000); // Reset period
TIM_TimeBaseStructure.TIM_Prescaler = 0; // Frequency division
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; // Clock division
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Down; // Counting mode
TIM_TimeBaseInit(TIM7, &TIM_TimeBaseStructure);
// Enable TIM7 update interrupt
TIM_ITConfig(TIM7, TIM_IT_Update, ENABLE);
// 2. Configure DAC
DAC_DeInit();
/* DAC channel1 Configuration */
DAC_InitStructure.DAC_Trigger = DAC_Trigger_None; //
DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;
DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bits8_0;
DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable;
// DA channel 2 initialization
DAC_Init(DAC_Channel_2, &DAC_InitStructure);
/* Enable DAC Channel1: Once the DAC channel1 is enabled, PA.04 is
automatically connected to the DAC converter. */
DAC_Cmd(DAC_Channel_2, ENABLE);
// 3. Start TIM7
TIM_Cmd(TIM7, ENABLE);
}
void TIM7_IRQHandler(void)
{
INT16U tmpCap;
if (TIM_GetITStatus(TIM7, TIM_IT_Update) != RESET)
{
if( wavecount < wave0Length )
{
tmpCap = wave0[wavecount];
wavecount++;
/* Set DAC Channel1 DHR register */
DAC_SetChannel2Data(DAC_Align_8b_R,tmpCap);
}
else
{
// Complete the transfer and turn off the interrupt
wavecount = 0;
TIM_ITConfig(TIM7, TIM_IT_Update, DISABLE);
TIM_Cmd(TIM7, DISABLE);
// Need to turn off DAC, otherwise there will be noise when there is no sound
DAC_Cmd(DAC_Channel_2, DISABLE);
}
}
/* Clear TIM6 update interrupt */
TIM_ClearITPendingBit(TIM7, TIM_IT_Update);
}
// Get the timer automatically according to the sampling rate
// Extracted from waveplayer.c
INT16U GetARRValue(INT16U sample)
{
INT16U arrValue;
/* Update OCA value to match .WAV file sampling rate */
switch (sample)
{
case SAMPLE_RATE_8000 :
arrValue = (uint16_t)(72000000/8000);
break; /* 8KHz = 2x36MHz / 9000 */
case SAMPLE_RATE_11025:
arrValue = (uint16_t)(72000000/11025);
break; /* 11.025KHz = 2x36MHz / 6531 */
case SAMPLE_RATE_16000:
arrValue = (uint16_t)(72000000/16000);
break; /* 16KHz = 2x36MHz / 4500 */
case SAMPLE_RATE_22050:
arrValue = (uint16_t)(72000000/22050);
break; /* 22.05KHz = 2x36MHz / 2365 */
case SAMPLE_RATE_44100:
arrValue = (uint16_t)(72000000/44100);
break; /* 44.1KHz = 2x36MHz / 1633 */
case SAMPLE_RATE_48000:
arrValue = (uint16_t)(72000000/48000);
break; /* 48KHz = 2x36MHz / 1500 */
default:
arrValue = 0;
break;
}
return arrValue;
}
Previous article:STM32 PCM1770 debugging
Next article:STM32F4 FFT music spectrum is not too easy!
- Popular Resources
- Popular amplifiers
- Learn ARM development(16)
- Learn ARM development(17)
- Learn ARM development(18)
- Embedded system debugging simulation tool
- A small question that has been bothering me recently has finally been solved~~
- Learn ARM development (1)
- Learn ARM development (2)
- Learn ARM development (4)
- Learn ARM development (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- Pickering Launches New Future-Proof PXIe Single-Slot Controller for High-Performance Test and Measurement Applications
- Apple faces class action lawsuit from 40 million UK iCloud users, faces $27.6 billion in claims
- Apple faces class action lawsuit from 40 million UK iCloud users, faces $27.6 billion in claims
- The US asked TSMC to restrict the export of high-end chips, and the Ministry of Commerce responded
- The US asked TSMC to restrict the export of high-end chips, and the Ministry of Commerce responded
- ASML predicts that its revenue in 2030 will exceed 457 billion yuan! Gross profit margin 56-60%
- Detailed explanation of intelligent car body perception system
- How to solve the problem that the servo drive is not enabled
- Why does the servo drive not power on?
- What point should I connect to when the servo is turned on?
- Qorvo at CES 2020: Innovative Solutions for 5G, IoT, Wi-Fi 6 and V2X
- dsp28335 Ecap Summary
- Motor drive control essence summary post
- AD automatically adds test points
- iTOP-3399 development board Linux system modify boot LOGO
- [GD32E231 DIY Contest] 4. Simulate IIC to operate OLED
- Analysis of possible causes of I2C failure
- Pingtouge RVB2601 board-IIC bus test
- 【GD32E503 Review】 + littlegl ported to GD32E503V-EVAL
- Discover the world's most in-demand medical power supplies