void timer2_config(u16 arr,u16 psc)
{
timer_parameter_struct timer_initpara;
timer_deinit(TIMER2);
rcu_periph_clock_enable(RCU_TIMER2);
timer_initpara.prescaler = psc;
timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
timer_initpara.counterdirection = TIMER_COUNTER_UP;
timer_initpara.period = arr;
timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
timer_initpara.repetitioncounter = 0;
timer_init(TIMER2, &timer_initpara);
timer_master_output_trigger_source_select(TIMER2,TIMER_TRI_OUT_SRC_UPDATE);
timer_auto_reload_shadow_enable(TIMER2);
timer_enable(TIMER2);
}
void ADC_Init()
{
adc_deinit(ADC0);
rcu_periph_clock_enable(RCU_ADC0);
rcu_periph_clock_enable(RCU_GPIOA);
gpio_init(GPIOA, GPIO_MODE_AIN, GPIO_OSPEED_50MHZ, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2);
rcu_adc_clock_config(RCU_CKADC_CKAPB2_DIV8);
/* ADC scan mode function enable */
adc_special_function_config(ADC0, ADC_SCAN_MODE, ENABLE);
adc_special_function_config(ADC0, ADC_CONTINUOUS_MODE, DISABLE);
/* ADC trigger config */
adc_external_trigger_source_config(ADC0, ADC_REGULAR_CHANNEL, ADC0_1_EXTTRIG_REGULAR_T2_TRGO);
/* ADC data alignment config */
adc_data_alignment_config(ADC0, ADC_DATAALIGN_RIGHT);
/* configure the ADC sync mode */
adc_mode_config(ADC_MODE_FREE);
/* ADC channel length config */
adc_channel_length_config(ADC0, ADC_REGULAR_CHANNEL, 3);
/* ADC regular channel config */
adc_regular_channel_config(ADC0, 0, ADC_CHANNEL_2, ADC_SAMPLETIME_28POINT5);
adc_regular_channel_config(ADC0, 1, ADC_CHANNEL_1, ADC_SAMPLETIME_28POINT5);
adc_regular_channel_config(ADC0, 2, ADC_CHANNEL_0, ADC_SAMPLETIME_28POINT5);
/* ADC external trigger enable */
adc_external_trigger_config(ADC0, ADC_REGULAR_CHANNEL, ENABLE);
/* enable ADC interface */
adc_enable(ADC0);
delay_1ms(10);
/* ADC calibration and reset calibration */
adc_calibration_enable(ADC0);
/* ADC DMA function enable */
adc_dma_mode_enable(ADC0);
adc_software_trigger_enable(ADC0,ADC_REGULAR_CHANNEL);
}
void dma_config(u32 maddr, u32 paddr,u16 datalength)
{
/* ADC_DMA_channel configuration */
dma_parameter_struct dma_data_parameter;
rcu_periph_clock_enable(RCU_DMA0);
/* ADC_DMA_channel deinit */
dma_deinit(DMA0, DMA_CH0);
/* initialize DMA single data mode */
dma_data_parameter.periph_addr = (uint32_t)paddr;
dma_data_parameter.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
dma_data_parameter.memory_addr = (uint32_t)(maddr);
dma_data_parameter.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
dma_data_parameter.periph_width = DMA_PERIPHERAL_WIDTH_16BIT;
dma_data_parameter.memory_width = DMA_MEMORY_WIDTH_16BIT;
dma_data_parameter.direction = DMA_PERIPHERAL_TO_MEMORY;
dma_data_parameter.number = datalength;
dma_data_parameter.priority = DMA_PRIORITY_HIGH;
dma_init(DMA0, DMA_CH0, &dma_data_parameter);
dma_interrupt_enable(DMA0, DMA_CH0,DMA_INT_FTF);
dma_interrupt_flag_clear(DMA0,DMA_CH0,DMA_INT_FLAG_G | DMA_INT_FLAG_FTF | DMA_INT_FLAG_HTF | DMA_INT_FLAG_ERR);
dma_circulation_enable(DMA0, DMA_CH0);
/* enable DMA channel */
dma_channel_enable(DMA0, DMA_CH0);
}
extern void user_adc_deal_func(void);
void DMA0_Channel0_IRQHandler()
{
if(dma_interrupt_flag_get(DMA0,DMA_CH0,DMA_INT_FLAG_FTF) != RESET)
{
dma_interrupt_flag_clear(DMA0,DMA_CH0,DMA_INT_FLAG_G | DMA_INT_FLAG_FTF | DMA_INT_FLAG_HTF | DMA_INT_FLAG_ERR);
user_adc_deal_func();
}
}
拟采用timer2的更新触发AD进行采样,APB2时钟频率为72MHz,当ADC0的时钟被RCU_CKADC_CKAPB2_DIV6时,DMA不能够转换成功,无法进入DMA中断。当ADC被RCU_CKADC_CKAPB2_DIV8分频时,偶尔芯片复位能够开始转换,有时候芯片板卡复位无法正常转换,大家遇到过这种情况吗??? |
|