- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
1、矩阵键盘 为了减少I/O口的占用,通常将按键排列成矩阵形式。在矩阵式键盘中,每条水平线和垂直线在交叉处不直接连通,而是通过一个按键加以连接。使用8个io口来进行16个按键的控制读取,可以减小io口的使用,用4条I/O线作为行线,4条I/O线作为列线组成的键盘。矩阵键盘检测方法主要有两种,一种是逐行扫描、一种是行列扫描.
1、逐行扫描 通过在矩阵按键的每一条行线上轮流输出低(高)电平,检测矩阵按键的列线,当检测到的列线不全为高(低)电平的时候,说明有按键按下。然后,根据当前输出低电平的行号和检测到低电平的列号组合,判断是哪一个按键被按下.
2、行列扫描 首先,在全部行线上输出低电平,检测矩阵按键的列线,当检测到的列线不全为高电平的时候,说明有按键按下,并判断是哪一列有按键按下。然后,反过来,在全部列线上输出低电平,检测矩阵按键的行线,当检测到的行线不全为高电平的时候,说明有按键按下,并判断是哪一行有按键按下。最后,根据检测到的行号和检测的列号组合,以判断是哪一个按键被按下.
2、程序设计 。
实现效果:逐行扫描矩阵键盘并打印出键值。 思路:保持一列输出高,重复扫描行.
key.c 。
#include "key.h"
uint8_t i=0,j=0;//行、列号
/************************************************
*@Function :key_Init
*@brief :按键GPIO初始化函数
*@param :void
*@retval : void
*************************************************/
void Key_Init(void)
{
//使能GPIO时钟
rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_GPIOB);
//四列 PB1 PB2 PB10 PB11 作为输出
gpio_init(GPIOB,GPIO_MODE_OUT_PP,GPIO_OSPEED_10MHZ,GPIO_PIN_1);
gpio_init(GPIOB,GPIO_MODE_OUT_PP,GPIO_OSPEED_10MHZ,GPIO_PIN_2);
gpio_init(GPIOB,GPIO_MODE_OUT_PP,GPIO_OSPEED_10MHZ,GPIO_PIN_10);
gpio_init(GPIOB,GPIO_MODE_OUT_PP,GPIO_OSPEED_10MHZ,GPIO_PIN_11);
//四行 PA3 PA4 PA5 PA6 下拉输入 默认为低电平
gpio_init(GPIOA,GPIO_MODE_IPD,GPIO_OSPEED_10MHZ,GPIO_PIN_3);
gpio_init(GPIOA,GPIO_MODE_IPD,GPIO_OSPEED_10MHZ,GPIO_PIN_4);
gpio_init(GPIOA,GPIO_MODE_IPD,GPIO_OSPEED_10MHZ,GPIO_PIN_5);
gpio_init(GPIOA,GPIO_MODE_IPD,GPIO_OSPEED_10MHZ,GPIO_PIN_6);
//列初始化为低电平
gpio_bit_reset(GPIOB, GPIO_PIN_1);
gpio_bit_reset(GPIOB, GPIO_PIN_2);
gpio_bit_reset(GPIOB, GPIO_PIN_10);
gpio_bit_reset(GPIOB, GPIO_PIN_11);
}
/************************************************
*@Function :Rank1_Scan(void)
*@brief :第一行扫描函数
*@param :void
*@retval : 0(可以返回行号i)
*************************************************/
uint8_t Rank1_Scan(void)
{
//第一列输出高,其它三列输出低
gpio_bit_set(GPIOB, GPIO_PIN_1);
gpio_bit_reset(GPIOB, GPIO_PIN_2);
gpio_bit_reset(GPIOB, GPIO_PIN_10);
gpio_bit_reset(GPIOB, GPIO_PIN_11);
//检测第一行按键状态,为高则按下
if(gpio_input_bit_get(GPIOA, GPIO_PIN_3)==1)
{
delay_1ms(10);//消抖
while(gpio_input_bit_get(GPIOA, GPIO_PIN_3)==1)
delay_1ms(10);
printf("KeyNumber:%d\r\n",KEY1);
}
//检测第二行按键状态,为高则按下
if(gpio_input_bit_get(GPIOA, GPIO_PIN_4)==1)
{
delay_1ms(10);;
while(gpio_input_bit_get(GPIOA, GPIO_PIN_4)==1)
delay_1ms(10);;
printf("KeyNumber:%d\r\n",KEY5);
}
//检测第三行按键状态
if(gpio_input_bit_get(GPIOA, GPIO_PIN_5)==1)
{
delay_1ms(10);;
while(gpio_input_bit_get(GPIOA, GPIO_PIN_5)==1)
delay_1ms(10);
printf("KeyNumber:%d\r\n",KEY9);
}
//检测第四行按键状态
if(gpio_input_bit_get(GPIOA, GPIO_PIN_6)==1)
{
delay_1ms(10);
while(gpio_input_bit_get(GPIOA, GPIO_PIN_6)==1)
delay_1ms(10);
printf("KeyNumber:%d\r\n",KEY13);
}
gpio_bit_reset(GPIOB, GPIO_PIN_1);//将第一列拉低回原状态
return 0;
}
主函数 。
#include "gd32f10x.h"
#include "gd32f103c_eval.h"
#include "systick.h"
#include "key.h"
#include "usart.h"
int main(void)
{
systick_config();//系统时钟
//USART相关配置
Usart_Init();
Key_Init();
printf("Init OK!\r\n");
while(1)
{
Rank1_Scan();
}
}
以上是行扫描实现思路,剩下的按键只需将剩下的三列依次保持一列输出高,重复扫描行即可.
3、实验现象 。
实际测试均能准确打印出键值.
4、程序优化 。
行扫描程序有大量重复代码,可以使用循环语句嵌套条件选择语句将四列依次置高,这样就只需要一段通用的行扫描语句,降低重复率.
最后此篇关于国产MCU兆易GD32实现矩阵按键扫描的文章就讲到这里了,如果你想了解更多关于国产MCU兆易GD32实现矩阵按键扫描的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我有一段代码看起来像这样: void update_clock(uint8_t *time_array) { time_t time = *((time_t *) &time_array[0]
我有一 block 带有特殊 UEXT connector 的 Olimex A20 板它可以连接 SPI、I2C 和 RS 232。我喜欢使用 Olimex 的 MOD Zigbee 模块直接通过
我有一个在基于 ARM Cortex-M 的 MCU 上运行并用 C 和 C++ 编写的应用程序。我用 gcc和 g++编译它并希望完全禁用任何堆使用。 在 MCU 启动文件中,堆大小已设置为 0。除
我目前正在学习微 Controller 和处理器,我对两者之间的一些区别有一些疑问。据我了解,MCU 包含一个实现处理器架构的处理器。例如,我正在使用 SAML22 微 Controller ,其处理
有很多类似的问题,但似乎没有一个问题完全相同。我正在将 STML4 MCU 连接到 6 轴传感器 (LSM6DS3)。我已经成功地在 I2C 中实现了所有内容,但想要 SPI 的额外速度(和 DMA,
我正在尝试将部分二进制文件的 md5 哈希值插入到二进制文件中,以跟踪 MCU 固件版本。 我是这样处理的:在链接脚本中,我将 Flash 分成两部分 MEMORY
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 6 年前。 Improve this qu
我正在尝试弄清楚如何为我的 C8051F020 MCU 创建一个定时器。以下代码使用通过以下公式传递给 init_Timer2() 的值: 65535-(0.1/(12/2000000)=48868。
我之前有编写基于事件和轮询的嵌入式系统的经验(适用于没有抢占式操作系统的微型 MCU)。 在基于事件的系统中,任务通常在队列上接收事件(消息)并依次处理它们。 在基于轮询的系统中,任务以一定的时间间隔
我是 python 的新手,我正在使用 2.7 和 spyder 我有一个运行这个的 anduino 风格的板子: void setup() { Serial1.begin(115200); }
我是 python 的新手,我正在使用 2.7 和 spyder 我有一个运行这个的 anduino 风格的板子: void setup() { Serial1.begin(115200); }
我想使用JAVA提取JPEG文件的各个MCU。我在JPEG header 中找不到有关MCU的信息。信息如下:JPEg的MCU大小是8x8、16x8、8x16还是16x16?或提取单个 MCU 所需的
我正在致力于将字节数组的内容从 Android 移动应用程序传输到 MCU。我能够成功地逐字节传输数据(多个数据包),但无法成功发送整个数组(作为一个数据包)。应该注意的是,数据将通过 GATT 配置
我正在从事一个项目,该项目涉及让 FreeRTOS 的 CMSIS-RTOS 打包在 STM32F051C6 上运行。我在 Visual Studio 中使用 VisualGDB 编写和调试代码,并使
下面的代码是如何在单片机上使用实时时钟的示例。 我的问题与回调和函数指针有关。 我在下面包含了 rtc_config_t 的结构声明。 我的问题是,在线 cfg.callback = rtc_exam
在我看来,MCU RAM 包含链接器值、全局范围变量、堆、堆栈,然后某些部分未使用。 因此,工程师是否倾向于发布固件,使一些 MCU RAM 未被使用,因为应用程序不需要它来运行? 最佳答案 这取决于
这里是新手。我目前正在从事一个涉及在 MCU(NUC200LE3AN) 闪存上保存密码的项目。 这些代码工作得很好。写入后,即使在 MCU 重新启动后,我也能够读取 user_password1 的确
简介:我设计了一个带有 ATSAME54N20A 的嵌入式系统。 32 位 ARM® Cortex®-M4F MCU。该板将很快组装好并准备好进行编程,因此我正在设置我的编程环境。我选择了一个简单的解
我只是尝试使用 Scott Meyers 在“Effectice C++ in an Embedded Environment”中建议的 placement new 运算符。 DefaultM
我有一个带有集成和可自定义聊天系统(基于 XMPP)的网站。 我尝试过很多 WebRTC 框架,比如 licode , muaz-khan's , jinja 的插件, OpenTok对于 WebRT
我是一名优秀的程序员,十分优秀!