一乐电子

 找回密码
 请使用微信账号登录和注册会员

QQ登录

只需一步,快速开始

微信扫码登录

手机号码,快捷登录

手机号码,快捷登录

搜索
查看: 2303|回复: 1

[其他综合] 采用138的16键键盘电路试验程序

[复制链接]
发表于 2012-4-3 10:33 | 显示全部楼层 |阅读模式
朋友拿了一个16键的键盘电路板,要求编一个能取出16个键的长按和短按的键值。这个电路以前没有接触过,它和一般的4*4矩阵电路不同,好像应该是2列8行,1列接到单片机的INT0口的P3.2,1列接到INT1口的P3.3. 8行分别接到138的y0-y7,138的A,B,C分别接单片机的p3.5,p3.6,p3.7,这样一共用5个口就可以控制16个按键比一般的常规4*4矩阵电路可以节省3个口。在单片机的资源不是太紧张的时候这样使用,而且占用了2个外部中断口,有什么好处呢?(没有想明白,可能是单片机的资源紧张吧,据说是用的80元1片的单片机哟,呵呵。)参考电路图,学习用c编写,试了2天,写了一个可以取出长按和短按的键值的使用程序附后,有兴趣的朋友或者到时有可能IO口紧张不够用的朋友,可以一起交流探讨,现在这个程序写得太烂,太野,我是知道的,仅仅是能用而已,呵呵。

16键电路图

16键电路图


/*********************************************
2012-03-29
键盘程序试验.c
**********************************************/   
#include<reg1210.h>
#include<intrins.h>
#include"lr_lcd_api.h"
#include <stdio.h>   
sbit led_1=P1^6;
sbit led_2=P0^5;
sbit  key1=P1^1;
sbit  key2=P0^6;
sbit io_int0=P3^2;
sbit io_int1=P3^3;
sbit a_138=P3^5;
sbit b_138=P3^6;
sbit c_138=P3^7;
#define uchar unsigned char
#define uint unsigned int
unsigned char code string5c[]="5_ca";
unsigned char code string5[]="5_da";
unsigned char code string6c[]="6_ca";
unsigned char code string6[]="6_da";
unsigned char code string7c[]="7_ca";
unsigned char code string7[]="7_da";
unsigned char code string8c[]="8_ca";
unsigned char code string8[]="8_da";
unsigned char code string9c[]="9_ca";
unsigned char code string9[]="9_da";
unsigned char code string10c[]="10_ca";
unsigned char code string10[]="10_da";
unsigned char code string11c[]="11_ca";
unsigned char code string11[]="11_da";
unsigned char code string12c[]="12_ca";
unsigned char code string12[]="12_da";
unsigned char code string13c[]="13_ca";
unsigned char code string13[]="13_da";
unsigned char code string14c[]="14_ca";
unsigned char code string14[]="14_da";
unsigned char code string15c[]="15_ca";
unsigned char code string15[]="15_da";
unsigned char code string16c[]="16_ca";
unsigned char code string16[]="16_da";
unsigned char code string17c[]="17_ca";
unsigned char code string17[]="17_da";
unsigned char code string18c[]="18_ca";
unsigned char code string18[]="18_da";
unsigned char code string19c[]="19_ca";
unsigned char code string19[]="19_da";
unsigned char code string20c[]="20_ca";
unsigned char code string20[]="20_da";
bit f_int0;
bit f_int1;         
uchar key_z=0xff;
uchar key_z_0_00b;   //短按键键值(0x0x) 对应INT0
uchar key_z_0_c0b;   //长按键键值(0xcx) 对应INT0
uchar key_z_1_00b;   //短按键键值(0x0x) 对应INT1
uchar key_z_1_c0b;   //长按键键值(0xcx) 对应INT1

uchar key_jsq=0;   //按键实际的按下时间(变量)
#define aj_ca_da_bz 25 //按键长按短按标准 (常量)

