【GD32L233C-START评测】第4篇 不一样的按键--ADC键盘
[复制链接]
本帖最后由 yang_alex 于 2022-2-20 17:14 编辑
ADC按键可以节省MCU的I/O资源,按键部分采用电阻分压,部分电路通过按键实现电阻并联分压,由MCU的ADC采样电压同按键对应值进行比较的方法实现。如下图:
在这里,我们的Key_ADC接评估板上的PA1,也是ADC_IN1(ADC通道1).
先配置系统时钟。要想跑,心跳不能少。(低功耗的必备良药:那个功能不需要,时钟一关自然跑不了)
void rcu_config(void)
{
/* enable GPIOC clock */
rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_GPIOC);
/* enable ADC clock */
rcu_periph_clock_enable(RCU_ADC);
/* config ADC clock */
rcu_adc_clock_config(RCU_ADCCK_APB2_DIV6);
}
再把PA1配置成ADC通道1。同时配置评估板上的4个LED等对应的PA7,PA8,PC6和PC7作为通用GPIO,对应指示4个按键:
void gpio_config(void)
{
/* config the GPIO as analog mode */
gpio_mode_set(ADC_GPIO_PORT, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, ADC_GPIO_PIN);
/* configure LED GPIO pin */
gpio_mode_set(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_7 | GPIO_PIN_8);
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_7 | GPIO_PIN_8);
gpio_mode_set(GPIOC, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_6 | GPIO_PIN_7);
gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_6 | GPIO_PIN_7);
}
然后配置ADC:ADC功能激活,采用软件触发,右对齐,采样通道1,采样率,8位数据,ADC使能,ADC校准(ADC带有一个前置校准功能。校准后采样比较准)
void adc_config(void)
{
/* ADC contineous function enable */
adc_special_function_config(ADC_CONTINUOUS_MODE, ENABLE);
/* ADC trigger config */
adc_external_trigger_source_config(ADC_REGULAR_CHANNEL, ADC_EXTTRIG_REGULAR_NONE);
/* ADC data alignment config */
adc_data_alignment_config(ADC_DATAALIGN_RIGHT);
/* ADC channel length config */
adc_channel_length_config(ADC_REGULAR_CHANNEL, 1U);
/* ADC regular channel config */
adc_regular_channel_config(0U, BOARD_ADC_CHANNEL, ADC_SAMPLETIME_55POINT5);
adc_external_trigger_config(ADC_REGULAR_CHANNEL, ENABLE);
/* ADC resolusion 8B */
adc_resolution_config(ADC_RESOLUTION_8B);
/* enable ADC interface */
adc_enable();
delay_1ms(1U);
/* ADC calibration and reset calibration */
adc_calibration_enable();
}
前期工作准备好了,主程序中使能ADC软件触发,在死循环中清ADC转换结束标志,触发一次新的采样转换,对转换结果进行比较,确定是那个按键按下,点亮对应的LED灯。当然触发ADC开始采样转换也可以放到中断中去做。
#include "gd32l23x.h"
#include "systick.h"
#include <stdio.h>
#include "gd32l233c_start.h"
#define BOARD_ADC_CHANNEL ADC_CHANNEL_1
#define ADC_GPIO_PORT GPIOA
#define ADC_GPIO_PIN GPIO_PIN_1
uint16_t adc_value;
void rcu_config(void);
void gpio_config(void);
void adc_config(void);
int main(void)
{
/* system clocks configuration */
rcu_config();
/* systick configuration */
systick_config();
/* GPIO configuration */
gpio_config();
/* configures COM port */
gd_eval_com_init(EVAL_COM);
/* ADC configuration */
adc_config();
adc_software_trigger_enable(ADC_REGULAR_CHANNEL);
while(1)
{
adc_flag_clear(ADC_FLAG_EOC);
while(SET != adc_flag_get(ADC_FLAG_EOC)) {
}
adc_value = ADC_RDATA;
if(adc_value > 0x68)
{
gd_eval_led_on(LED1);
gd_eval_led_off(LED2);
gd_eval_led_off(LED3);
gd_eval_led_off(LED4);
}
else if(adc_value > 0x48)
{
gd_eval_led_on(LED2);
gd_eval_led_off(LED1);
gd_eval_led_off(LED3);
gd_eval_led_off(LED4);
}
else if(adc_value > 0x38)
{
gd_eval_led_on(LED3);
gd_eval_led_off(LED1);
gd_eval_led_off(LED2);
gd_eval_led_off(LED4);
}
else if(adc_value > 0x2e)
{
gd_eval_led_on(LED4);
gd_eval_led_off(LED1);
gd_eval_led_off(LED2);
gd_eval_led_off(LED3);
}
else
{
gd_eval_led_off(LED1);
gd_eval_led_off(LED2);
gd_eval_led_off(LED3);
gd_eval_led_off(LED4);
}
delay_1ms(100U);
}
}
编译下载,迫不及待的上电。OK.功能正常,偶尔出现其他灯被一闪而过的点亮,主要是我们只采样一次,想避免的话,可以多采样几次进行滤波。
看看运行的效果吧:
|