#include // 修改该文件以适应硬件环境/单片机型号等 // CH452常量定义 #include #define uchar unsigned char #define ushort unsigned short #define CH452_I2C_ADDR0 0x40 // CH452的ADDR=0时的地址 #define CH452_I2C_ADDR1 0x60 // CH452的ADDR=1时的地址,默认值 #define CH452_I2C_MASK 0x3E // CH452的2线接口高字节命令掩码 uchar KeyValue; sbit CH452_SDA=P1^7; sbit CH452_SCL=P1^6; sbit CH452_INT=P3^2; const uchar KeyCode[16]={0x40,0x41,0x42,0x43,//0,1,2,3 0x48,0x49,0x4A,0x4B,//4,5,6,7 0x50,0x51,0x52,0x53,//8,9,A,B 0x58,0x59,0x5A,0x5B};//C,D,E,F void CH452_I2c_Start() // 操作起始,两线制方式,SDA用做中断输出,使用以下两个函数 {
// EX0=0; //禁止键盘中断,防止开始时被CH452中断而进入中断服务程序中的START CH452_SDA=1; /*发送起始条件的数据信号*/ CH452_SCL=1; _nop_(); CH452_SDA=0; /*发送起始信号*/ _nop_(); CH452_SCL=0; /*钳住I2C总线,准备发送或接收数据 */ _nop_(); }
void CH452_I2c_Stop() // 操作结束 { CH452_SDA=0; _nop_(); CH452_SCL=1; _nop_(); CH452_SDA=1; /*发送I2C总线结束信号*/ _nop_(); _nop_(); IE0=0; // 清除中断标志,因为通过SDA输出数据所以会误中断 EX0=0; }
void CH452_I2c_WrByte(uchar dat) //写一个字节数据 { unsigned char i; for(i=0;i!=8;i++) // 输出8位数据 { if(dat&0x80) {CH452_SDA=1;} else {CH452_SDA=0;} _nop_(); CH452_SCL=1; dat<<=1; _nop_(); _nop_(); CH452_SCL=0; _nop_(); } CH452_SDA=1; _nop_(); CH452_SCL=1; // 接收应答 _nop_(); _nop_(); CH452_SCL=0; _nop_(); }
unsigned char CH452_I2c_RdByte() //读一个字节数据 { unsigned char dat,i; CH452_SDA=1; dat=0; for(i=0;i!=8;i++) // 输入8位数据 { CH452_SCL=1; _nop_(); _nop_(); dat<<=1; if(CH452_SDA) dat++; // 输入1位 CH452_SCL=0; _nop_(); } CH452_SDA=1; _nop_(); CH452_SCL=1; // 发出无效应答 _nop_(); _nop_(); CH452_SCL=0; _nop_(); return(dat);
} //CH452写命令函数 void CH452_WriteCommand(unsigned int Command) { CH452_I2c_Start(); CH452_I2c_WrByte(((Command>>7)&0x3E)|0x40); CH452_I2c_WrByte(Command); CH452_I2c_Stop(); }
unsigned char CH452_Read() //读取按键 { ushort cmd; uchar keycode; CH452_I2c_Start(); /*启动总线*/ CH452_I2c_WrByte((uchar)(cmd>>7)&CH452_I2C_MASK|0x01|CH452_I2C_ADDR1); keycode=CH452_I2c_RdByte(); /*读取数据*/ CH452_I2c_Stop(); /*结束总线*/ return(keycode); }
void CH452_Init() { uchar KeyValue; IT0=0; //设置下降沿触发 EX0=1; //开中断 EA=1; //总中断 KeyValue=0xFF; //键值初值 CH452_WriteCommand(0x0700); //2线接口ACK CH452_WriteCommand(0x0403);//开显示、键盘 }
void CH452_GetKeyValue()interrupt 0 { uchar i; uchar GetKeyValue=0x00; //键盘代码 CH452_I2c_Start(); CH452_I2c_WrByte(((0x0700>>7)&0x3E)|0x41); GetKeyValue=CH452_Read(); CH452_I2c_Stop(); if(GetKeyValue==0x00) return; //读出键码为0跳过 for(i=0;i<16;i++) { //查找键盘代码对应的键值 if(GetKeyValue==KeyCode[i]) { KeyValue=i; break; } } } void main { CH452_Init(); lcd_init(); if(KeyValue==0x40) { write_lcd(0,0,"0"); }