钻石会员
主题
回帖0
积分19891
阅读权限50
注册时间2009-4-2
最后登录1970-1-1
在线时间 小时
|
朋友拿了一个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键电路图
/*********************************************
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;
}}}
/******************************************************************************/ |
|