/**********************************************************************
LCD1602顯示 rs P3^5 rw P3^6 ep P3^7 P0口 為數據輸出口
1838的數據采集口為3.2口 為外部中斷
***********************************************************************/
#include "stc8.h"
#define u8 unsigned char
#define u16 unsigned int
int i;
//void delay(uchar x); //x*0.14MS
sbit IRIN = P3^2; //紅外接收器數據線
u8 IRCOM[7];
sbit rw=P3^6; //1602 IO口定義 這里用的數據口是P0口
sbit rs=P3^5;
sbit ep=P3^7;
unsigned char code d[] = {" IR-CODE: --H "};
unsigned char code cdis1[] = {" 51 hei "};
unsigned char code a[] ={ //漢字
0x04,0x1f,0x15,0x1f,0x15,0x1f,0x05,0x07, //電
0x0f,0x02,0x04,0x1f,0x04,0x04,0x14,0xc, //子
0x04,0x1f,0x15,0x1f,0x15,0x1f,0x05,0x07, //電
0x0f,0x02,0x04,0x1f,0x04,0x04,0x14,0xc }; //子
/**************************** 延時函數 ***********************************/
void delay(unsigned int a)
{
while(a--);
}
void delay1(unsigned char x) //x*0.14MS
{
unsigned char i;
while(x--)
{
for (i = 0; i<13; i++) {}
}
}
/*************************************************************************************/
/*************************************************************************************/
/***************************** 1602 *******************************************/
u8 lcd_busy() //查忙 這部很重要 否則有的顯示容易出現亂碼
{
u8 result;
rs = 0;
rw = 1;
ep = 1;
delay(50);
result = P0&0x80;
ep = 0;
return result; //返回值
}
void lcd_com(unsigned char com)// 地址
{
while(lcd_busy());
rs=0;
ep=0;
rw=0;
P0=com;
delay(50);
ep=1;
delay(50);
ep=0;
}
void lcd_date(unsigned char date)//采集輸出數據
{
while(lcd_busy());
rs=1; //1是些數據 0是寫指令
rw=0; // 1是讀 0是寫
ep=0; //E端為使能端,當E端由高電平跳變成低電平時,液晶模塊執行命令
P0=date;
delay(5);
ep=1;
delay(5);
ep=0;
}
void lcd_pos(unsigned char pos)
{
lcd_com(pos|0x80); //數據指針=80+地址變量
}
void writetab() // 寫 漢字函數
{
unsigned char m;
lcd_com(0x40); //寫CGRAM 此處是指令
for (m = 0; m< 32; m++)
lcd_date(a[m]);
}
void init()//1602初始化
{
lcd_com(0x38);
delay(50);
lcd_com(0x38);
delay(50);
lcd_com(0x38);
delay(50);
lcd_com(0x0c);
delay(50);
lcd_com(0x06);
delay(50);
lcd_com(0x01);
delay(1000);
writetab() ; // 漢字初始化
}
/*******************************************************************************/
/*******************************************************************************/
/*******************************************************************************/
void hanzi() //漢字顯示
{
lcd_pos(0x00);
lcd_date(0x00);
lcd_pos(0x01);
lcd_date(0x01);
}
/************************************************************************/
void IR_IN() interrupt 0
{
unsigned char j,k,N=0;
EX0 = 0;
// delay1(15);
delay1(120);
if (IRIN==1)
{ EX0 =1;
return;
}
//確認IR信號出現
while (!IRIN) //等IR變為高電平,跳過9ms的前導低電平信號。
{delay1(8);}
for (j=0;j<4;j++) //收集四組數據
{
for (k=0;k<8;k++) //每組數據有8位
{
while (IRIN) //等 IR 變為低電平,跳過4.5ms的前導高電平信號。
{delay1(8);}
while (!IRIN) //等 IR 變為高電平
{delay1(8);}
while (IRIN) //計算IR高電平時長
{
delay1(8);
N++;
if (N>=30)
{ EX0=1;
return;} //0.14ms計數過長自動離開。
} //高電平計數完畢
IRCOM[j]=IRCOM[j] >> 1; //數據最高位補“0”
if (N>=8)
{IRCOM[j] = IRCOM[j] | 0x80;} //數據最高位補“1”
N=0;
}
}
if (IRCOM[2]!=~IRCOM[3])
{ EX0=1;
return; }
IRCOM[5]=IRCOM[2] & 0x0F; //取鍵碼的低四位
IRCOM[6]=IRCOM[2] >> 4; //右移4次,高四位變為低四位
if(IRCOM[5]>9)
{ IRCOM[5]=IRCOM[5]+0x37;}
else
IRCOM[5]=IRCOM[5]+0x30;
if(IRCOM[6]>9)
{ IRCOM[6]=IRCOM[6]+0x37;}
else
IRCOM[6]=IRCOM[6]+0x30;
lcd_pos(0x4b);
lcd_date(IRCOM[6]); //第一位數顯示
lcd_pos(0x4c);
lcd_date(IRCOM[5]);
EX0 = 1;
}
/**********************************************************/
void main(void)
{
IE = 0x81; //允許總中斷中斷,使能 INT0 外部中斷
TCON = 0x01; //觸發方式為脈沖負邊沿觸發
IRIN=1; //I/O口初始化
init(); //1602初始化
hanzi() ; //顯示漢字
delay(100);
lcd_pos(0x00);
i=0;
while(cdis1[i]!='\0') //顯示字母
{
lcd_date(cdis1[i]);
i++;
}
delay(100);
lcd_pos(0x40);
i=0;
while(d[i]!='\0') //顯示字母
{
lcd_date(d[i]);
i++;
}
while(1);
}
void test1()
{ unsigned char a,b,c;
if(a>b)
{
c=0;
}
else
{
c=1;
}
}
void test2()
{
while(i<10)
{
i=i+1;
}
}
|