本帖最后由 bogu1992 于 2022-4-7 14:34 编辑
芯片采用GD32F303, ADC采用规则组,单次转换模式,中断获取方式,TIMER触发源。最后能进入ADC中断,但无法获取ADC的值。
代码部分:
void Adc_GPIO_Configuration(void)
{
/* enable GPIOA clock */
rcu_periph_clock_enable(RCU_GPIOA);
gpio_init(GPIOA, GPIO_MODE_AIN, GPIO_OSPEED_MAX, GPIO_PIN_1);
}
void Adc_Configuration(void)
{
/* enable ADC0 clock */
rcu_periph_clock_enable(RCU_ADC0);//
/* config ADC clock */
rcu_adc_clock_config(RCU_CKADC_CKAPB2_DIV4);//
/* configure ADC resolution */
adc_resolution_config(ADC0 , ADC_RESOLUTION_12B);//
/* configure ADC discontinuous mode */
<font color="#000000"> //adc_discontinuous_mode_config(ADC0 , ADC_REGULAR_CHANNEL , 1);</font><font color="#ff0000">//单次模式不需要执行该函数</font>
/* configure the ADC mode */
adc_mode_config(ADC_MODE_FREE);//
/* enable or disable ADC special function */
adc_special_function_config(ADC0 , ADC_CONTINUOUS_MODE , DISABLE);
adc_special_function_config(ADC0, ADC_SCAN_MODE, DISABLE);
adc_special_function_config(ADC0, ADC_INSERTED_CHANNEL_AUTO, DISABLE);
/* configure ADC data alignment */
adc_data_alignment_config(ADC0 , ADC_DATAALIGN_RIGHT);//
/* configure the length of regular channel group or inserted channel group */
// <font color="#000000">adc_channel_length_config(ADC0 , ADC_REGULAR_CHANNEL , 1);</font><font color="#ff0000">//单次模式不需要执行该函数</font>
<font color="#ff0000"> //如需切换ADC,则执行下述函数一次即可获取对应的ADC的值</font>
<font color="#0000ff"> // adc_regular_channel_config(ADC0 ,</font><font color="#ff0000"> 0</font><font color="#0000ff"> , ADC_CHANNEL_0 , ADC_SAMPLETIME_7POINT5);
adc_regular_channel_config(ADC0 ,</font><font color="#ff0000"> 0</font><font color="#0000ff"> , ADC_CHANNEL_1 , ADC_SAMPLETIME_7POINT5);
// adc_regular_channel_config(ADC0 , </font><font color="#ff0000">0</font><font color="#0000ff"> , ADC_CHANNEL_2 , ADC_SAMPLETIME_7POINT5);
// adc_regular_channel_config(ADC0 , </font><font color="#ff0000">0</font><font color="#0000ff"> , ADC_CHANNEL_3 , ADC_SAMPLETIME_7POINT5);</font>
/* configure ADC external trigger source */
adc_external_trigger_source_config(ADC0, ADC_REGULAR_CHANNEL, ADC0_1_EXTTRIG_REGULAR_T2_TRGO);//
/* enable ADC external trigger */
adc_external_trigger_config(ADC0, ADC_REGULAR_CHANNEL, ENABLE);//
/* clear the ADC flag */
adc_interrupt_flag_clear(ADC0, ADC_INT_FLAG_EOC);
/* enable ADC interrupt */
adc_interrupt_enable(ADC0, ADC_INT_EOC);//
// adc_tempsensor_vrefint_enable();
/* enable ADC interface */
adc_enable(ADC0);//
/* ADC calibration and reset calibration */
adc_calibration_enable(ADC0);//
/* enable ADC software trigger */
// adc_software_trigger_enable(ADC0 , ADC_REGULAR_CHANNEL);
}
void SetSampRate(uint32_t freq)
{
//配置定时器3作为ADC的转换触发源
uint16_t Period;
timer_parameter_struct timer_initpara;
rcu_periph_clock_enable(RCU_TIMER2);
timer_deinit(TIMER2);
/*
采样频率计算公式 :
period = 48000000 / freq ;
1200 == 40KHz 采样频率
*/
Period = FMASTER / freq-1;
timer_initpara.prescaler = 1;
timer_initpara.alignedmode = TIMER_COUNTER_EDGE;//????
timer_initpara.counterdirection = TIMER_COUNTER_UP;
timer_initpara.period = Period;
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);
}
void Adc_Start(void)
{
timer_counter_value_config(TIMER2 , 0);
timer_enable(TIMER2);
}
void Adc_Stop(void)
{
timer_disable(TIMER2);
}
void ADC0_1_IRQHandler(void){
if(adc_interrupt_flag_get( ADC0, ADC_INT_FLAG_EOC)){
u16 Conversion_Value = adc_regular_data_read(ADC0);
adc_interrupt_flag_clear( ADC0, ADC_INT_FLAG_EOC);
}
}
SetSampRate(10000);
//系统中断管理
void NVIC_Configuration(void)
{
rcu_periph_clock_enable(RCU_TIMER1);
rcu_periph_clock_enable(RCU_TIMER2);
rcu_periph_clock_enable(RCU_TIMER3);
rcu_periph_clock_enable(RCU_TIMER4);
rcu_periph_clock_enable(RCU_ADC0);
nvic_priority_group_set(NVIC_PRIGROUP_PRE1_SUB3);
nvic_irq_enable(TIMER1_IRQn, 0U, 1U);//原timer9
nvic_irq_enable(TIMER3_IRQn, 0U, 2U);
nvic_irq_enable(TIMER4_IRQn, 0U, 3U);
nvic_irq_enable(ADC0_1_IRQn, 0U, 0U);
}
void GPIO_Configuration(void)
{
rcu_periph_clock_enable(RCU_AF);
rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_GPIOB);
rcu_periph_clock_enable(RCU_GPIOC);
rcu_periph_clock_enable(RCU_GPIOD);
gpio_deinit(GPIOA);
gpio_deinit(GPIOB);
gpio_deinit(GPIOC);
gpio_deinit(GPIOD);
gpio_afio_deinit();
}
程序函数有一个巨坑:
adc_channel_length_config(ADC0 , ADC_REGULAR_CHANNEL , 1);//
void adc_channel_length_config(uint32_t adc_periph, uint8_t adc_channel_group, uint32_t length)的描述:
/*!
\brief configure the length of regular channel group or inserted channel group
\param[in] adc_periph: ADCx,x=0,1,2
only one among these parameters can be selected
\param[in] adc_channel_group: select the channel group
only one parameter can be selected
\arg ADC_REGULAR_CHANNEL: regular channel group
\arg ADC_INSERTED_CHANNEL: inserted channel group
\param[in] length: the length of the channel
regular channel 1-16
inserted channel 1-4
\param[out] none
\retval none
*/
规则通道的 length 为1-16,而ADC是从0开始,函数里也已经(length-1U),但不知道为什么PA1口
函数adc_channel_length_config(ADC0 , ADC_REGULAR_CHANNEL , 2);就能用了adc_channel_length_config(ADC0 , ADC_REGULAR_CHANNEL , 2);不需要该函数。
如需更改或切换其他ADC口则执行一遍下述函数进行刷新:
adc_regular_channel_config(uint32_t adc_periph , uint8_t rank , uint8_t adc_channel , uint32_t sample_time)
其中 固定参数 rank = 0;即可
|
|