液晶显示1602与遥控程序演示!
//遥控带液晶显示程序,已经调试完毕2002/10/30
//并可显示时钟
//若遥控接收不到,修改脉宽值即可
//
//-----------------------------------------------
//http://www.mcu123.com
//Email:ycxms88@163.com
//作者:Mingtree
//变量类型标识的宏定义,
#define uchar unsigned char
#define uint unsigned int
#define DEDA 20
unsigned char deda=0;
// 1602 控制引脚定义,
sbit RS = P0^0;
sbit RW = P0^1;
sbit Elcm =P0^2;
#define DATAPORT P1 // 数据端口
#define busy 0x80 //用于检查写忙信号
//外键控制(本程序未用,现在用遥控控制)
sbit act=P2^1; /*加键*/
sbit deb=P2^0; /*减键*/
sbit cong=P2^2; /*功能键*/
char data LED6[8];/*六位显示缓冲区*/
code char love[]="I LOVE YOU ";
code char time[]="0123456789ABCDEF:MinHour ";
unsigned char hour=0,min=0,sec=0;
bit menu=0;
bit up=0;
bit dw=0;
#define temp1 DBYTE[0x50]
#define temp2 DBYTE[0x51]
#define teMP3 DBYTE[0x52]
#define temp4 DBYTE[0x53]
#define temp5 DBYTE[0x54]
//遥控
unsigned char yt; //中断次数
bit start=0; //起码标志
bit h=0; //解码标志
unsigned char da=0; //暂存数据
unsigned char gt=0,gv=0; //
//
void delay400ms(void);
void delay5ms(void);
void lcdreset( void ); //LCD RESET
void WaitForEnable( void ); //忙信号检测
void lcdwrite_c( uchar CMD,uchar AttribC );//
void DispOneChar(uchar x,uchar y,uchar Wdata);//显示一个字符
void LOCateXY( char posx,char posy);
void LcdWrite_D( char dataW ) ; //写一个数据
void yk(void);
/*键盘检测*/
void acct_1(void);
unsigned char conh=0; /*功能键键值*/
void key_hit(unsigned char add3);
void delay(void);
/*定时初始化------------*/
void init_timer()
{
TMOD=0x11;
TH0=0x4c;
TL0=0x00;
IP=0x10;
IE=0X82;
TR0=1;
IT0=1; //边沿触发方式
EX0=1; //INT0
}
/*------------------------*/
/*----------显示缓冲区放数子程序--------------*/
void gift_in(void){
if(conh==0){
led6[0]=hour/10;
led6=hour%10;
led6=16;
led6=min/10;
led6[4]=min%10;
led6[5]=16;
led6[6]=sec/10;
led6[7]=sec%10;
}
else if(conh==1){
led6[0]=17;
led6=18;
led6=19;
led6=16;
led6[4]=min/10;
led6[5]=min%10;
led6[6]=24;
led6[7]=24;
}
else{
led6[0]=20;
led6=21;
led6=22;
led6=23;
led6[4]=16;
led6[5]=hour/10;
led6[6]=hour%10;
led6[7]=24;
}
}
/*----------时间判断子程序--------------*/
conv()
{
if(sec==60){min++;sec=0;}
if(min==60){hour++;min=0;}
if(hour==24) hour=0;
gift_in();
}
/*-----------中断服务程序-------------*/
void time8()interrupt 1 using 3
{
TH0=0x4c;
TL0=0x00;
deda++;
if(deda==DEDA)
{
sec++;deda=0;
}
conv();
}
/*-----------送显子程序-------------*/
void disp1(uchar x,uchar y) {
unsigned char *pd;
unsigned char*kt;
unsigned char b;
kt=&led6[0]; /*送led的首地址给指针KT*/
for(b=0;b<8;b++){ /* 显示六位*/
pd=&time[*kt]; /*查表---送要显示的码给指针pd*/
kt++; /*缓冲区加1*/
DispOneChar(x,y,*pd);
x++; //显示位置X
}
}
/*------------------------*/
/*=======================================================
显示字符串
=======================================================*/
void disp(uchar x,uchar y,char *ptr) {
uchar i,l=0;
while (ptr[l] >31){l++;};
for (i=0;i<l;i++) {
DispOneChar(x++,y,ptr[i]);
if ( x == 16 ){
x = 0; y ^= 1;
}
}
}
/*=======================================================
按指定位置显示数出一个字符
=======================================================*/
void DispOneChar(uchar x,uchar y,uchar Wdata) {
LocateXY( x, y ); // 定位显示地址
LcdWrite_D( Wdata ); // 写字符
}
/*=======================================================
显示光标定位
=======================================================*/
void LocateXY( char posx,char posy) {
uchar temp;
temp = posx & 0xf;
posy &= 0x1;
if ( posy )temp |= 0x40;
temp |= 0x80;
lcdwrite_c(temp,0);
}
//初始化
void lcdreset(void){
lcdwrite_c(0x38, 0); //显示模式设置(不测试忙信号)共三次
delay5ms();
lcdwrite_c(0x38, 0);
delay5ms();
lcdwrite_c(0x38, 0);
delay5ms();
lcdwrite_c( 0x38, 1);
lcdwrite_c( 0x08, 1);
lcdwrite_c( 0x01, 1);
lcdwrite_c( 0x06, 1);
lcdwrite_c( 0x0c, 1);
}
/*=======================================================
写控制字符子程序: E=1 RS=0 RW=0
=======================================================*/
void lcdwrite_c( uchar CMD,uchar AttribC ) {
if (AttribC) WaitForEnable(); // 检测忙信号?
RS = 0; RW = 0; _nop_();
DATAPORT =CMD; _nop_(); // 送控制字子程序
Elcm = 1;_nop_();_nop_();Elcm = 0; // 操作允许脉冲信号
}
/*=======================================================*/
/*=======================================================
当前位置写字符子程序: E =1 RS=1 RW=0
=======================================================*/
void LcdWrite_D( char dataW ) {
WaitForEnable(); // 检测忙信号
RS = 1; RW = 0; _nop_();
DATAPORT = dataW; _nop_();
Elcm = 1; _nop_(); _nop_(); Elcm = 0; // 操作允许脉冲信号
}
/*=======================================================
正常读写操作之前必须检测LCD控制器状态: CS=1 RS=0 RW=1
DB7: 0 LCD控制器空闲; 1 LCD控制器忙
========================================================*/
void WaitForEnable( void ) {
DATAPORT = 0xff;
RS =0; RW = 1; _nop_(); Elcm = 1; _nop_(); _nop_();
while( DATAPORT & busy );
Elcm = 0;
}
// 短延时
void delay5ms(void)
{
uint i = 5552;
while(i--);
}
//长延时
void delay400ms(void)
{
uchar i = 5;
uint j;
while(i--)
{
j=7269;
while(j--);
};
}
/*-------延时---------------*/
void delay(void){
int r;
int e;
for(r=0;r<500;r++){ /*外层循环*/
_nop_ (); /* delay for hardware */
_nop_ (); /* delay for hardware */
_nop_ (); /* delay for hardware */
for(e=0;e<3;e++){ /*内层循环*/
_nop_ (); /* delay for hardware */
_nop_ (); /* delay for hardware */
_nop_ (); /* delay for hardware */
_nop_ (); /* delay for hardware */
_nop_ (); /* delay for hardware */
}
}
}
/*----------功能键识别子程序--------------*/
void acct_1(void){
tf: _nop_();
if(menu){
menu=0;
conh++;
if(conh==3) conh=0;
}
if(conh==1){key_hit(min); //低位设置
conv();
disp1(3,0);
delay();
}
if(conh==2){key_hit(hour); //高位设置
conv();
disp1(3,0);
delay();
}
/* if(conh==3){key_hit(thtl) //显示高位,低位
conv();
delay();
delay();
delay();
delay();
delay();
}
if(conh==4){key_hit(save);
conv();
disp();
delay();
}*/
yk();
if(!conh==0) goto tf; /*功能设置完毕?未设置则继续执行功能键处理*/
}
/*-----------加减键处理子程序-------------*/
/*按键处理*/
void key_hit(unsigned char add3)
{
if(dw){
dw=0; /*减键*/
add3--;
if(add3>=60) add3=0;
if(conh==1) min=add3;
if(conh==2) hour=add3;
conv();
disp1(3,0);
}
if(up){ /*加键*/
up=0; /*减键*/
add3++;
if(add3==60) add3=0;
if(conh==1) min=add3;
if(conh==2) hour=add3;
conv();
disp1(3,0);
}
if(conh==1) min=add3;
if(conh==2) hour=add3;
}
//遥控码识别
void yk(void){
if(temp2==0xe2){
if(temp4==0xf1){
if(temp3==0x2c){
if(temp5==0x16){ //功能键
menu=1;
temp3=0;
temp5=0;
}
}
if(temp3==0x44){
if(temp5==0x22){ //加键
up=1;
temp3=0;
temp5=0;
}
}
if(temp3==0x54){
if(temp5==0x2a){ //减键
dw=1;
temp3=0;
temp5=0;
}
}
}
}
}
//遥控中断除理
void int0a()interrupt 0 using 2
{
// TH1=TL1=0;
//TR0=1; //启动定时器
yt++; //中断次数
if(yt==1)
{
TH1=TL1=0;
TR1=1; //启动定时器
}
if(yt==2)
{
temp1=TH1; //为起始
TH1=TL1=0;
if(temp1>=0x1f)
{ //大于8ms
start=1; //置起码标志
}
else
{
start=0;
yt=0;
TR1=0;
}
}
else
{
if(start==1)
{ //是起始才可以继续接收
temp1=TH1; //装入上次定时值
TH1=TL1=0; //重新计数
if(temp1>=0x05)
{ //大于1.2ms
h=1;
}
else if(temp1>=0x01)
{ //大于0.25ms
h=0;
}
da*=2;
if(h) da++;
gt++;
if(gt==8)
{ //读8位
gt=0;gv++;
if(gv==1) temp2=da;
if(gv==2) temp3=da;
if(gv==3) temp4=da;
if(gv==4)
{temp5=da;
gv=0;
start=0;
yt=0;
TR1=0;
}
da=0;
}
}
}
}
/*------------------------*/
void main(void)
{
init_timer();
led6[0]=0;
led6=2;
led6=2;
led6=2;
led6[4]=2;
led6[5]=2;
lcdreset(); //初始化
delay400ms();
disp1(3,0);
disp(2,1,love); //显示
delay400ms();
// DispOneChar(0,1,time);
while(1)
{
delay400ms();
disp1(3,0);
acct_1();
yk();
}
}
各位见笑了.