GD32 定时器+DMA+ADC 实现16K 音频ADC采样及PCM编码
参考代码:
uint16_t ad_value[1920*2]; //音频原始AD采样值
uint8_t audio_EncodeValue[1008]; //音频PCM编码值
uint8_t StartSend=0; //编码后发送标志
void adc_rcu_config(void);
void adc_gpio_config(void);
void adc_dma_config(void);
void adc_timer_config(void);
void adc_config(void);
/*!
\brief RCU configuration function for ADC
\param[in] none
\param[out] none
\retval none
*/
void adc_rcu_config(void)
{
/* enable the GPIO clock */
rcu_periph_clock_enable(RCU_GPIOA);
/* ADCCLK = PCLK2/4 */
rcu_adc_clock_config(RCU_ADCCK_APB2_DIV4);
/* enable DMA clock */
rcu_periph_clock_enable(RCU_DMA);
/* enable ADC clock */
rcu_periph_clock_enable(RCU_ADC);
/* enable TIMER0 clock */
rcu_periph_clock_enable(RCU_TIMER0);
}
/*!
\brief GPIO configuration function for ADC
\param[in] none
\param[out] none
\retval none
*/
void adc_gpio_config(void)
{
/* configure PA1(ADC channel1) as analog input */
gpio_mode_set(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_1);
}
/*!
\brief DMA configuration function for ADC
\param[in] none
\param[out] none
\retval none
*/
void adc_dma_config(void)
{
dma_parameter_struct dma_init_struct;
/* initialize DMA channel0 */
dma_deinit(DMA_CH0);
dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY;
dma_init_struct.memory_addr = (uint32_t)ad_value;
dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
dma_init_struct.memory_width = DMA_MEMORY_WIDTH_16BIT;
dma_init_struct.number = 1920*2; //双BUFFER 循环缓冲
dma_init_struct.periph_addr = (uint32_t)&(ADC_RDATA);
dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_16BIT;
dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
dma_init(DMA_CH0, &dma_init_struct);
/* configure DMA mode */
dma_circulation_enable(DMA_CH0);
dma_memory_to_memory_disable(DMA_CH0);
dma_interrupt_enable(DMA_CH0,DMA_INT_FTF); //DMA完成中断使能
dma_interrupt_enable(DMA_CH0,DMA_INT_HTF); // DMA半完成中断使能 实现双缓冲
/* enable DMA channel0 */
dma_channel_enable(DMA_CH0);
}
/*!
\brief TIMER configuration function for ADC
\param[in] none
\param[out] none
\retval none
*/
void adc_timer_config(void)
{
timer_oc_parameter_struct timer_ocintpara;
timer_parameter_struct timer_initpara;
timer_deinit(TIMER0);
/* TIMER0 configuration */
timer_initpara.prescaler = 53; //108MHZ--54分频到2MHZ
timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
timer_initpara.counterdirection = TIMER_COUNTER_UP;
timer_initpara.period = 1250; //16KHz的音频采样频率
timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
timer_initpara.repetitioncounter = 0;
timer_init(TIMER0, &timer_initpara);
/* CH0 configuration in PWM mode1 */
timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_LOW;
timer_ocintpara.outputstate = TIMER_CCX_ENABLE;
timer_channel_output_config(TIMER0, TIMER_CH_0, &timer_ocintpara);
timer_channel_output_pulse_value_config(TIMER0, TIMER_CH_0, 625); //50%占空比
timer_channel_output_mode_config(TIMER0, TIMER_CH_0, TIMER_OC_MODE_PWM1);
timer_channel_output_shadow_config(TIMER0, TIMER_CH_0, TIMER_OC_SHADOW_DISABLE);
/* auto-reload preload enable */
timer_auto_reload_shadow_enable(TIMER0);
timer_primary_output_config(TIMER0, ENABLE);
}
/*!
\brief ADC configuration function
\param[in] none
\param[out] none
\retval none
*/
void adc_config(void)
{
/* ADC channel length config */
adc_channel_length_config(ADC_REGULAR_CHANNEL, 1);
/* ADC regular channel config */
adc_regular_channel_config(0, ADC_CHANNEL_1, ADC_SAMPLETIME_55POINT5);
/* ADC external trigger enable */
adc_external_trigger_config(ADC_REGULAR_CHANNEL, ENABLE);
/* ADC external trigger source config */
adc_external_trigger_source_config(ADC_REGULAR_CHANNEL, ADC_EXTTRIG_REGULAR_T0_CH0);
/* ADC data alignment config */
adc_data_alignment_config(ADC_DATAALIGN_RIGHT);
/* enable ADC interface */
adc_enable();
/* ADC calibration and reset calibration */
adc_calibration_enable();
/* ADC DMA function enable */
adc_dma_mode_enable();
}
void DMA_Channel0_IRQHandler(void)
{
if(dma_interrupt_flag_get(DMA_CH0,DMA_INT_FLAG_FTF)
{
dma_interrupt_flag_clear(DMA_CH0,DMA_INT_FLAG_FTF);
// ADPCM 编码
audio_EncodeValue = ADPCM_Encode(adc_value);
//发送音频数据
StartSend = 1;
}
if(dma_interrupt_flag_get(DMA_CH0,DMA_INT_FLAG_HTF)
{
dma_interrupt_flag_clear(DMA_CH0,DMA_INT_FLAG_HTF);
// ADPCM 编码
audio_EncodeValue = ADPCM_Encode(adc_value);
//发送音频数据
StartSend = 1;
}
} |