打印
[研电赛技术支持]

RT-Thread开发GD32F450 添加adc外设

[复制链接]
205|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zljiu|  楼主 | 2023-7-19 15:13 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
    开发板使用的是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

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

50

主题

3319

帖子

3

粉丝