#define k5_da_z 0x00
#define k5_ca_z 0xc0
#define k6_da_z 0x01
#define k6_ca_z 0xc1
#define k7_da_z 0x02
#define k7_ca_z 0xc2
#define k8_da_z 0x03
#define k8_ca_z 0xc3
#define k9_da_z 0x04
#define k9_ca_z 0xc4
#define k10_da_z 0x05
#define k10_ca_z 0xc5
#define k11_da_z 0x06
#define k11_ca_z 0xc6
#define k12_da_z 0x07
#define k12_ca_z 0xc7
#define k13_da_z 0x08
#define k13_ca_z 0xc8
#define k14_da_z 0x09
#define k14_ca_z 0xc9
#define k15_da_z 0x0a
#define k15_ca_z 0xca
#define k16_da_z 0x0b
#define k16_ca_z 0xcb
#define k17_da_z 0x0c
#define k17_ca_z 0xcc
#define k18_da_z 0x0d
#define k18_ca_z 0xcd
#define k19_da_z 0x0e
#define k19_ca_z 0xce
#define k20_da_z 0x0f
#define k20_ca_z 0xcf
/**********************************************************/
/**********************************************************/
//串口初始化
void init_serialcomm(void)
{
     SCON0=0x50;        //在12MHz下,设置串行口波特率为9600,方式1,并允许接收
     PCON=0x00;
     T2CON=0X34;        //定时器2波特率自动重装
     RCAP2H=0xff;       //波特率9600,时钟频率12MHZ
     RCAP2L=0xdC;//9;
     EA=1;  
     ES=0;  //开串口中断
}
/************************************************************/
//中断接收服务程序
void serial () interrupt 4 using 3
{   
   if(RI)
    {
  RI=0;//清中断标志
    }
  if(TI)
    {
TI=0;//清发送标志位
}
}
/**********************************************************/
//定时器0中断初始化
void init_t0(void){
   TMOD=0x01;  //用定时器0
   TH0=76;
   TL0=0;
   ET0=1; //定时器0中断允许
   TR0=1;
   EA=1;
}  
/**********************************************************/
//定时器0中断服务程序
void it0() interrupt 1 using 1
{ TH0=76;
TL0=0;
key_jsq++;
}
/**********************************************************/
//外部中断0,外部中断1初始化
//允许外部中断0,外部中断1中断,设置为边缘触发
void init_int0int1(void){     
  
  f_int0=0;
  f_int1=0;  
   
   IT0=1;  //外部中断0设为边缘触发
   IT1=1;  //外部中断1设为边缘触发
   EX0=1;
   EX1=1;
   EA=1;
}
/***********************************************************/
//外部中断0服务程序
void int0() interrupt 0 using 0
{
  EX0=0;   
  f_int0=1;

}         
/***********************************************************/
//外部中断1服务程序
void int1() interrupt 2 using 2
{
  EX1=0;     

  f_int1=1;
}
/**********************************************************/   
/**********************************************************/  
void delay(uint dly)
{while(dly--)
{ _nop_();
   _nop_();
   _nop_();
   _nop_();
}}
//##############################################################
//##############################################################
void LR_Send_Char(uchar byte)//串口发送一个字节
  {
//  while(DTR==1);//判断是否忙,如果忙的话,一直等待
   SBUF=byte;
   while(TI==0);
   TI=0;
  }
/*===============================================
函数功能:显示字符前用
参数列表:无
2012-03-21  fxh
=================================================*/
void LR_LCD_show_string(){         
LR_Send_Char(0x1b);
LR_Send_Char(0x25);
LR_Send_Char(0x01);
}
/*===============================================
/*===============================================
函数功能:自动判断、显示字符
参数列表:
     buf: 存放要显示的字符缓冲区,要以0结尾
特别注意,buf的最后要有一个0——就是说多添加一个0
=================================================*/
void LR_LCD_ShowString(unsigned char *buf)
{
LR_LCD_show_string();
while(*buf)LR_Send_Char(*buf++);  
}
//################################################################
/*===============================================
函数功能:调用预置画面
参数列表:
    n:预置画面的起始页
=================================================*/
void LR_LCD_CallPage(uchar n)
{
LR_Send_Char(0x1b);
LR_Send_Char(0x50);
LR_Send_Char(n);
}
/*==================================================
函数功能:清屏
参数列表:
    clr:清屏颜色
===================================================*/
void LR_LCD_ScreenClear(uchar clr)
{
LR_Send_Char(0x1b);
LR_Send_Char(0x42);
LR_Send_Char(clr);
}
/**********************************************************/
/*===================================================
函数功能:取按键值
参数列表:
=====================================================*/
void q_key_z(void)
  {
   while(f_int0){ key_jsq=0;
           while(!io_int0){                 
   if(key_jsq>=aj_ca_da_bz){key_jsq=0; key_z=key_z_0_c0b;}}   

  if(key_z==key_z_0_c0b){key_jsq=0;f_int0=0;EX0=1;delay(4400);}
  else { key_z=key_z_0_00b;f_int0=0;EX0=1;delay(4400);}
       }
//-------------------------------------------------------------------   
   while(f_int1){ key_jsq=0;
           while(!io_int1){                 
   if(key_jsq>=aj_ca_da_bz){key_jsq=0; key_z=key_z_1_c0b;}}   

  if(key_z==key_z_1_c0b){key_jsq=0;f_int1=0;EX1=1;delay(4400);}
  else { key_z=key_z_1_00b;f_int1=0;EX1=1;delay(4400);}      
       }
  }
