例程资料链接如下:
BD网盘链接:
https://pan.baidu.com/s/1JUMZH-sJAH-dPB0AtEvE7w
提取码:oe9t
相关视频:基于CW32的薄膜式键盘的应用
一、简介
薄膜式键盘是一种常见的输入设备,它由一层薄膜电路板和一层触摸膜组成。薄膜电路板上印有导电图案,而触摸膜则具有与之对应的按键区域。这种键盘的应用场景非常广泛,以下是几个典型的应用场景:
(1)电子产品:薄膜式键盘被广泛应用于各种电子产品中,如手机、平板电脑、数码相机等。由于其结构简单、体积小巧,可以很好地满足电子产品的设计需求。
(2)工业控制:在工业自动化领域,薄膜式键盘常用于控制面板和操作界面。它们具有防尘、防水、抗腐蚀等特性,能够适应恶劣的工作环境。
(3)医疗设备:医疗设备通常需要高度卫生和易清洁的特点,薄膜式键盘因其表面光滑、易擦拭的特性而被广泛应用于医疗设备中,如手术台、心电图仪等。
二、所需物料
本实验使用到了CW32-48F大学计划开发板、5*4薄膜式键盘模块、0.96寸OLED显示屏及Keil5开发环境。开发板上留有矩阵键盘接口,可以直接将模块插上使用。
三、核心代码
main.c:
#include "main.h"
#include "OLED.h"
#include "Key.h"
#include "Delay.h"
#include "BTIM.h"
#define NUM_LENGTH 6
uint8_t choose_flag=0; //选中标识
uint8_t choose_index=0; //数组下标
uint8_t exert_flag=0; //执行标识
uint8_t number[NUM_LENGTH]={0}; //存储6位数字
uint8_t num_index=0; //数组下标
char temp='.'; //默认值'.'
int main()
{
uint8_t i;
uint8_t position=0; //选中的数字在数组中的位置
OLED_Init(); //OLED显示
Key_GPIO_Init(); //5*4薄膜键盘GPIO初始化
BTIM_Init(); //定时器初始化,控制按键扫描周期
while(1)
{
if(exert_flag==1) //若执行标识已打开
{
switch(temp)
{
case '<': //选中左移
if(choose_flag==0) position=choose_index+1; //向左选中数字
if(position!=0) //若已有数字输入
{
choose_flag=1; //打开选中标识
OLED_Clear_Row(2); //先清除已有标识符号‘^’
if(--position==0) position=choose_index; //选中左移
OLED_ShowChar(2,position,'^'); //显示选中标识符号'^'
}
break;
case '>':
if(choose_flag==0) position=choose_index; //向右选中数字
if(position!=0) //若已有数字输入
{
choose_flag=1; //打开选中标识
OLED_Clear_Row(2); //先清除已有标识符号'^'
if(++position==choose_index+1) position=1;//选中右移
OLED_ShowChar(2,position,'^'); //显示选中标识符号'^'
}
break;
case 'E':
choose_flag=0; //关闭选中标识
OLED_Clear_Row(2); //清除选中标识符号'^'
break;
default:
if(choose_flag==0) //若未打开选中标识
{
choose_index=num_index+1;
if(num_index==0)
{
OLED_Clear_Row(1);
for(i=0;i<NUM_LENGTH;i++) //溢出清零
number=0;
}
number[num_index]=temp;
OLED_ShowNum(1,num_index+1,number[num_index],1);
num_index++; //输入右移
choose_index=num_index;
if(num_index==NUM_LENGTH) num_index=0;
}
else
{
number[position-1]=temp; //若已打开选中标识,将获取的键值保存至数组中对应的位置
OLED_ShowNum(1,position,number[position-1],1);//显示屏上覆盖原有数字
}
break;
}
exert_flag=0; //执行后关闭标识
}
}
}
void BTIM1_IRQHandler(void) //基本定时器1中断服务函数
{
static uint8_t cnt = 0;
if(BTIM_GetITStatus(CW_BTIM1,BTIM_IT_OV))
{
if(++cnt>=18)
{
cnt=0;
temp=Key_Scan(); //每180ms执行一次按键扫描,返回值赋值给temp
if(temp!='.') exert_flag=1; //打开执行标识
}
BTIM_ClearITPendingBit(CW_BTIM1,BTIM_IT_OV); //清除标志位
}
}
Key.c:
#include "Key.h"
#include "main.h"
#include "Delay.h"
#include "OLED.h"
#define ROW_PORT CW_GPIOA //键盘行引脚端口
#define COL_PORT CW_GPIOB //键盘列引脚端口
#define ROW_NUM 4 //4行
#define COL_NUM 4 //4列
uint16_t row_pins[ROW_NUM]={GPIO_PIN_1,GPIO_PIN_4,GPIO_PIN_5,GPIO_PIN_6}; //每一行所对应的引脚
uint16_t col_pins[COL_NUM]={GPIO_PIN_15,GPIO_PIN_14,GPIO_PIN_13,GPIO_PIN_12}; //每一列所对应的引脚
char key_value[ROW_NUM][COL_NUM]={ //键值
1, 2, 3, '(',
4, 5, 6, ')',
7, 8, 9, 'E',
'<', 0, '>', 'Y'
};
void Key_GPIO_Init(void)
{
__RCC_GPIOA_CLK_ENABLE();
__RCC_GPIOB_CLK_ENABLE();
//rows-->置行
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.IT=GPIO_IT_NONE;
GPIO_InitStruct.Mode=GPIO_MODE_OUTPUT_PP; //推挽输出
GPIO_InitStruct.Pins=row_pins[0]|row_pins[1]|row_pins[2]|row_pins[3];
GPIO_InitStruct.Speed=GPIO_SPEED_HIGH;
GPIO_Init(ROW_PORT, &GPIO_InitStruct);
//cols-->检列
GPIO_InitStruct.Mode=GPIO_MODE_INPUT_PULLUP; //上拉输入
GPIO_InitStruct.Pins=col_pins[0]|col_pins[1]|col_pins[2]|col_pins[3];
GPIO_Init(COL_PORT, &GPIO_InitStruct);
}
char Key_Scan(void)
{
uint8_t i,j;
char key = '.'; //默认值'.'
for ( i = 0; i < ROW_NUM; i ++ ) //1-4行依次置低
{
GPIO_WritePin(ROW_PORT,row_pins,GPIO_Pin_RESET);
for( j = 0; j < COL_NUM; j ++ ) //依次检测1~4列电平
{
if( GPIO_ReadPin(COL_PORT,col_pins[j])==RESET ) //如果检测到低电平,则代表有按键按下
{
key = key_value[j]; //获取键值
break; //跳出检列循环
}
}
GPIO_WritePin(ROW_PORT,row_pins,GPIO_Pin_SET); //本行恢复高电平,准备置低下一行
if(key != '.') break; //若key不是默认值,则代表已检测到按键按下,退出置行循环,结束本次按键扫描
}
return key; //返回键值
}
四、效果演示
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/2302_81038468/article/details/136449440
|
 共1人点赞
|