本篇文章来自极术社区与兆易创新组织的GD32F427开发板评测活动,更多开发板试用活动请关注极术社区网站。作者:hehung
之前发帖
【GD32F427开发板试用】1. 串口实现scanf输入控制LED
【GD32F427开发板试用】2. RT-Thread标准版移植
【GD32F427开发板试用】3. 硬件IIC0驱动OLED显示中文
前言
本文实现了使用GD32FF427V-START板子的ADC功能读取摇杆模块的XY坐标移动数值。
本文实现功能如下:
- 基于RT-Thread OS;
- 驱动ADC读取模拟电压;
- 采集摇杆模块的XY坐标的移动位置数值。
资料查询
通过查看芯片数据手册可以知道PA1分别连接到了ADC0的Channel1与Channel2,基于此信息,我们使用PA1与PA2来作为摇杆模块的X坐标与Y坐标的移动量,如下为数据手册信息。
软件编写
知道了硬件连接,我们就可以开始写软件了,此部分不做过多说明,详见源码,GD官方也提供了丰富的参考源码。
ADC初始化
- 初始化时钟以及分频;
- 初始化PA1作为模拟端口;
- 初始化ADC0,配置为软件触发采集。
void Adc_Init(void) { /* enable GPIOC clock / rcu_periph_clock_enable(RCU_GPIOA); / enable ADC clock / rcu_periph_clock_enable(RCU_ADC0);; / config ADC clock / adc_clock_config(ADC_ADCCK_PCLK2_DIV8); / config the GPIO as analog mode / gpio_mode_set(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_1 | GPIO_PIN_2); / ADC data alignment config / adc_data_alignment_config(ADC0, ADC_DATAALIGN_RIGHT); / ADC channel length config / adc_channel_length_config(ADC0, ADC_REGULAR_CHANNEL, 1U); / ADC trigger config / adc_external_trigger_source_config(ADC0, ADC_REGULAR_CHANNEL, ADC_EXTTRIG_REGULAR_EXTI_11); / ADC external trigger config / adc_external_trigger_config(ADC0, ADC_REGULAR_CHANNEL, ENABLE); / enable ADC interface / adc_enable(ADC0); rt_thread_mdelay(1U); / ADC calibration and reset calibration */ adc_calibration_enable(ADC0); }
ADC采集函数
我们使用软件触发采集,代码如下:
uint16_t Adc_ChSample(uint8_t channel)
{
/* ADC regular channel config */
adc_regular_channel_config(ADC0, 0U, channel, ADC_SAMPLETIME_480);
/* ADC software trigger enable */
adc_software_trigger_enable(ADC0, ADC_REGULAR_CHANNEL);
/* wait the end of conversion flag */
while(!adc_flag_get(ADC0, ADC_FLAG_EOC));
/* clear the end of conversion flag */
adc_flag_clear(ADC0, ADC_FLAG_EOC);
/* return regular channel sample value */
return (adc_regular_data_read(ADC0));
}
主函数
主函数初始化ADC,IIC,OLED;
while循环中没100ms采集一次ADC数据,代码如下:
int main(void)
{
char adc_str[16];
/* Initialize the ADC */
Adc_Init();
/* Configure the I2C GPIO ports */
i2c_gpio_config();
/* Configure I2C */
i2c_config();
/* Configure OLED */
OLED_Init();
OLED_ShowString(0, 0, (const uint8_t*)"GD32F427V-START", 16, 1);
OLED_ShowHzStringRow(0, 16, (const char*)"极术社区", 1);
OLED_ShowString(64, 16, (const uint8_t*)"|hehung", 16, 1);
OLED_Refresh_Gram();
while (1)
{
sprintf(adc_str, "ADC-X:%03d", (int)(Adc_ChSample(ADC_CHANNEL_1)/4096.0*100.0));
OLED_ShowString(0, 32, (const char*)adc_str, 16, 1);
sprintf(adc_str, "ADC-Y:%03d", (int)(Adc_ChSample(ADC_CHANNEL_2)/4096.0*100.0));
OLED_ShowString(0, 48, (const char*)adc_str, 16, 1);
OLED_Refresh_Gram();
rt_thread_mdelay(100);
}
return RT_EOK;
}
显示效果
见下面的图片,移动摇杆,ADC0的Channel0与Channel1可以采集到X与Y坐标的数值,50表示正中间的位置。0表示最小位置,99表示最大位置。
详细效果见视频:
【GD32F427开发板试用】4. ADC采集摇杆模块移动量