/********************************************************************
/*******************************************************************/
/*******************************************************************/
void main()
{ //uchar k;
delay(100);
init_t0();
init_serialcomm();

LR_LCD_ScreenClear(1); //发送清兰屏指令1B 42 01
   
    led_1=1;
    led_2=0;
    init_int0int1();
key_z=0xff;
while(1){
   key_z=0xff;
  
   if(key1==0){led_1=~led_1;led_2=~led_2;while(key1==0){;}}
   //if(key2==0){

   // LR_LCD_ShowString(string20);
//LR_LCD_CallPage(48);

//k++; if(k>7)k=0; while(key2==0){;} delay(1000);
  // }
/***********************************************************/     
   c_138=0;b_138=0;a_138=0;  //000
   delay(2200);  
   
  key_z_0_c0b=k17_ca_z; //
  key_z_0_00b=k17_da_z; //
  
  key_z_1_c0b=k18_ca_z; //
  key_z_1_00b=k18_da_z; //
   q_key_z();
/***********************************************************/
   c_138=0;b_138=0;a_138=1;  //001
   delay(2200);  
  key_z_0_c0b=k13_ca_z; //
  key_z_0_00b=k13_da_z; //
  
  key_z_1_c0b=k14_ca_z; //
  key_z_1_00b=k14_da_z;  //
  
   q_key_z();
/***********************************************************/   
   c_138=0;b_138=1;a_138=0; //010
   delay(2200);  
  key_z_0_c0b=k9_ca_z;  //
  key_z_0_00b=k9_da_z;  //
  
  key_z_1_c0b=k10_ca_z; //
  key_z_1_00b=k10_da_z;  //
   
   q_key_z();
/***********************************************************/
   c_138=0;b_138=1;a_138=1; //011
   delay(2200);  
  key_z_0_c0b=k5_ca_z;  //
  key_z_0_00b=k5_da_z;  //
  
  key_z_1_c0b=k6_ca_z;  //
  key_z_1_00b=k6_da_z;   //
   
   q_key_z();
/***********************************************************/
   c_138=1;b_138=0;a_138=0; //100
   delay(2200);  
   
  key_z_0_c0b=k20_ca_z;
  key_z_0_00b=k20_da_z;
  
  key_z_1_c0b=k19_ca_z;
  key_z_1_00b=k19_da_z;
   
   q_key_z();
/***********************************************************/  
   c_138=1;b_138=0;a_138=1; //101
   delay(2200);
  key_z_0_c0b=k16_ca_z;  //
  key_z_0_00b=k16_da_z;  //
  
  key_z_1_c0b=k15_ca_z;  //
  key_z_1_00b=k15_da_z;   //
   
   q_key_z();
/***********************************************************/  
   c_138=1;b_138=1;a_138=0; //110
   delay(2200);
  key_z_0_c0b=k12_ca_z;   //
  key_z_0_00b=k12_da_z;   //
  
  key_z_1_c0b=k11_ca_z;   //
  key_z_1_00b=k11_da_z;    //
   
   q_key_z();
/***********************************************************/  
   c_138=1;b_138=1;a_138=1; //111
   delay(2200);
  
  key_z_0_c0b=k8_ca_z; //
  key_z_0_00b=k8_da_z; //
  
  key_z_1_c0b=k7_ca_z; //
  key_z_1_00b=k7_da_z;  //
   
   q_key_z();
/**************************************************************/  
   switch(key_z){
     case k20_ca_z: LR_LCD_ScreenClear(0); LR_LCD_ShowString(string20c);break;
     case k20_da_z: LR_LCD_ScreenClear(0); LR_LCD_ShowString(string20);break;
  
  case k19_ca_z: LR_LCD_ScreenClear(0); LR_LCD_ShowString(string19c);break;
     case k19_da_z: LR_LCD_ScreenClear(0); LR_LCD_ShowString(string19);break;
   
     case k18_ca_z: LR_LCD_ScreenClear(0); LR_LCD_ShowString(string18c);break;
     case k18_da_z: LR_LCD_ScreenClear(0); LR_LCD_ShowString(string18);break;
     case k17_ca_z: LR_LCD_ScreenClear(0); LR_LCD_ShowString(string17c);break;
     case k17_da_z: LR_LCD_ScreenClear(0); LR_LCD_ShowString(string17);break;
     case k16_ca_z: LR_LCD_ScreenClear(0); LR_LCD_ShowString(string16c);break;
     case k16_da_z: LR_LCD_ScreenClear(0); LR_LCD_ShowString(string16);break;
     case k15_ca_z: LR_LCD_ScreenClear(0); LR_LCD_ShowString(string15c);break;
     case k15_da_z: LR_LCD_ScreenClear(0); LR_LCD_ShowString(string15);break;
     case k14_ca_z: LR_LCD_ScreenClear(0); LR_LCD_ShowString(string14c);break;
     case k14_da_z: LR_LCD_ScreenClear(0); LR_LCD_ShowString(string14);break;
     case k13_ca_z: LR_LCD_ScreenClear(0); LR_LCD_ShowString(string13c);break;
     case k13_da_z: LR_LCD_ScreenClear(0); LR_LCD_ShowString(string13);break;
     case k12_ca_z: LR_LCD_ScreenClear(0); LR_LCD_ShowString(string12c);break;
     case k12_da_z: LR_LCD_ScreenClear(0); LR_LCD_ShowString(string12);break;
     case k11_ca_z: LR_LCD_ScreenClear(0); LR_LCD_ShowString(string11c);break;
     case k11_da_z: LR_LCD_ScreenClear(0); LR_LCD_ShowString(string11);break;
     
  case k10_ca_z: LR_LCD_ScreenClear(0); LR_LCD_ShowString(string10c);break;
     case k10_da_z: LR_LCD_ScreenClear(0); LR_LCD_ShowString(string10);break;
     case k9_ca_z: LR_LCD_ScreenClear(0); LR_LCD_ShowString(string9c);break;
     case k9_da_z: LR_LCD_ScreenClear(0); LR_LCD_ShowString(string9);break;
     case k8_ca_z: LR_LCD_ScreenClear(0); LR_LCD_ShowString(string8c);break;
     case k8_da_z: LR_LCD_ScreenClear(0); LR_LCD_ShowString(string8);break;
     case k7_ca_z: LR_LCD_ScreenClear(0); LR_LCD_ShowString(string7c);break;
     case k7_da_z: LR_LCD_ScreenClear(0); LR_LCD_ShowString(string7);break;
     case k6_ca_z: LR_LCD_ScreenClear(0); LR_LCD_ShowString(string6c);break;
     case k6_da_z: LR_LCD_ScreenClear(0); LR_LCD_ShowString(string6);break;
     case k5_ca_z: LR_LCD_ScreenClear(0); LR_LCD_ShowString(string5c);break;
     case k5_da_z: LR_LCD_ScreenClear(0); LR_LCD_ShowString(string5);break;   
   
       default:   key_z=0xff;
  }}}
/******************************************************************************/
发表于 2012-4-11 22:53 | 显示全部楼层
不错哦,
回复

使用道具 举报

本版积分规则

QQ|一淘宝店|手机版|商店|一乐电子 ( 粤ICP备09076165号 ) 公安备案粤公网安备 44522102000183号

GMT+8, 2025-11-4 14:57 , Processed in 0.031704 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表