RT-Thread开发GD32F450添加adc外设

电子说

1.2w人已加入

描述

开发板使用的是gd32f450zk,env工具使用的版本是1.3.5,rtthread版本是5.0.0

添加adc外设的步骤如下:

步骤1: 查看开发板的电路原理图,确定adc的使用引脚,使用的是引脚PF6,即adc012_IN4,如下图:

ADC

步骤2: 使用env工具开启adc外设,并选择配置相应的adc外设,如下如

ADC

ADC

步骤3:打开drv_adc.c文件,修改代码

ADC

修改后代码如下,也可以全部修改为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

提示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 - probe adc by name
adc read - read adc value on the channel
adc disable - disable adc channel
adc enable - enable adc channel

ADC

步骤5:测试发现输入并无变化的情况下,读取的值一直在变,并且变化太大,读取到的值快速减小。

说明配置的有问题,查找原因,发现再使能adc外设的时候,没有对引脚的时钟进行使能,再static void gd32_adc_gpio_init(rcu_periph_enum adc_clk, rt_base_t pin)函数中增加使能引脚时钟,修改如下:

rcu_periph_clock_enable(RCU_GPIOF);

修改之后测试,测试结果

ADC

读取的值不会变化很大,而是再一定的范围内变化。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分