矩阵按键检测与LED控制
例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。提示:这里对文章进行总结:例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。
一、矩阵案件原理图
如下图所示,矩阵按键可以节省IO口资源,通过8个IO口可以控制16个按键
假设,刚开始行(ROW)为推挽输出的挽(低电平状态),列(COL)为上拉输入(高电平状态)
在前面的GPIO输出模式中分析了,如果是输出模式分为推挽输出和开漏输出,这里还是选择用推挽输出,并且是“挽(输出低电平)”
,因为挽是将外部电流吸入到GND,将电压拉低。而“推(输出高电平)”
,从VCC向外推送电流,将电压推高。
GPIO输入模式有四种,浮空、上拉、下拉,模拟。上拉模式(即默认高电平),在MCU的这个引脚内部,有一个上拉电阻连接到VCC,在这个引脚没有任何操作的情况下,仍然稳定的保持在高电平状态。
假设S6按键按下,开关导通,KROW_2输出的低电平会将KCOL_2的高电平拉低,MCU发现KCOL_2从高电平变成低电平,由此判断出KCOL_2有按键按下,但是无法确定是S2、S6、S10、S14哪一个
检测到列后,MCU会检测行
所以,反转状态
,将行(ROW)设为上拉输入,列(COL)设为推挽输出,找出是哪一行被按下,由行和列就可以锁定这个按键
二、代码实现
- 对按键初始化
(1)刚开始状态:行作为推挽输出,列作为上拉输入,检测列
(2)然后反转状态:行作为上拉输入,列作为推挽输出,检测行。 - 对LED初始化
- 写点亮LED的函数和熄灭LED的函数
- 主函数:
(1)检测列,如果某一列从1变成0,说明此列有按键按下,用一个值记录是哪一列,如果啥都没有检测到,就熄灭LED
(2)检测行,如果某一行从1变成0,说明此行有按键按下,用一个值记录是哪一行,如果啥都没有检测到,就熄灭LED
(3)根据检测到的行列,点亮对应的LED
下图是之前写的对LED初始化,但是这个代码效率不高,可以将其改一下,
//修改后的代码:
void gpio_led_config(){
//1.打开GPIOC、GPIOD时钟
rcu_periph_clock_enable(RCU_GPIOC);
rcu_periph_clock_enable(RCU_GPIOD);
//2.配置LED的电源开关为推挽输出
gpio_mode_set(GPIOC, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED_SW);
gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, LED_SW);
// 3.一次性配置LED的八个引脚
uint32_t all_led_pins = LED1 | LED2 | LED3 | LED4 | LED5 | LED6 | LED7 | LED8;
gpio_mode_set(GPIOD, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, all_led_pins );
gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, all_led_pins );
//4.打开LED电源开关
gpio_bit_reset(GPIOC, LED_SW); //低电平导通
//5.初始化关闭所有LED
LED_OFF();
}
完整代码:
#include "gd32f4xx.h"
#include "systick.h"
#include <stdio.h>
#include "main.h"
// PE8 9 10 11 ROW1 ROW2 ROW3 ROW4
// PE12 13 14 15 COL1 COL2 COL3 COL4
#define ROW1 GPIO_PIN_8
#define ROW2 GPIO_PIN_9
#define ROW3 GPIO_PIN_10
#define ROW4 GPIO_PIN_11
#define COL1 GPIO_PIN_12
#define COL2 GPIO_PIN_13
#define COL3 GPIO_PIN_14
#define COL4 GPIO_PIN_15
#define LED_SW GPIO_PIN_6
#define LED1 GPIO_PIN_8
#define LED2 GPIO_PIN_9
#define LED3 GPIO_PIN_10
#define LED4 GPIO_PIN_11
#define LED5 GPIO_PIN_12
#define LED6 GPIO_PIN_13
#define LED7 GPIO_PIN_14
#define LED8 GPIO_PIN_15
void gpio_led_config()
{
rcu_periph_clock_enable(RCU_GPIOC);
rcu_periph_clock_enable(RCU_GPIOD);
gpio_mode_set(GPIOC, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED_SW);
gpio_mode_set(GPIOD, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED1);
gpio_mode_set(GPIOD, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED2);
gpio_mode_set(GPIOD, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED3);
gpio_mode_set(GPIOD, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED4);
gpio_mode_set(GPIOD, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED5);
gpio_mode_set(GPIOD, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED6);
gpio_mode_set(GPIOD, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED7);
gpio_mode_set(GPIOD, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED8);
gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, LED_SW);
gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, LED1);
gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, LED2);
gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, LED3);
gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, LED4);
gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, LED5);
gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, LED6);
gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, LED7);
gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, LED8);
gpio_bit_reset(GPIOC, GPIO_PIN_6); // 打开LED的开关(低电平导通)
}
// 行做输出(推挽),列做输入(上拉),检测列
void gpio_rowout_colin()
{
// 1. 初始化时钟
rcu_periph_clock_enable(RCU_GPIOE);
// 2. 输出模式 行输出推挽
gpio_mode_set(GPIOE, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, ROW1);
gpio_mode_set(GPIOE, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, ROW2);
gpio_mode_set(GPIOE, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, ROW3);
gpio_mode_set(GPIOE, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, ROW4);
// 3. 输入模式 列做输入 GPIO_PUPD_PULLUP 表示上拉输入
gpio_mode_set(GPIOE, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, COL1);
gpio_mode_set(GPIOE, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, COL2);
gpio_mode_set(GPIOE, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, COL3);
gpio_mode_set(GPIOE, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, COL4);
// 4. 行输出做推挽
gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, ROW1);
gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, ROW2);
gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, ROW3);
gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, ROW4);
}
// 行做输入(上拉),列做输出(推挽),检测行
void gpio_rowin_colout()
{
// 1. 初始化时钟
rcu_periph_clock_enable(RCU_GPIOE);
// 2. 输出模式 列输出推挽
gpio_mode_set(GPIOE, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, COL1);
gpio_mode_set(GPIOE, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, COL2);
gpio_mode_set(GPIOE, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, COL3);
gpio_mode_set(GPIOE, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, COL4);
// 3. 输入模式 行做输入 GPIO_PUPD_PULLUP 表示上拉输入
gpio_mode_set(GPIOE, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, ROW1);
gpio_mode_set(GPIOE, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, ROW2);
gpio_mode_set(GPIOE, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, ROW3);
gpio_mode_set(GPIOE, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, ROW4);
// 4. 列输出做推挽
gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, COL1);
gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, COL2);
gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, COL3);
gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, COL4);
}
void led_running(uint8_t row, uint8_t col)
{
if (row == 1)
{
switch(col)
{
case 1:
gpio_bit_reset(GPIOD, LED1); // 点亮LED1(低电平亮灯)
break;
case 2:
gpio_bit_reset(GPIOD, LED2); // 点亮LED2(低电平亮灯)
break;
case 3:
gpio_bit_reset(GPIOD, LED3); // 点亮LED3(低电平亮灯)
break;
case 4:
gpio_bit_reset(GPIOD, LED4); // 点亮LED4(低电平亮灯)
break;
}
}
if (row == 2)
{
switch(col)
{
case 1:
gpio_bit_reset(GPIOD, LED5); // 点亮LED5(低电平亮灯)
break;
case 2:
gpio_bit_reset(GPIOD, LED6); // 点亮LED6(低电平亮灯)
break;
case 3:
gpio_bit_reset(GPIOD, LED7); // 点亮LED7(低电平亮灯)
break;
case 4:
gpio_bit_reset(GPIOD, LED8); // 点亮LED8(低电平亮灯)
break;
}
}
if (row == 3)
{
switch(col)
{
case 1:
gpio_bit_reset(GPIOD, LED8); // 点亮LED5(低电平亮灯)
break;
case 2:
gpio_bit_reset(GPIOD, LED7); // 点亮LED6(低电平亮灯)
break;
case 3:
gpio_bit_reset(GPIOD, LED6); // 点亮LED7(低电平亮灯)
break;
case 4:
gpio_bit_reset(GPIOD, LED5); // 点亮LED8(低电平亮灯)
break;
}
}
if (row == 4)
{
switch(col)
{
case 1:
gpio_bit_reset(GPIOD, LED4); // 点亮LED5(低电平亮灯)
break;
case 2:
gpio_bit_reset(GPIOD, LED3); // 点亮LED6(低电平亮灯)
break;
case 3:
gpio_bit_reset(GPIOD, LED2); // 点亮LED7(低电平亮灯)
break;
case 4:
gpio_bit_reset(GPIOD, LED1); // 点亮LED8(低电平亮灯)
break;
}
}
}
void LED_OFF()
{
gpio_bit_set(GPIOD, LED1); // 高电平灭灯
gpio_bit_set(GPIOD, LED2); // 高电平灭灯
gpio_bit_set(GPIOD, LED3); // 高电平灭灯
gpio_bit_set(GPIOD, LED4); // 高电平灭灯
gpio_bit_set(GPIOD, LED5); // 高电平灭灯
gpio_bit_set(GPIOD, LED6); // 高电平灭灯
gpio_bit_set(GPIOD, LED7); // 高电平灭灯
gpio_bit_set(GPIOD, LED8); // 高电平灭灯
}
int main(void)
{
uint8_t row_state;
uint8_t col_state;
// 系统滴答定时器配置(必须存在)
systick_config();
// 初始化LED灯的电路
gpio_led_config();
while(1)
{
gpio_rowout_colin(); // 先判断列(行出列入) 电平是0表示列中有按键按下
if (gpio_input_bit_get(GPIOE, COL1) == 0)
{ // 第一列有按键按下
col_state = 1;
}else if (gpio_input_bit_get(GPIOE, COL2) == 0)
{
col_state = 2;
}else if (gpio_input_bit_get(GPIOE, COL3) == 0)
{
col_state = 3;
}else if (gpio_input_bit_get(GPIOE, COL4) == 0)
{
col_state = 4;
}else
{
row_state = 0;
col_state = 0;
LED_OFF();
continue;
}
gpio_rowin_colout(); // 判断行(行入列出)
if (gpio_input_bit_get(GPIOE, ROW1) == 0)
{ // 第一列有按键按下
row_state = 1;
}else if (gpio_input_bit_get(GPIOE, ROW2) == 0)
{
row_state = 2;
}else if (gpio_input_bit_get(GPIOE, ROW3) == 0)
{
row_state = 3;
}else if (gpio_input_bit_get(GPIOE, ROW4) == 0)
{
row_state = 4;
}else
{
row_state = 0;
col_state = 0;
LED_OFF();
continue;
}
led_running(row_state, col_state);
}
}
2.读入数据
代码如下(示例):
data = pd.read_csv(
'https://labfile.oss.aliyuncs.com/courses/1283/adult.data.csv')
print(data.head())
该处使用的url网络请求的数据。
总结
提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。
更多推荐
所有评论(0)