【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)
- {
-
- rcu_periph_clock_enable(RCU_GPIOA);
- rcu_periph_clock_enable(RCU_GPIOC);
-
- rcu_periph_clock_enable(RCU_ADC);
-
- rcu_adc_clock_config(RCU_ADCCK_APB2_DIV6);
- }
再把PA1配置成ADC通道1。同时配置评估板上的4个LED等对应的PA7,PA8,PC6和PC7作为通用GPIO,对应指示4个按键:
- void gpio_config(void)
- {
-
- gpio_mode_set(ADC_GPIO_PORT, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, ADC_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_special_function_config(ADC_CONTINUOUS_MODE, ENABLE);
-
- adc_external_trigger_source_config(ADC_REGULAR_CHANNEL, ADC_EXTTRIG_REGULAR_NONE);
-
- adc_data_alignment_config(ADC_DATAALIGN_RIGHT);
-
- adc_channel_length_config(ADC_REGULAR_CHANNEL, 1U);
-
- adc_regular_channel_config(0U, BOARD_ADC_CHANNEL, ADC_SAMPLETIME_55POINT5);
- adc_external_trigger_config(ADC_REGULAR_CHANNEL, ENABLE);
-
- adc_resolution_config(ADC_RESOLUTION_8B);
-
- adc_enable();
- delay_1ms(1U);
-
- 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)
- {
-
- rcu_config();
-
- systick_config();
-
- gpio_config();
-
-
- gd_eval_com_init(EVAL_COM);
-
-
- 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.功能正常,偶尔出现其他灯被一闪而过的点亮,主要是我们只采样一次,想避免的话,可以多采样几次进行滤波。
看看运行的效果吧:
|