本帖最后由 蚁族 于 2013-8-16 20:34 编辑
#include "REG52.H" #include "stdio.h" #include "intrins.h"
#define uchar unsigned char #define uint unsigned int
***it LCD_RS=P2^4; ***it LCD_RW=P2^5; ***it LCD_EN=P2^6; ***it LCD_BG=P2^3; //当LCD_BG=0时LCD1602屏幕不亮,当LCD_BG=1时LCD1602屏幕亮 uchar code table[]="0123456789 ";
void LCD_init(); void display_xy(uchar x,uchar y); void display_int(uchar x,uchar y,int num);
***it key_clk=P3^4; ***it key_dat=P3^5; ***it key_row1=P3^6; ***it key_row2=P3^7;
uchar row,key=0; uchar buffer;
void key_sendbyte(uchar byte); uchar key_value(); void key_scan();
void Delayms(uint z) { uint i,j; for(i=z;i>0;i--) for(j=135;j>0;j--); } /*****LCD1602初始化********/ void Busy() { uchar temp=0x80; //初始化temp最高位为1,使得能够进入下面的while循环 P0=0xff; //(P0就是8个数据口) LCD_RS=0; //设置命令操作 LCD_RW=1; //设置读操作 LCD_EN=1; //使能 Delayms(5); //(这是设的延时函数,不用解释) while(temp & 0x80) //判忙,一旦表达式为假,即temp最高位为0,则表示1602不忙,跳出while. { temp=P0; Delayms(10); //把p0的的高位读入temp,延时 } LCD_EN=0; //关闭使能信号 } /*写指令数据到LCD */ void LCD_wcmd(uchar cmd) { Busy(); //忙闲信号的判断 LCD_RS = 0; LCD_RW = 0; LCD_EN = 0; P0 = cmd; Delayms(5); LCD_EN = 1; Delayms(5); LCD_EN = 0; }
/*写显示数据到LCD */ void LCD_wdat(uchar dat) { Busy(); LCD_RS = 1; LCD_RW = 0; LCD_EN = 0; P0 = dat; Delayms(5); LCD_EN = 1; Delayms(10); LCD_EN = 0; }
/*LCD初始化*/ void LCD_init() { LCD_wcmd(0x38); //16*2显示,5*7点阵,8位数据 Delayms(5); LCD_wcmd(0x38); //16*2显示,5*7点阵,8位数据 Delayms(5); LCD_wcmd(0x38); Delayms(5); //三次初始化,确保完成 LCD_wcmd(0x0c); //显示开,关光标 Delayms(5); LCD_wcmd(0x06); //移动光标 Delayms(5); LCD_wcmd(0x01); //清除LCD的显示内容 Delayms(5); }
/*设置光标位置, x是列号,y是行号*/ void display_xy(uchar x,uchar y) { // LCD_wcmd(0x01); //清楚光屏 if(y==1) x+=0xc0; //0xc0第二行首地址 else x+=0x80; //0x80第一行首地址 LCD_wcmd(x); } /*在具体位置显示一个整数*/ void display_int(uchar x,uchar y,long num) { uint a,b,c,d,e; a=num/10000; // 万位 b=num%10000/1000; // 千位 c=num%10000%1000/100; // 百位 d=num%10000%1000%100/10; // 十位 e=num%10; // 个位 display_xy(x,y); if(num<0) { LCD_wdat(0xb0); a=-a; b=-b; c=-c; d=-d; e=-e; } if(a!=0) LCD_wdat(table[a]); if(a!=0|b!=0) LCD_wdat(table); if(a!=0|b!=0|c!=0) LCD_wdat(table[c]); if(a!=0|b!=0|c!=0|d!=0) LCD_wdat(table[d]); LCD_wdat(table[e]); }
//2*8键盘
void key_sendbyte(uchar byte) //串行输出子程序 { uint i; //局部变量i for(i=0;i<8;i++) //循环8次 { key_clk=0; //将时钟信号设为低电平 key_dat=byte&0x80; //(0x80即十进制的128, 二进制的10000000 按位发送) key_clk=1; //再将时钟信号设置为高电平,将输出一个时钟信号的上升沿 byte<<= 1; //byte变量左移一位 } } uchar key_value() { uchar key_bit,i; buffer=0xff; key_sendbyte(0x00); if(!(key_row1&key_row2)) { Delayms(10); //消除按键抖动 if(!(key_row1&key_row2)) //有键按下 { if(!key_row1) //第一行有键按下 { row=0; key_bit=0xfe; for(i=0;i<8;i++) { key_sendbyte(key_bit); //查看是否是这个数值的键按下 if(!key_row1) { buffer=key_bit; //如果是,把键值存入buffer break; } key_bit = _crol_(key_bit,1); //如果不是,进行是否是下一个键按下的断定 } return buffer; //返回键值 }
if(!key_row2) //第二行有键按下 { row=1; key_bit=0xfe; for(i=0;i<8;i++) { key_sendbyte(key_bit); //查看是否是这个数值的键按下 if(!key_row2) { buffer=key_bit; //如果是,把键值存入buffer break; } key_bit = _crol_(key_bit,1); //如果不是,进行是否是下一个键按下的断定 } return buffer; //返回键值 } } } } void key_scan() { uchar temp=0; temp=key_value(); if(row==0) { switch(temp) { case 0xfe:key=1;break; case 0xfd:key=2;break; case 0xfb:key=3;break; case 0xf7:key=4;break; case 0xef:key=5;break; case 0xdf:key=6;break; case 0xbf:key=7;break; case 0x7f:key=8;break; default:break; } } else { switch(temp) { case 0xfe:key=9;break; case 0xfd:key=10;break; case 0xfb:key=11;break; case 0xf7:key=12;break; case 0xef:key=13;break; case 0xdf:key=14;break; case 0xbf:key=15;break; case 0x7f:key=16;break; default:break; } } }
void main () { LCD_init(); // 初始化LCD LCD_BG=1; while(1) { key_scan(); display_int(0,0,key); display_int(0,1,buffer); } } 程序扫描不大键盘,不知为什么?
|