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

cathy的头像
cathy 发布于:周五, 09/08/2023 - 10:49 ,关键词:

例程资料链接如下:

BD网盘链接:

https://pan.baidu.com/s/1JUMZH-sJAH-dPB0AtEvE7w

提取码:oe9t

一、简介 

1.薄膜式键盘是一种常见的输入设备,它由一层薄膜电路板和一层触摸膜组成。薄膜电路板上印有导电图案,而触摸膜则具有与之对应的按键区域。这种键盘的应用场景非常广泛,以下是几个典型的应用场景:

(1)电子产品:薄膜式键盘被广泛应用于各种电子产品中,如手机、平板电脑、数码相机等。由于其结构简单、体积小巧,可以很好地满足电子产品的设计需求。

(2)工业控制:在工业自动化领域,薄膜式键盘常用于控制面板和操作界面。它们具有防尘、防水、抗腐蚀等特性,能够适应恶劣的工作环境。

(3)医疗设备:医疗设备通常需要高度卫生和易清洁的特点,薄膜式键盘因其表面光滑、易擦拭的特性而被广泛应用于医疗设备中,如手术台、心电图仪等。

二、所需物料

本实验使用到了CW32-48F大学计划开发板、5*4薄膜式键盘模块、0.96寸OLED显示屏及Keil5开发环境。开发板上留有矩阵键盘接口,可以直接将模块插上使用。

1.png

CW32-48F大学计划板   

2.png

5*4薄膜式键盘

   3.png

键盘内部连线示意图

注:键盘的9根引线从左至右分别与单片机引脚PB15、PB14、PB13、PB12、PA6、PA5、PA4、PA1、PA0相连。

三、核心代码

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[i]=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[i],GPIO_Pin_RESET);    
        for( j = 0; j < COL_NUM; j ++ )  //依次检测1~4列电平    
        {      
            if( GPIO_ReadPin(COL_PORT,col_pins[j])==RESET )  //如果检测到低电平,则代表有按键按下      
            {        
                key = key_value[i][j];    //获取键值        
                break;            //跳出检列循环      
            }    
        }    
        GPIO_WritePin(ROW_PORT,row_pins[i],GPIO_Pin_SET);  //本行恢复高电平,准备置低下一行    
        if(key != '.') break; //若key不是默认值,则代表已检测到按键按下,退出置行循环,结束本次按键扫描  
    }   
    
    return key;  //返回键值
}

四、效果演示

4.png

5.png

6.png

7.png

来源:CW32生态社区

免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 15