网站去哪里做,wordpress 主题 企业,网站设计软件手机版,创建公司网站 教程这里写目录标题 1、矩阵按键2、代码片段分析 1、矩阵按键 通过将4x4矩阵按键的每一行依次设为低电平#xff0c;同时保持其它行为高电平#xff0c;然后读取所有列的电平状态#xff0c;可以检测到哪个按键被按下。如果某列变为低电平#xff0c;说明对应行和列的按键被按下… 这里写目录标题 1、矩阵按键2、代码片段分析 1、矩阵按键 通过将4x4矩阵按键的每一行依次设为低电平同时保持其它行为高电平然后读取所有列的电平状态可以检测到哪个按键被按下。如果某列变为低电平说明对应行和列的按键被按下。这样逐行扫描即可确定按键的位置。 2、代码片段分析
/*********************************************************************Function : 矩阵键盘行列读写操作Parameter : ReadIo 读输入的IOWirteIo 写输出的IOReturn : 行列IO输出状态
**********************************************************************/
uint8_t GPIO_KEY_RW(uint16_t ReadIo,uint16_t WirteIo)
{uint16_t Wdata0,Rdata0; /* 写操作 */KeyBordSetOut(KEY_ALL); //设置IOif(WirteIo0x0f00)GPIO_SetBits(GPIOE,KEY_LINE); //写行else GPIO_ResetBits(GPIOE,KEY_LIST); //写列 Wdata GPIO_ReadOutputData(GPIOE);//读输出 Wdata WirteIo; //取有效区域/* 读操作 */KeyBordSetIn(ReadIo); //设置IO Rdata GPIO_ReadInputData(GPIOE); //读输入Rdata ReadIo; //取有效区域/* 状态返回 */Rdata | Wdata; //合并两次读取的数据return (uint8_t)(Rdata8); //移位返回
}
初始化
Wdata 和 Rdata 初始化为 0。 写操作
检查 WirteIo 是否为 0x0f00二进制0000111100000000 如果是则设置 GPIOE 中对应 KEY_LINE 的位具体位取决于 KEY_LINE 的定义。 如果不是则复位 GPIOE 中对应 KEY_LIST 的位具体位取决于 KEY_LIST 的定义。 读取 GPIOE 的输出数据到 Wdata。 Wdata 与 WirteIo 进行与操作保留有效区域的数据。 读操作
使用 ReadIo 设置IO方向。 读取 GPIOE 的输入数据到 Rdata。 Rdata 与 ReadIo 进行与操作保留有效区域的数据。 状态返回
将 Wdata 和 Rdata 进行或操作合并两次读取的数据。 返回 Rdata 右移8位后的值。 假设按下第一个按键 假设按下的是第一个按键具体的步骤如下
初始化
Wdata 0 Rdata 0 写操作
WirteIo 0x0f00 假设为真则设置 GPIOE 对应 KEY_LINE 的位。 读取 GPIOE 输出数据 假设 GPIOE 输出数据为 0000111100000000二进制。 Wdata WirteIo Wdata 0000111100000000 0000111100000000 0000111100000000 读操作
设置IO方向具体操作取决于 KeyBordSetIn 函数。 读取 GPIOE 输入数据 假设按下第一个按键时GPIOE 输入数据为 0000000100000000二进制。 Rdata ReadIo Rdata 0000000100000000 ReadIo假设 ReadIo 为 0000000100000000结果 Rdata 0000000100000000 状态返回
Rdata | Wdata Rdata 0000000100000000 | 0000111100000000 0000111100000000 返回值 将 Rdata 右移8位后返回Rdata 8 00001111 所以函数返回值为 0x0F二进制00001111 /*********************************************************************Function : 矩阵键盘键值扫描Parameter : N/AReturn : 键值
**********************************************************************/
uint8_t KeyBoardScan(void)
{uint8_t KeyValue0,Key0;uint8_t a 0;/* 检测键盘是否有按键按下0x0f表示所有列都未按下 */if(GPIO_KEY_RW(KEY_LIST,KEY_LINE)!0x0f){/* 测试列状态 */Key GPIO_KEY_RW(KEY_LIST,KEY_LINE); // 读取列的状态/* 判断列状态并映射为按键值 */switch(Key){case(0x1F): // 第一列所有行都按下KeyValue 1; // 对应键值为1break;case(0x2F): // 第二列所有行都按下KeyValue 2; // 对应键值为2break;case(0x4F): // 第三列所有行都按下KeyValue 3; // 对应键值为3break;case(0x8F): // 第四列所有行都按下KeyValue 4; // 对应键值为4break;}/* 测试行状态 */Key GPIO_KEY_RW(KEY_LINE,KEY_LIST); // 读取行的状态/* 判断行状态并映射为按键值 */switch(Key){case(0x0E): // 第一行所有列都按下KeyValue KeyValue; // 保持当前列的键值不变break;case(0x0D): // 第二行所有列都按下KeyValue KeyValue 4; // 当前列的键值加4对应第二行break;case(0x0B): // 第三行所有列都按下KeyValue KeyValue 8; // 当前列的键值加8对应第三行break;case(0x07): // 第四行所有列都按下KeyValue KeyValue 12; // 当前列的键值加12对应第四行break;}/* 按键松手检测 */while((a 50) (Key ! 0x00)) // 循环检测按键是否松手最多检测50次{delay_ms(5); // 延时5毫秒Key GPIO_KEY_RW(KEY_LINE,KEY_LIST); // 再次读取行的状态a 1; // 计数器加1}}/* 返回键值 */return KeyValue;
}