?? 8574keyboard.c.bak
字號:
//#include <reg52.h>
#include <ADI/ADuC834.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
//1602移植過來的
sbit rs=P2^3; //1602的數據/指令選擇控制線
sbit rw=P2^4; //1602的讀寫控制線
sbit en=P2^5; //1602的使能控制線
/*P2口接1602的D0~D7,注意不要接錯了順序,我以前可在這上面吃過虧~*/
uchar code table[]="LCD1602 check ok"; //要顯示的內容1放入數組tablel
uchar code table1[]="study up"; //要顯示的內容2放入數組table1
uchar code esc[]="ESC";
uchar code light[]="LIGHT";
uchar code avc[]="AVC";
uchar code memo[]="MEMO";
uchar code hold[]="HOLD";
uchar code setup[]="SETUP";
uchar code pgdn[]="PgDn";
uchar n,m=0;
uchar slvadr=0x40 ; //被控器地址
uchar ack;
uchar key;
uchar curkey;
uchar key_right_flag=1;
uchar KeyPort;
uchar RBT[8];
//1602移植過來的
void delay(uint n) //延時函數
{
uint x,y;
for(x=n;x>0;x--)
for(y=110;y>0;y--);
}
void lcd_wcom(uchar com) //1602寫命令函數
{
rs=0; //選擇指令寄存器
rw=0; //選擇寫
P0=com; //把命令字送入P2
delay(5); //延時一小會兒,讓1602準備接收數據
en=1; //使能線電平變化,命令送入1602的8位數據口
en=0;
}
void lcd_wdat(uchar dat) //1602寫數據函數
{
rs=1; //選擇數據寄存器
rw=0; //選擇寫
P0=dat; //把要顯示的數據送入P2
delay(5); //延時一小會兒,讓1602準備接收數據
en=1; //使能線電平變化,數據送入1602的8位數據口
en=0;
}
void lcd_init() //1602初始化函數
{
lcd_wcom(0x38); //8位數據,雙列,5*7字形
lcd_wcom(0x0F); //開啟顯示屏,關光標,光標不閃爍
lcd_wcom(0x06); //顯示地址遞增,即寫一個數據后,顯示位置右移一位
lcd_wcom(0x01); //清屏
}
void PCF8574init(void)
{
I2CM=1;
}
void delay1ms(uchar x)
{
unsigned char i,j;
while(x--)
{
for(i=5;i>0;i--)
for(j=132;j>0;j--);
}
}
void Delay_Cycles(char delay)
{
while(delay--);
}
/*---------------------------------------------------------------------------------------------------
開始:START
描述:啟動I2C 總線子程序--發送I2C 起始條件
---------------------------------------------------------------------------------------------------*/
void start(void)
{
MDE=1;
MCO=1;
MDO=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
MDO=0;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
MCO=0;
}
void Ack_I2c(uchar a) //a=0發送應答信號,=1發送非應答信號
{
MDE=1;
if(a==0)MDO=0; /*在此發出應答或非應答信號 */
else MDO=1;
_nop_();
_nop_();
_nop_();
MCO=1;
_nop_();
_nop_(); /*時鐘低電平周期大于4μs*/
_nop_();
_nop_();
_nop_();
MCO=0; /*清時鐘線,鉗住I2C總線以便繼續接收*/
_nop_();
_nop_();
}
void wrbyt(uchar shu)
{
uchar i;
ack=0;
MDE=1; // SETB MDE ; to enable SDATA pin as an output
MCO=0;
for(i=0;i<8;i++)
{
if(shu&0x80)
{
MDO=1;
_nop_();
MCO=1;
_nop_();
_nop_();
_nop_();
MCO=0;
//MDO=0;
}
else
{
MDO=0;
_nop_();
MCO=1;
_nop_();
_nop_();
_nop_();
MCO=0;
}
shu=shu<<1;
}
MDO=1;
MDE=0; // CLR MDE ; release data line for acknowledge
MCO=1; // SETB MCO ; send clock for acknowledge
Delay_Cycles(3);
MCO=0;
}
//void SendByte_Upon_I2C(unsigned char byte)
//{
// unsigned char send_bitdata;
// unsigned char send_bytedata=byte;
// uchar BITCNT=8; // MOV BITCNT,#8 ; 8 bits in a byte
// MDE=1; // SETB MDE ; to enable SDATA pin as an output
// MCO=0; // CLR MCO ; make sure that the clock line is low
// Delay_Cycles(5);
// while(BITCNT--)
// {
// if(send_bytedata&0x80)send_bitdata=1;
// else send_bitdata=0;
// MDO=send_bitdata; // MOV MDO,C ; put data bit on SDATA line
// MCO=1; // SETB MCO ; clock to send bit
// Delay_Cycles(1);
// Delay_Cycles(5);
// MCO=0; // CLR MCO ; clear clock
// send_bytedata<<=1;
// } // DJNZ BITCNT,SENDBIT ; jump back and send all eight bits
// MDE=0; // CLR MDE ; release data line for acknowledge
// MCO=1; // SETB MCO ; send clock for acknowledge
// Delay_Cycles(3);
// MCO=0; //NEXT: CLR MCO ; clear clock
// return; // RET
//}
uchar RcvByte()
{
uchar retc;
uchar BitCnt;
retc=0;
MDE=0; /*置數據線為輸入方式*/
for(BitCnt=0;BitCnt<8;BitCnt++)
{
_nop_();
MCO=0; /*置時鐘線為低,準備接收數據位*/
_nop_();
_nop_(); /*時鐘低電平周期大于4.7μs*/
_nop_();
_nop_();
_nop_();
MCO=1; /*置時鐘線為高使數據線上數據有效*/
_nop_();
_nop_();
retc=retc<<1;
if(MDI==1)retc=retc+1; /*讀數據位,接收的數據位放入retc中 */
_nop_();
_nop_();
}
MCO=0;
_nop_();
_nop_();
return(retc);
}
/*---------------------------------------------------------------------------------------------------
名稱:STOP
描述:停止I2C 總線子程序--發送I2C 總線停止條件
---------------------------------------------------------------------------------------------------*/
void stop(void)
{
MDE=1;
MDO=0;
_nop_();
MCO=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
MDO=1;
_nop_();
_nop_();
_nop_();
}
void checkack(void)
{
// MDO=1; /*8位發送完后釋放數據線,準備接收應答位*/
// MDE=0;
// _nop_();
// _nop_();
// MCO=1;
// _nop_();
// _nop_();
// _nop_();
if(MDI==0)
ack=1;
else
ack=0; /*判斷是否接收到應答信號*/
MCO=0;
MDE=1;
_nop_();
_nop_();
}
/*************************************************************************************
主程序
**************************************************************************************/
void ext0_int() interrupt 0//SPIandI2C_InterruptRoutine(void) interrupt 7//
{
// if(key_right_flag<2)
// {
EX0=0;
start();
wrbyt(0x41);
RBT[1]=RcvByte();
Ack_I2c(1);
stop();
if(RBT[1]>=0x70)//如果接收的數正確
key_right_flag++;
KeyPort = (RBT[1] & 0xF0);
//KeyPort=(0x70&0xF0);
start();
wrbyt(0x40);
wrbyt(0x0F);
checkack();
stop();
start();
wrbyt(0x41);
RBT[2]=RcvByte();
Ack_I2c(1);
stop();
if(RBT[2]<=0x0F)//判斷是否正確
key_right_flag++;
key = (RBT[2] & 0x0F);
key|=KeyPort;
if(key!=0xFF)
curkey=key;
// }
// if(key_right_flag>=2)
// {
key_right_flag=0;
start();//恢復8574初始狀態
wrbyt(0x40);
wrbyt(0xF0);
checkack();
stop();
EX0=1;
// }
}
/*************************************************************************************
主程序
**************************************************************************************/
void main()
{
EX0=1;
PCF8574init();//主機模式
start();
wrbyt(slvadr);//發一個數據或地址
wrbyt(0xF0);//端口初始化
checkack();
stop();
delay1ms(1);
delay1ms(1);
delay1ms(1);
start();
wrbyt(0x41);
RBT[0]=RcvByte();
Ack_I2c(1);
stop();
EA=1;
//1602移植過來的
lcd_init(); //液晶初始化
lcd_wcom(0x80); //顯示地址設為80H(即00H,)上排第一位
for(m=0;m<16;m++) //將table[]中的數據依次寫入1602顯示
{
lcd_wdat(table[m]);
delay(1);
}
lcd_wcom(0x80+0x44); //重新設定顯示地址為0xc4,即下排第5位
for(n=0;n<8;n++) //將table1[]中的數據依次寫入1602顯示
{
lcd_wdat(table1[n]);
delay(1);
}
while(1)
{
uchar i;
switch (curkey)
{/*將按鍵碼輸出到顯示*/
case 0x7E:
lcd_wcom(0x80);
//lcd_wdat('L');
for(i=0;i<5;i++)
{
lcd_wdat(light[i]);
}
curkey=0;
break;
case 0xBE:
lcd_wcom(0x80);
//lcd_wdat('A');
for(i=0;i<3;i++)
{
lcd_wdat(avc[i]);
}
curkey=0;
break;
case 0xDE:
lcd_wcom(0x80);
lcd_wdat('M');
for(i=0;i<4;i++)
{
lcd_wdat(memo[i]);
}
curkey=0;
break;
case 0xEE:
lcd_wcom(0x80);
lcd_wdat('H');
for(i=0;i<4;i++)
{
lcd_wdat(hold[i]);
}
curkey=0;
break;
case 0xED:
lcd_wcom(0x80);
lcd_wdat('S');
for(i=0;i<5;i++)
{
lcd_wdat(setup[i]);
}
curkey=0;
break;
case 0xDD:
lcd_wcom(0x80);
lcd_wdat('9');
curkey=0;
break;
case 0xBD:
lcd_wcom(0x80);
lcd_wdat('8');
curkey=0;
break;
case 0x7D:
lcd_wcom(0x80);
lcd_wdat('7');
curkey=0;
break;
case 0xEB:
lcd_wcom(0x80);
lcd_wdat('P');
for(i=0;i<4;i++)
{
lcd_wdat(pgdn[i]);
}
curkey=0;
break;
case 0xDB:
lcd_wcom(0x80);
lcd_wdat('6');
curkey=0;
break;
case 0xBB:
lcd_wcom(0x80);
lcd_wdat('5');
curkey=0;
break;
case 0x7B:
lcd_wcom(0x80);
lcd_wdat('4');
curkey=0;
break;
case 0xE7:
lcd_wcom(0x80);
for(i=0;i<3;i++)
{
lcd_wdat(esc[i]);
}
//lcd_wdat('E');
curkey=0;
break;
case 0xD7:
lcd_wcom(0x80);
lcd_wdat('3');
curkey=0;
break;
case 0xB7:
lcd_wcom(0x80);
lcd_wdat('2');
curkey=0;
break;
case 0x77:
lcd_wcom(0x80);
lcd_wdat('1');
curkey=0;
break;
case 0x7F:
lcd_wcom(0x80);
lcd_wdat('0');
curkey=0;
break;
case 0xBF:
lcd_wcom(0x80);
lcd_wdat('.');
curkey=0;
break;
case 0xDF:
lcd_wcom(0x80);
lcd_wdat('+');
curkey=0;
break;
case 0xEF:
//lcd_wcom(0x80);
lcd_wdat('*');
lcd_wcom(0x80+0x44);
curkey=0;
break;
default :
break;
}
delay1ms(1);
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -