1、电子密码锁完整代码#include#include #include #include VIIC_C51.h#define uchar unsigned char#define uint unsigned int#define CSI24WC02 0XA0#define uchar unsigned charsbit lcdrs=P20;sbit lcdrw=P21;sbit lcden=P22;sbit alarm=P23;sbit red=P27;sbit green=P26;sbit KEY_INT=P32;/led testsbit LED1=P35;sbit LED2=P31;uch
2、ar hour,min,sec,us;uchar flag=1,canscan=0,lock=0;uchar password8=0,0,0,0,0,0,0,0;uchar input8=0,1,2,3,4,5,6,7;uchar code a=0xF7,0xFB,0xFD,0xFE;unsigned char DelayNS(unsigned char no) unsigned char i,j; for(; no0; no-) for(i=0; i100; i+) for(j=0; j100; j+); return 0; unsigned char delay_eep(unsigned
3、char j) unsigned char k,l; for(l=0;l=j;l+) for(k=0;k0;i-);/lcd 写命令void write_com(uchar com) lcdrs=0; lcdrw=0; P0=com; delay(2); lcden=1; delay(2); lcden=0;/lcd 写数据void write_data(uchar date) lcdrs=1; lcdrw=0; P0=date; delay(2); lcden=1; delay(2); lcden=0;/lcd 的初始化 void init_lcd() write_com(0x38); wr
4、ite_com(0x0c); write_com(0x06); write_com(0x01);/ lcd 清屏void clearscn() write_com(0x06); write_com(0x01);/lcd 显示坐标void gotoxy(uchar x,uchar y) if(x=1) write_com(0x80+y); if(x=2) write_com(0xc0+y);/写lcd字符串void write_str(uchar *str) while(*str!=0) write_data(*str); delay(2); str+; /写一位数字void write_num
5、(uchar num) write_data(0x30+num);/写两位数void write_num2(uchar num) uchar x,y; x=num/10; y=num%10; write_num(x); write_num(y);/ 矩阵键盘扫描函数uchar scan(void) uchar row,col; uchar j,m; P1=0xF0; if(P1&0xF0)!=0xF0) delay(1); if(P1&0xF0)!=0xF0) col=(P1|0x0F); j=0; P1=aj; while(j=3) if(P1&0xF0)!=0xF0) row=aj; br
6、eak; else j+;P1=aj; m=row+col; return(m); else return(0); uchar coding(uchar m) uchar k; switch(m) case(0x08+0x80):k=0;break; case(0x08+0x40):k=1;break; case(0x08+0x20):k=2;break; case(0x08+0x10):k=3;break; case(0x04+0x80):k=4;break; case(0x04+0x40):k=5;break; case(0x04+0x20):k=6;break; case(0x04+0x
7、10):k=7;break; case(0x02+0x80):k=8;break; case(0x02+0x40):k=9;break; case(0x02+0x20):k=10;break; case(0x02+0x10):k=11;break; case(0x01+0x80):k=12;break; case(0x01+0x40):k=13;break; case(0x01+0x20):k=14;break; case(0x01+0x10):k=15;break; return(k);/c重新设置密码void setpassword() uchar tmp,key,i=0; write_c
8、om(0x38); write_com(0x0c); write_com(0x06); write_com(0x01); gotoxy(1,0); write_str( ); gotoxy(1,10); write_str(SET ); while(1) tmp=scan(); if(tmp!=0) key=coding(tmp); if(key=9&i8) if(i=8&(key=11) gotoxy(1,10); write_str(SET OK); gotoxy(1,0); write_str( ); break; delay(250); /蜂鸣器报警void buzzeralarm()
9、 alarm=0; delay(250); alarm=1; delay(250); alarm=0; delay(250); alarm=1; delay(250); alarm=0; delay(250); alarm=1; delay(250);/定时器0中断服务函数/作用 给输入三次错误倒计时用void time0() interrupt 1 TL0=0xb0;TH0=0x3c;if(+us=20) us=0; gotoxy(1,6); write_num2(sec); gotoxy(1,3); write_num2(min); gotoxy(1,0); write_num2(hour
10、);if(+sec=60) sec=0; if(+min=60) min=0; if(+hour=1) hour=0;TR0=0;lock=0; gotoxy(2,10); write_str(UNLOCKED); /主函数 void main(void) uchar tmp,key,i=0,j,scannum=0; uchar td8=0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1; /eeprom send buff uchar rd8=0x00,0x01,0x02,0x03,0x04; /eeprom read buff green=0; red=0; t0_init()
11、; init_lcd(); LED1=0; LED2=0; while(1) tmp=scan(); /读入键值 if(tmp!=0) key=coding(tmp); if(key=9)&(i0)i-; delay(250); if(i=8&key=11)/确认键 i=0; #if 1 IRcvStr(CSI24WC02,0,rd,0x8); /?EEPROM delay_eep(200); for(i=0; i8; i+) /?password passwordi = rdi; i = 0; #endif for(j=0;j=7;j+) if(inputj!=passwordj) flag
12、=1; else flag=0; if(lock=0) if(flag) flag = 0; scannum+; gotoxy(2,10); write_str(ERR! ); write_num(scannum); red=1; buzzeralarm(); if(scannum=3)lock=1;TR0=1; else clearscn(); gotoxy(2,10); write_str(again ); continue; else gotoxy(2,10); write_str(OK! ); green=1; if(lock) gotoxy(2,10); write_str(LOCK
13、ED); gotoxy(1,0); write_str( ); canscan=0; delay(250); if(green=1)&(key=13) LED1=1; green=0; delay(200); LED1=0; if(key=12)&(green=1)/ setpassword(); ISendStr(CSI24WC02,0,password,0x8); / /* VIIC_C51.C 此程序是I2C操作平台(主方式的软件平台)的底层的C子程序,如发送数据及接收数据,应答位发送,并提供了几个直接面对器件的操作函数,它很方便的与用户程序连接并扩展. 注意:函数是采用软件延时的方法产
14、生SCL脉冲,固对高晶振频率要作 一定的修改.(本例是1us机器周期,即晶振频率要小于12MHZ)*/ #include /*头文件的包含*/#include #define uchar unsigned char /*宏定义*/#define uint unsigned int#define _Nop() _nop_() /*定义空指令*/* 常,变量定义区 */ /*端口位定义*/sbit SDA=P37; /*模拟I2C数据传送位*/sbit SCL=P36; /*模拟I2C时钟控制位*/ /*状态标志*/bit ack; /*应答标志位*/ /* 起动总线函数 函数原型: void S
15、tart_I2c(); 功能: 启动I2C总线,即发送I2C起始条件. */void Start_I2c() SDA=1; /*发送起始条件的数据信号*/ _Nop(); SCL=1; _Nop(); /*起始条件建立时间大于4.7us,延时*/ _Nop(); _Nop(); _Nop(); _Nop(); SDA=0; /*发送起始信号*/ _Nop(); /* 起始条件锁定时间大于4s*/ _Nop(); _Nop(); _Nop(); _Nop(); SCL=0; /*钳住I2C总线,准备发送或接收数据 */ _Nop(); _Nop();/* 结束总线函数 函数原型: void St
16、op_I2c(); 功能: 结束I2C总线,即发送I2C结束条件. */void Stop_I2c() SDA=0; /*发送结束条件的数据信号*/ _Nop(); /*发送结束条件的时钟信号*/ SCL=1; /*结束条件建立时间大于4s*/ _Nop(); _Nop(); _Nop(); _Nop(); _Nop(); SDA=1; /*发送I2C总线结束信号*/ _Nop(); _Nop(); _Nop(); _Nop();/* 字节数据传送函数 函数原型: void SendByte(uchar c);功能: 将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对 此状态位进
17、行操作.(不应答或非应答都使ack=0 假) 发送数据正常,ack=1; ack=0表示被控器无应答或损坏。*/void SendByte(uchar c) uchar BitCnt; for(BitCnt=0;BitCnt8;BitCnt+) /*要传送的数据长度为8位*/ if(cBitCnt)&0x80)SDA=1; /*判断发送位*/ else SDA=0; _Nop(); SCL=1; /*置时钟线为高,通知被控器开始接收数据位*/ _Nop(); _Nop(); /*保证时钟高电平周期大于4s*/ _Nop(); _Nop(); _Nop(); SCL=0; _Nop(); _No
18、p(); SDA=1; /*8位发送完后释放数据线,准备接收应答位*/ _Nop(); _Nop(); SCL=1; _Nop(); _Nop(); _Nop(); if(SDA=1)ack=0; else ack=1; /*判断是否接收到应答信号*/ SCL=0; _Nop(); _Nop();/* 字节数据传送函数 函数原型: uchar RcvByte();功能: 用来接收从器件传来的数据,并判断总线错误(不发应答信号), 发完后请用应答函数。 */ uchar RcvByte() uchar retc; uchar BitCnt; retc=0; SDA=1; /*置数据线为输入方式*
19、/ for(BitCnt=0;BitCnt8;BitCnt+) _Nop(); SCL=0; /*置时钟线为低,准备接收数据位*/ _Nop(); _Nop(); /*时钟低电平周期大于4.7s*/ _Nop(); _Nop(); _Nop(); SCL=1; /*置时钟线为高使数据线上数据有效*/ _Nop(); _Nop(); retc=retc1; if(SDA=1)retc=retc+1; /*读数据位,接收的数据位放入retc中 */ _Nop(); _Nop(); SCL=0; _Nop(); _Nop(); return(retc);/* 应答子函数原型: void Ack_I2
20、c(bit a); 功能:主控器进行应答信号,(可以是应答或非应答信号)*/void Ack_I2c(bit a) if(a=0)SDA=0; /*在此发出应答或非应答信号 */ else SDA=1; _Nop(); _Nop(); _Nop(); SCL=1; _Nop(); _Nop(); /*时钟低电平周期大于4s*/ _Nop(); _Nop(); _Nop(); SCL=0; /*清时钟线,钳住I2C总线以便继续接收*/ _Nop(); _Nop(); /* 向无子地址器件发送字节数据函数 函数原型: bit ISendByte(uchar sla,ucahr c); 功能: 从启
21、动总线到发送地址,数据,结束总线的全过程,从器件地址sla. 如果返回1表示操作成功,否则操作有误。注意: 使用前必须已结束总线。*/bit ISendByte(uchar sla,uchar c) Start_I2c(); /*启动总线*/ SendByte(sla); /*发送器件地址*/ if(ack=0)return(0); SendByte(c); /*发送数据*/ if(ack=0)return(0); Stop_I2c(); /*结束总线*/ return(1);/* 向有子地址器件发送多字节数据函数 函数原型: bit ISendStr(uchar sla,uchar suba,ucahr *s,uchar no); 功能: 从启动总线到发送地址,子地址,数据,结束总线的全过程,从器件 地址sla,子地址suba,发送内容是s指向的内容,发送no个字节。 如果返回1表示操作成功,否则操作有误。注意: 使用前必须已结束总线。*/bit ISendStr(uchar sla,uchar suba,uchar *s,uchar no) uchar i; Start_I2c(); /*启动总线*/ SendByte(s
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1