打印
[产品应用]

基于CW32的薄膜式键盘的应用

[复制链接]
51|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
例程资料链接如下:
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

使用特权

评论回复
沙发
AdaMaYun| | 2025-4-12 21:41 | 只看该作者
案件原理非常实用

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

27

主题

80

帖子

0

粉丝