开发板使用的是gd32f450zk,env工具使用的版本是1.3.5,rtthread版本是5.0.0。
添加adc外设的步骤如下:
步骤1:查看开发板的电路原理图,确定adc的使用引脚,使用的是引脚PF6,即adc012_IN4,如下图:
步骤2:使用env工具开启adc外设,并选择配置相应的adc外设,如下图:
步骤3:打开drv_adc.c文件,修改代码
修改后代码如下,也可以全部修改为GET_PIN(F, 6)。
#ifdef BSP_USING_ADC2
{
ADC2,
RCU_ADC2,
{
GET_PIN(A, 0), GET_PIN(A, 1), GET_PIN(A, 2), GET_PIN(A, 3),
GET_PIN(F, 6), GET_PIN(A, 5), GET_PIN(A, 6), GET_PIN(A, 7),
GET_PIN(B, 0), GET_PIN(B, 1), GET_PIN(C, 0), GET_PIN(C, 1),
GET_PIN(C, 2), GET_PIN(C, 3), GET_PIN(C, 4), GET_PIN(C, 5),
},
&adc2,
"adc2",
},
#endif
还需要修改的函数有:
static rt_err_t gd32_adc_enabled(struct rt_adc_device *device, rt_uint32_t channel, rt_bool_t enabled);
static rt_err_t gd32_adc_convert(struct rt_adc_device *device, rt_uint32_t channel, rt_uint32_t *value);
ADC_REGULAR_CHANNEL 未定义,改为ADC_ROUTINE_CHANNEL,同时将其余报错进行修改,修改后的代码如下:
/**
* @brief ADC enable
*This function enable adc.
* @param device, channel, enabled
* @retval None
*/
static rt_err_t gd32_adc_enabled(struct rt_adc_device *device, rt_uint32_t channel, rt_bool_t enabled)
{
uint32_t adc_periph;
struct gd32_adc * adc = (struct gd32_adc *)device->parent.user_data;
if (channel >= MAX_EXTERN_ADC_CHANNEL)
{
LOG_E("invalid channel");
return -RT_EINVAL;
}
adc_periph = (uint32_t )(adc->adc_periph);
if (enabled == ENABLE)
{
gd32_adc_gpio_init(adc->adc_clk, adc->adc_pins[channel]);
adc_channel_length_config(adc_periph, ADC_ROUTINE_CHANNEL, 1);
adc_data_alignment_config(adc_periph, ADC_DATAALIGN_RIGHT);
#if defined SOC_SERIES_GD32F4xx
adc_external_trigger_source_config(adc_periph, ADC_ROUTINE_CHANNEL, ADC_EXTTRIG_ROUTINE_EXTI_11);
#else
adc_external_trigger_source_config(adc_periph, ADC_REGULAR_CHANNEL, ADC0_1_2_EXTTRIG_REGULAR_NONE);
#endif
adc_external_trigger_config(adc_periph, ADC_ROUTINE_CHANNEL, ENABLE);
#if defined SOC_SERIES_GD32F4xx
adc_routine_channel_config(adc_periph, 0, channel, ADC_SAMPLETIME_480);
#else
adc_regular_channel_config(adc_periph, 0, channel, ADC_SAMPLETIME_13POINT5);
#endif
adc_enable(adc_periph);
/* ADC calibration and reset calibration */
adc_calibration_enable(adc_periph);
}
else
{
adc_disable(adc_periph);
}
return 0;
}
/**
* @brief convert adc.
*This function get adc value.
* @param device, channel, value
* @retval None
*/
static rt_err_t gd32_adc_convert(struct rt_adc_device *device, rt_uint32_t channel, rt_uint32_t *value)
{
uint32_t adc_periph;
struct gd32_adc * adc = (struct gd32_adc *)(device->parent.user_data);
if (!value)
{
LOG_E("invalid param");
return -RT_EINVAL;
}
adc_periph = (uint32_t )(adc->adc_periph);
adc_software_trigger_enable(adc_periph, ADC_ROUTINE_CHANNEL);
while(!adc_flag_get(adc_periph, ADC_FLAG_EOC)){};
// clear flag
adc_flag_clear(adc_periph, ADC_FLAG_EOC);
*value = adc_routine_data_read(adc_periph);
return 0;
}
步骤4:编译正常,下载到开发板,进行测试,测试指令如下:
msh />adc
Usage:
adc probe <device name> - probe adc by name
adc read <channel> - read adc value on the channel
adc disable <channel> - disable adc channel
adc enable <channel> - enable adc channel
步骤5:测试发现输入并无变化的情况下,读取的值一直在变,并且变化太大,读取到的值快速减小。说明配置的有问题,查找原因,发现再使能adc外设的时候,没有对引脚的时钟进行使能,再static void gd32_adc_gpio_init(rcu_periph_enum adc_clk, rt_base_t pin)函数中增加使能引脚时钟,修改如下:
rcu_periph_clock_enable(RCU_GPIOF);
修改之后测试,测试结果如下:
读取的值不会变化很大,而是再一定的范围内变化。
————————————————
版权声明:本文为CSDN博主「嵌入式学习和实践」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_46158019/article/details/129701001
|
|