单片机密码锁C程序完整代码

合集下载

指纹密码锁主程序

指纹密码锁主程序

#include 〈reg52.h〉#include <intrins。

h>#include"24C0x。

h”#include”LCD12864。

h"#define uchar unsigned char#define uint unsigned int#define buffer1ID 0x01#define buffer2ID 0x02#define queren 0x88#define tuichu 0x84#define shanchu 0x82#define User 2void fan();sbit B0=B^0;sbit B7=B^7;sbit k2=P3^7;sbit jidianqi=P3^6;//sbit Buzzer=P0^0;extern unsigned char times[];uchar Member,sec,z=0; // =1uchar code buffer[User][6]={{”000000”}};uchar dz[4];uchar time[4];uchar mima[6];uchar mimag[6];//uchar mimaID[6]={1,2,3,4,5,6}; uchar mimaID[6];uchar data K;uchar data Key;uint PageID;uchar data querenma=11;uchar sum[2];int summaf,summas;uchar xdata UserPassword[6]={0};//密码uchar xdata DSY_BUFFER[16]={0};//缓存void Red_Init(void);//检测脉冲宽度unsigned char check(void);unsigned char redchange(unsigned char rednum);void delayms(unsigned int z){unsigned int x,y;for(x=z;x〉0;x-—)for(y=110;y>0;y-—);}/********************************************************************* 名称:Chack(uchar User_Number)*功能:单一用户密码检测* 输入:User_Number* 输出:密码正确与错误,错误返回0,正确返回1********************************************************************/uchar Chack(uchar User_Number){uchar flag, i,temp[6],Address;Address=User_Number*10;for(i=0;i〈6;i++){temp[i]=x24c02_read(Address);delayms(10);Address++;}for(i=0;i<6;i++){if(temp[i]==UserPassword[i])flag=1;elseflag=0;}return flag;}/********************************************************************* 名称:PassWord_Chack()* 功能:所有用户密码检测*输入:无* 输出: 密码正确与错误,错误返回0,正确返回1********************************************************************/uchar PassWord_Chack(){uchar i=0;while(i<User){if(Chack(i)==1){Member=i+1;return 1;}i++;}return 0;}void delay(uint tt){ uchar i;while(tt-—){for(i=0;i〈125;i++);}}/*********************************************************************名称: UART_Init()*功能: 单片机串口初始化*单片机:晶振11.0592MHz 波特率为9600bps* 指纹模块:波特率为9600bps,********************************************************************/void UART_Init(){SCON= 0x50; //串口方式1 //REN=1; 允许接收PCON=0x00;//SMOD=0TMOD= 0x21;//定时器1定时方式2TH1= 0xFD;//11。

基于STC89C52单片机的电子密码锁(完整版)-附-仿真图-原理图

基于STC89C52单片机的电子密码锁(完整版)-附-仿真图-原理图

目录1绪论 (1)1.1本设计的研究背景与研究目的 (1)1.2国内外研究现状 (2)2电子密码锁的总体设计方案 (3)2.1方案论证 (3)2.1.1方案一采用单片机控制方案 (3)2.1.2方案二采用数字电路控制方案 (4)2.1.3方案三采用EDA控制方案 (5)2.2方案比较以及可行性 (5)3电子密码锁硬件电路的设计 (6)3.1中央控制模块的设计 (6)3.1.1主控芯片STC89C52单片机的简介 (6)3.1.2时钟电路的设计 (7)3.1.3复位电路的设计 (8)3.2键盘输入模块的设计 (9)3.2.1矩阵键盘工作原理 (9)3.2.2单片机键盘扫描法 (10)3.3LCD显示密码模块的设计 (10)3.3.1LCD1602简介 (11)3.3.2LCD1602液晶显示模块与单片机连接电路 (12)3.4开锁模块的设计 (13)3.5报警模块的设计 (13)3.6硬件电路总体设计 (14)4电子密码锁的软件设计 (15)4.1主程序流程介绍 (15)4.2键盘模块流程图 (16)4.3显示模块流程图 (18)4.4修改密码流程图 (19)4.5开锁和报警模块流程图 (20)5电子密码锁的系统调试及分析 (22)5.1硬件电路调试及结果分析 (22)5.2软件调试及功能分析 (22)5.2.1调试过程 (22)5.2.2仿真结果分析 (24)5.3系统调试 (26)6结论及展望 (28)6.1结论 (28)6.2展望 (28)谢辞 (29)参考文献 (30)附录 (32)附1部分代码 (32)附2总电路图 (40)电子密码锁的设计与制作1绪论1.1本设计的研究背景与研究目的随着人们生活水平的提高和社会科技的进步,锁已发展到了密码锁、磁性锁、电子锁、激光锁、声控锁等等。

在传统钥匙的基础上,加了一组或多组密码,不同声音,不同磁场,不同声波,不同光束光波,不同图像。

(如指纹、眼底视网膜等)来控制锁的开启。

单片机密码锁(掉电可记忆密码)

单片机密码锁(掉电可记忆密码)

/***************************************************** ***************************程序功能:本程序结合了24C02存储器的存储功能,可以掉电保存密码。

第一次运行时,若输入000000原始密码后无反应,可以试验着将主程序中前面的一小段被注释线屏蔽的程序前的注释线删掉,然后从头编译下载(可以将密码还功能键S1---S10数字键0-9S12---更改密码完毕后确认S11---更改密码S13---重试密码、从头设定S14---关闭密码锁初始密码:000000密码位数:6位原为000000)。

此后,再将这小段程序屏蔽掉,再编译下载。

方可正常使用。

1、开锁:下载程序后,直接按六次S1(即代表数字1),8位LED亮,锁被打开,输入密码时,六位数码管依次显示小横杠。

2、更改密码:只有当开锁(LED亮)后,该功能方可使用。

首先按下更改密码键S11,然后设置相应密码,此时六位数码管会显示设置密码对应的数字。

最后设置完六位后,按下S12确认密码更改,此后新密码即生效。

3、重试密码:当输入密码时,密码输错后按下键S13,可从头输入六位密码。

当设置密码时,设置中途想更改密码,也可按下此键从头设置。

4、关闭密码锁:按下S14即可将打开的密码锁关闭。

推荐初级演示步骤:输入原始密码000000---按下更改密码按键S11---按0到9设置密码---按S12确认密码更改---按S14关闭密码锁---输入新的密码打开密码锁***************************************************************** **************/#include<>#include <>#define uint unsigned int#define uchar unsigned charuchar old1,old2,old3,old4,old5,old6; //原始密码000000uchar new1,new2,new3,new4,new5,new6;//每次MCU采集到的密码输入uchar a=16,b=16,c=16,d=16,e=16,f=16; //送入数码管显示的变量uchar wei,key,temp;bit allow,genggai,ok,wanbi,retry,close;//各个状态位sbit dula=P2^6;sbit wela=P2^7;sbit beep=P2^3;sbit sda=P2^0;//IO口定义sbit scl=P2^1;unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00,0x40};/*****************IIC芯片24C02存储器驱动程序************************************/void nop(){}/////////24C02读写驱动程序////////////////////void delay1(unsigned int m){unsigned int n;_nop_();_nop_();for(n=0;n<m;n++);}void init()//24c02初始化子程序{}void start()//启动I2C总线{sda=1;scl=1;nop();sda=1;nop();}nop();scl=1;nop();sda=0;nop();scl=0;nop();void stop()//停止I2C总线{}void writebyte(unsigned char j)//写一个字节{unsigned char i,temp;sda=0;nop();scl=1;nop();sda=1;nop();temp=j;for (i=0;i<8;i++){}temp=temp<<1;scl=0;nop();sda=CY;nop();scl=1;nop();//待sda线上的数据安定后,将scl拉高//temp左移时,移出的值放入了CY中scl=0;nop();sda=1;nop();}unsigned char readbyte()//读一个字节{unsigned char i,j,k=0;scl=0; nop(); sda=1;for (i=0;i<8;i++){nop(); scl=1; nop();if(sda==1)j=1;elsej=0;k=(k<<1)|j;scl=0;}nop();}void clock()//I2C总线时钟{unsigned char i=0;scl=1;nop();while((sda==1)&&(i<255))i++;scl=0;nop();}////////从24c02的地址address中读取一个字节数据/////unsigned char read24c02(unsigned char address){unsigned char i;start();writebyte(0xa0);clock();return(k);writebyte(address);clock();start();writebyte(0xa1);clock();i=readbyte();stop();delay1(100);return(i);}//////向24c02的address地址中写入一字节数据info///// void write24c02(unsigned char address,unsigned char info) {start();writebyte(0xa0);clock();writebyte(address);clock();writebyte(info);clock();stop();delay1(5000); //这个延时一定要足够长,否则会出错。

单片机课程设计密码锁程序和仿真图

单片机课程设计密码锁程序和仿真图

#include<at89x51.h>#define uchar unsigned char#define uint unsigned intuint num=10; //开始让数码管什么都不显示bit set=0; //定义设置密码的位char count=-1; //开始让COUNT=-1,方便后面显示数码管sbit Beep=P1^2; //蜂鸣器uchar temp;uchar pws[6]={3,6,2,3,3,0}; //原始密码uchar pwx[6]; //按下的数字存储区bit rightflag; //密码正确标志位uchar workbuf[6];uchar code tabledu[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00,0x40 }; //段选码,共阴极uchar code tablewe[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf}; //位选码uint keyscan();void delay(uchar z) //延时,ms级{uchar y;for(;z>0;z--)for(y=120;y>0;y--);}void setpw() //设置密码函数{keyscan();}uint keyscan() //键盘扫描函数{P3=0xfe;temp=P3;temp=temp&0xf0;if(temp!=0xf0){delay(5); //键盘去抖,最好ms以上,这里用了mstemp=P3;temp=temp&0xf0;if(temp!=0xf0){count++;//按键计数加temp=P3;switch(temp){case 0xee:{num=7;if(count<6) //六位密码,所以COUNT<6{if(set==0) //设置密码键没有按下时pwx[count]=num; //存储按下的数字elsepws[count]=num; //设置密码键按下时,设置新密码workbuf[count]=tabledu[11]; //相应位的数码管显示"--",不显示相应的数字,密码是保密的}}break;case 0xde:{num=8;if(count<6) //以下扫描键盘的原理差不多同上{if(set==0)pwx[count]=num;elsepws[count]=num;workbuf[count]=tabledu[11];}}break;case 0xbe:{num=9;{if(count<6){if(set==0)pwx[count]=num;elsepws[count]=num;workbuf[count]=tabledu[11];}}}break;case 0x7e: //设置密码键按下{set=1; //设置密码标志位置P1_3=0; //设置密码指示灯亮workbuf[0]=0x00;//数码管第一位不显示workbuf[1]=0x00;//......workbuf[2]=0x00;//......workbuf[3]=0x00;workbuf[4]=0x00;workbuf[5]=0x00;//......count=-1; //按键计数复位为-1if(count<6) //密码没有设置完,继续设置密码{setpw(); //设置密码}}break;}while(temp!=0xf0) //按键抬起检测{temp=P3;temp=temp&0xf0;}}}P3=0xfd;temp=P3;temp=temp&0xf0;if(temp!=0xf0){delay(5);temp=P3;temp=temp&0xf0;if(temp!=0xf0){count++;temp=P3;switch(temp){case 0xed:{num=4;if(count<6){if(set==0)pwx[count]=num;elsepws[count]=num;workbuf[count]=tabledu[11];}}break;case 0xdd:{num=5;if(count<6){if(set==0)pwx[count]=num;elsepws[count]=num;workbuf[count]=tabledu[11];}}break;case 0xbd:{num=6;if(count<6){if(set==0)pwx[count]=num;elsepws[count]=num;workbuf[count]=tabledu[11];}}break;}while(temp!=0xf0){temp=P3;temp=temp&0xf0;}}}P3=0xfb;temp=P3;temp=temp&0xf0;if(temp!=0xf0){delay(5);temp=P3;temp=temp&0xf0;if(temp!=0xf0){count++;temp=P3;switch(temp){case 0xeb:{num=1;if(count<6){if(set==0)pwx[count]=num;elsepws[count]=num;workbuf[count]=tabledu[11];}}break;case 0xdb:{num=2;if(count<6){if(set==0)pwx[count]=num;elsepws[count]=num;workbuf[count]=tabledu[11];}}break;case 0xbb:{num=3;if(count<6){if(set==0)pwx[count]=num;elsepws[count]=num;workbuf[count]=tabledu[11];}}break;}while(temp!=0xf0){temp=P3;temp=temp&0xf0;}}}P3=0xf7;temp=P3;temp=temp&0xf0;if(temp!=0xf0){delay(5);temp=P3;temp=temp&0xf0;if(temp!=0xf0){count++;temp=P3;switch(temp){case 0xd7:{num=0;if(count<6){if(set==0)pwx[count]=num;elsepws[count]=num;workbuf[count]=tabledu[11];}}break;case 0xe7: num=20;break; //确定键按下检测case 0x77: //复位键或者输入密码全部一次删除{P1_1=0; //锁关P1_3=1; //密码设置指示灯灭set=0; //不设置密码num=10; //num复位count=-1; //COUNT复位workbuf[0]=tabledu[10]; //第一位数码管不显示workbuf[1]=tabledu[10]; //第二位数码管不显示workbuf[2]=tabledu[10];workbuf[3]=tabledu[10];workbuf[4]=tabledu[10];workbuf[5]=tabledu[10]; //......P1_0=1; //锁关}break;case 0xb7: //输入密码删除键(一位一位删除){count--;workbuf[count]=0x00; //因确定键按下时,COUNT也会加,而确定键不是密码,所以这里是COUNT,而不是COUNT+1count--; //因确定键按下时,确定键不是密码,COUNT也会加,这里COUNT再自减if(count<=-1)count=-1;}break;}while(temp!=0xf0){temp=P3;temp=temp&0xf0;}}}return(num);}void init() //利用定时显示数码管{TMOD=0x01;TH0=(65536-500)/200;TL0=(65536-500)%200;ET0=1;EA=1;TR0=1;}bit compare() //密码比较函数{if((pwx[0]==pws[0])&(pwx[1]==pws[1])&(pwx[2]==pws[2])&(pwx[3]==pws[3])&(pwx[4]==pws[4])&(pw x[5]==pws[5]))rightflag=1;elserightflag=0;return(rightflag);}void main(){uint i,j;init();P0=0;P1_1=0; //锁关while(1){keyscan();if(num==20) //如果确定键按下(修改密码和输入密码共用的确定键){if(count==6){if(set==1) //修改密码确定{P1_3=1;workbuf[0]=0;workbuf[1]=0;workbuf[2]=0;workbuf[3]=0;workbuf[4]=0;workbuf[5]=0;}else//输入密码确定{set=0;compare();if(rightflag==1) //如果密码正确{P1_0=0; //锁开P1_1=1;workbuf[0]=tabledu[8]; //数码管第一位显示"8"workbuf[1]=tabledu[8]; //数码管第二位显示"8"workbuf[2]=tabledu[8];workbuf[3]=tabledu[8];workbuf[4]=tabledu[8];workbuf[5]=tabledu[8]; //......}else{P1_1=0; //锁仍然是关workbuf[0]=0X71; //数码管第一位显示"F"workbuf[1]=0X71;workbuf[2]=0X71;workbuf[3]=0X71;workbuf[4]=0X71;workbuf[5]=0X71; //......for(i=0;i<1000;i++) //密码错误报警{for(j=0;j<80;j++);Beep=~Beep;}break;}}}else//若输入的密码位数不为位时{P1_1=0; //锁仍然关workbuf[0]=0X71; //数码管第一位显示"F"workbuf[1]=0X71;workbuf[2]=0X71;workbuf[3]=0X71;workbuf[4]=0X71;workbuf[5]=0X71;for(i=0;i<1000;i++){for(j=0;j<80;j++);Beep=~Beep;}break;}}}}void timer0() interrupt 1 //显示数码管{uchar i;TH0=(65536-500)/200; TL0=(65536-500)%200; for (i=0;i<6;i++) { P0=workbuf[i]; P2=tablewe[i]; delay(5); P0=0;}}XTAL218XTAL119ALE 30EA31PSEN 29RST9P0.0/AD039P0.1/AD138P0.2/AD237P0.3/AD336P0.4/AD435P0.5/AD534P0.6/AD633P0.7/AD732P1.01P1.12P1.23P1.34P1.45P1.56P1.67P1.78P3.0/RXD 10P3.1/TXD 11P3.2/INT012P3.3/INT113P3.4/T014P3.7/RD17P3.6/WR 16P3.5/T115P2.7/A1528P2.0/A821P2.1/A922P2.2/A1023P2.3/A1124P2.4/A1225P2.5/A1326P2.6/A1427U1AT89C51234567891RP1RESPACK-812365489=7+CONABCD1243D2LED-RED锁开锁关LS1SOUNDERD3LED-BLUE设置密码指示灯R11kR21kR310KR410K+12VQ3TIP127Q4TIP127Q18050Q28050Q5TIP122Q6TIP122+88.8Amps+88.8Amps+88.8Volts。

电子密码锁完整代码

电子密码锁完整代码

#include<reg51.h>#include <intrins.h>#include <absacc.h>#include "VIIC_C51.h"#define uchar unsigned char#define uint unsigned int#define CSI24WC02 0XA0#define uchar unsigned charsbit lcdrs=P2^0;sbit lcdrw=P2^1;sbit lcden=P2^2;sbit alarm=P2^3;sbit red=P2^7;sbit green=P2^6;sbit KEY_INT=P3^2;//led testsbit LED1=P3^5;sbit LED2=P3^1;uchar hour,min,sec,us;uchar flag=1,canscan=0,lock=0;uchar password[8]={0,0,0,0,0,0,0,0};uchar input[8]={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(; no>0; no--){for(i=0; i<100; i++)for(j=0; j<100; j++);}return 0;}unsigned char delay_eep(unsigned char j) {unsigned char k,l;for(l=0;l<=j;l++)for(k=0;k<=250;k++);return 0;}void t0_init(){TMOD=0x01;TL0=0xb0;TH0=0x3c;TR0=0;EA=1;ET0=1;}void delay(uchar n){uchar i;while(n--)for(i=125;i>0;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);write_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(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=a[j];while(j<=3){if((P1&0xF0)!=0xF0){row=~a[j];break;}else{j++;P1=a[j];}}m=row+col;return(m);}elsereturn(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+0x10):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_com(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&&i<8){if(i<8){password[i]=key;gotoxy(1,i);write_data(0x2a);}i++;alarm=0;delay(250);alarm=1;}if(i>=8&&(key==11)){gotoxy(1,10);write_str("SET OK");gotoxy(1,0);write_str(" ");break;}delay(250);}}}//蜂鸣器报警void buzzeralarm(){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);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 td[8]={0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1}; //eeprom send buff uchar rd[8]={0x00,0x01,0x02,0x03,0x04}; //eeprom read buffgreen=0;red=0;t0_init();init_lcd();LED1=0;LED2=0;while(1){tmp=scan(); //读入键值if(tmp!=0){key=coding(tmp);if((key<=9)&&(i<8)&&(lock==0)&&(green!=1))//判断输入次数(i),和锁定情况(lock) 和有效输入(key){red=0;gotoxy(1,10);write_str(" ");gotoxy(1,i);input[i]=key;i++;alarm=0;write_data(0x2a);delay(250);alarm=1;}if(key==10)//{gotoxy(1,i-1);write_data(0x20);if(i>0)i--;delay(250);}if(i==8&&key==11)//确认键{i=0;#if 1IRcvStr(CSI24WC02,0,rd,0x8); //?EEPROMdelay_eep(200);for(i=0; i<8; i++) //?password{password[i] = rd[i];} i = 0;#endiffor(j=0;j<=7;j++){if(input[j]!=password[j])flag=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("LOCKED");}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子程序,如发送数据及接收数据,应答位发送,并提供了几个直接面对器件的操作函数,它很方便的与用户程序连接并扩展.....注意:函数是采用软件延时的方法产生SCL脉冲,固对高晶振频率要作一定的修改....(本例是1us机器周期,即晶振频率要小于12MHZ)********************************************************************/#include <reg51.h> /*头文件的包含*/#include <intrins.h>#define uchar unsigned char /*宏定义*/#define uint unsigned int#define _Nop() _nop_() /*定义空指令*//* 常,变量定义区*//*端口位定义*/sbit SDA=P3^7; /*模拟I2C数据传送位*/sbit SCL=P3^6; /*模拟I2C时钟控制位*//*状态标志*/bit ack; /*应答标志位*//*******************************************************************起动总线函数函数原型: void Start_I2c();功能: 启动I2C总线,即发送I2C起始条件.********************************************************************/ void Start_I2c(){SDA=1; /*发送起始条件的数据信号*/_Nop();SCL=1;_Nop(); /*起始条件建立时间大于4.7us,延时*/_Nop();_Nop();_Nop();_Nop();SDA=0; /*发送起始信号*/_Nop(); /* 起始条件锁定时间大于4μs*/_Nop();_Nop();_Nop();_Nop();SCL=0; /*钳住I2C总线,准备发送或接收数据*/_Nop();_Nop();}/*******************************************************************结束总线函数函数原型: void Stop_I2c();功能: 结束I2C总线,即发送I2C结束条件.********************************************************************/ void Stop_I2c(){SDA=0; /*发送结束条件的数据信号*/_Nop(); /*发送结束条件的时钟信号*/SCL=1; /*结束条件建立时间大于4μs*/_Nop();_Nop();_Nop();_Nop();SDA=1; /*发送I2C总线结束信号*/_Nop();_Nop();_Nop();_Nop();}/*******************************************************************字节数据传送函数函数原型: void SendByte(uchar c);功能: 将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对此状态位进行操作.(不应答或非应答都使ack=0 假)发送数据正常,ack=1; ack=0表示被控器无应答或损坏。

电子密码锁制作及源代码

电子密码锁制作及源代码
rg_key();
didi();
lock=0;
while(l--)
{write_com(0x9e);
write_date(0x30+l); //正在倒计时
for(i=0;i<40;i++)
{if(modify_pw())
{key1=0;
break;}
delay1(25);}
if(key1==0)
{key1=1;
uint a,j;
/*按键声音*/
void didi()
{beep=0;
delay1(70);
beep=1;
delay1(70);
}
/*灯光闪烁*/
void flash()
{leபைடு நூலகம்=0;
delay1(70);
led=1;
delay1(70);
led=0;
delay1(70);
led=1;
delay1(70);}
注释:左图为继电器驱动灯光报警及照明电路图,右图为蜂鸣器报警电路原理图。
5、电磁锁模块设计
电磁锁是本设备中比较重要的电气及机械设备之一,其同样采用继电器驱动,但是由于其功率比较大,所以决定了其工作电流会比正常工作状态要大5倍左右,所以断电瞬间会产生很高的自感电动势,反馈到继电器线圈上,同时其强大的磁场会对单片机的工作造成影响,为了解决这个问题,最好是在单片机输出端加上光耦合器,以起到隔离的目的,但是为了不破坏电路布线的整体性,这里我们在电磁锁两端反向并联了一只高压二极管(1N4148),这样就消除了干扰。
电子密码锁
【摘要】
随着如今智能家居的发展,电子密码锁的兴起也随着得以发展,同时也由于其安全、方便、快捷、美观等特点被广大用户所接受。单片机在此方面的控制也得以普及。本设计是一个电子密码锁成品的模型,共可分为八个模块:主控芯片模块、电源模块、报警电路模块、无线遥控模块、液晶显示模块、键盘扫描、电磁锁模块、照明电路模块。本设计输入正确密码后即可开锁,门便会打开,只有门打开后才可修改密码,同时有密码验证功能。同时密码输入错误三次便会激活报警。为了节约电能,设备无操作一分钟时将会进入省电模式,按任意键后可激活设备。

AT89C51单片机电子密码锁

AT89C51单片机电子密码锁

AT89C51单片机电子密码锁#include"main.h"/******************** LCD PART START *******************************///5ms延时void Delay5Ms(void){unsigned int TempCyc = 5552;while(TempCyc--);}//读状态unsigned char ReadStatusLCM(void){LCM_Data = 0xFF;LCM_RS = 0;LCM_RW = 1;LCM_E = 0;LCM_E = 0;LCM_E = 1;Delay5Ms();while (LCM_Data & Busy); //检测忙信号return(LCM_Data);}//写数据void WriteDataLCM(unsigned char WDLCM){ReadStatusLCM(); //检测忙LCM_Data = WDLCM;LCM_RS = 1;LCM_RW = 0;LCM_E = 0; //若晶振速度太高能够在这后加小的延时LCM_E = 0; //延时LCM_E = 1;}//写指令void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC为0时忽略忙检测{if (BuysC) ReadStatusLCM(); //根据需要检测忙LCM_Data = WCLCM;LCM_RS = 0;LCM_RW = 0;LCM_E = 0;LCM_E = 0;LCM_E = 1;}//读数据unsigned char ReadDataLCM(void){LCM_RS = 1;LCM_RW = 1;LCM_E = 0;LCM_E = 0;LCM_E = 1;return(LCM_Data);}void LCMInit(void) //LCM初始化{LCM_Data = 0;WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号Delay5Ms();WriteCommandLCM(0x38,0);Delay5Ms();WriteCommandLCM(0x38,0);Delay5Ms();WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号WriteCommandLCM(0x08,1); //关闭显示WriteCommandLCM(0x01,1); //显示清屏WriteCommandLCM(0x06,1); // 显示光标移动设置WriteCommandLCM(0x0C,1); // 显示开及光标设置}//按指定位置显示一个字符,x表示列,Y表示行void LCD_write_char(unsigned char X,unsigned char Y, unsigned char DData){Y &= 0x1;X &= 0xF; //限制X不能大于15,Y不能大于1if (Y)X |= 0x40; //当要显示第二行时地址码+0x40;X |= 0x80; // 算出指令码WriteCommandLCM(X, 0); //这里不检测忙信号,发送地址码WriteDataLCM(DData);}//按指定位置显示一串字符void LCD_write_string(unsigned char X,unsigned char Y, unsigned char code *DData){unsigned char ListLength;ListLength = 0;Y &= 0x1;X &= 0xF; //限制X不能大于15,Y不能大于1while (*DData) //若到达字串尾则退出'\0'就是0{if (X <= 0xF) //X坐标应小于0xF{LCD_write_char(X,Y, *DData); //显示单个字符DData++;X++;}}}/************/#include<reg52.h>#include<math.h>#define uchar unsigned char#define uint unsigned int/******************** LCD PART START *******************************/void delay(uint z) //延时{uint x,y;for(x=z;x>0;x--)for(y=124;y>0;y--);}sbit e=P2^5;sbit rw=P2^6;sbit sr=P2^7;uchar code name[]="zxs";uchar code name1[]="zcf";uchar code name2[]="zx";void write_com(uchar com){int rs;rs=0;P0=com;delay(5);e=1;delay(5);e=0;}void write_data(uchar date){int rs;rs=1;P0=date;delay(5);e=1;delay(5);e=0;}void init(){e=0;rw=0;write_com(0x38);write_com(0x0c); write_com(0x06);write_com(0x01);write_com(0x80);}void display(){uchar i;for(i=0;i<3;i++){write_data(name[i]);}write_com(0x80+0x40);for(i=0;i<3;i++){write_data(name1[i]);}}void main(){init();display();}#include <AT89X51.h>#define uchar unsigned charuchar starbuf[10];uchar wordbuf[8];uchar pw[8]={1,2,3,4,5,6,7,8};uchar pwbuf[8];uchar count=0;// 初始没有输入密码,计数器设为0 uchar inputflag=0;// 先处于密码输入状态,非密码修改状态bit enterflag=0; // 没有按下确认键bit pwflag=0;// 密码标志先置为0sbit warn=P3^6;#define lcd_data P0sbit rs=P2^7;sbit rw=P2^6;sbit e=P2^5;///////////////////////LCD1602驱动程序///////////////////////void delay_1602(unsigned int i){while(i--);}void enrw(){rs=0;rw=0;e=0;delay_1602(250);e=1;}write_data(uchar c){lcd_data=c;rs=1;rw=0;e=0;delay_1602(250);e=1;}init_lcd(void)//初始化{lcd_data=0x01;//清屏幕enrw();lcd_data=0x38;//数据长度为8位,双行显示,5*7字符。

单片机密码锁程序

单片机密码锁程序

#include <reg51.h>#include"display.h"#include"delay.h"#define uchar unsigned char#define uint unsigned int#include"Globaldefine.h"#include"keyboard.h"uchar count; // 密码位计数uchar pw[4]; // 初始密码存储区uchar pwbuf[4]; // 输入密码存储区uchar selfdefinebuf[4]; //自定义密码存储区uchar error_cnt; //错误次数计数器bit enterflag; // 确认键按下与否标志bit pwflag; // 密码正确与否标志bit last_pwflag; //前一次密码输入正确与否标志sbit open=P2^5; //锁开指示灯,绿灯。

低电平亮sbit beep=P2^0; //蜂鸣器,低电平叫sbit red=P2^1; //红灯,低电平亮sbit close=P2^7; //锁合指示灯,黄色。

低电平亮sbit youxiao=P2^3; //蓝灯,按键有效指示。

低电平亮void flashred_L(void); //闪红灯,表示可输入自定义密码void flashred_S(void); //快闪红灯,重新输入自定义密码void flashall(void); //三盏灯全亮,不能继续输入uchar code dis_tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};//显示段码表0-F,最后一个位全灭段码sbit dig=P1^1; //数码管位选sbit seg=P1^0; //数码管段选/********************************************************************函数名称:void display(uint m,bit n)函数功能:显示函数入口参数:m-送入的显示值,为4位显示 n-显示模式选择 0显示错误信息 1正常显示送入的值出口参数:无说明:出错信息显示为EOF***********************************************************************/ void display(uint m,bit n){uchar i;uchar temp[4]; //显示的临时数组变量if(n) //如果为模式1{temp[3]=m/1000; //得到送入显示的值的每个位的值temp[2]=m%1000/100;temp[1]=m%100/10;temp[0]=m%10;}else{temp[3]=16; //显示出错信息EOFtemp[2]=14;temp[1]=0;temp[0]=15;}P0=0x00; //清楚上次显示残影seg = 1;seg = 0;i = 0; //for(i=0;i<4;i++){P0 = ~(0x01<<i); //共阴数码管位选低电平选中,故取反移位,数码管显示从右往左dig = 1; //开位选dig = 0; //关位选P0 = dis_tab[temp[i]];//送入显示数据seg = 1; //开段选seg = 0; //关段选delay_ms(1); //延时一定时间}}/* 键消抖延时函数 */void delay(void){uint i;for (i=8000;i>0;i--);}//蓝灯亮一下,再灭,用来表示按键按下有效void youxiaoled(){youxiao=0;delay();youxiao=1;}// 蜂鸣器短叫报警void baojing(){beep=0;delay();beep=1;delay();beep=0;delay();beep=1;}/* 密码比较函数 */bit pwcmp(void){bit flag;uchar i;for (i=0;i<4;i++){if (pw[i]==pwbuf[i])flag = 1;elseflag = 0;i = 4;error_cnt++; //错误次数加1 }}return(flag);}//初始化设置函数。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

单片机密码锁C程序完整代码2009-08-18 14:39#include<AT89x51.h>#include"intrins.h"#include"key.h"#include"xsh.h"#include"24c02.h"#define ulong unsigned longbit BJCB=0;//报警标志XG=0,//修改密码标志位BJ=0,//报警标志位SJ=0;//锁键盘标志位// xg=0;//修改密码标志位uchar PSWD0_0[16]={0};//密码输入缓存存储单元//uchar code PSWD0_1[16]={1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8};//用户初始密码存储单元//uchar PSWD1_0[16]={0};//读出密码缓存存储单元uchar PSWD1_1[16]={1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8};//管理员初始密码存储单元sbit OUT=P3^5;//输出端口sbit L1=P0^2;//上电指示sbit L2=P0^1;//开锁指示sbit L3=P0^0;//报警指示uint mg=0,//密码个数KSC=0,//开锁次数BJC=0,//报警次数TCNTY=0,//用户按键定时次数累加TCNTG=0,//管理员输入密码定时次数yhsh,//用户输入标志位glsh,//管理员输标志位shw;//密码输完标志位void yhmimaxig();//密码修改程序void glmimaxig();//管理员修改程序void bjyin(ulong t){ulong c;uint n;for(c=0;c<t;c++){for(n=0;n<50;n++); //延时BEEP=~BEEP; //取反输出到喇叭的信号}}void delay_10ms(void){uint i = 1000;while(i--);}//////////////定时中断服务函数////////////////////////////////////// void timer0() interrupt 1{uint i;TH0=(65536-50000)/256; //对TH0 TL0赋值50MS定时TL0=(65536-50000)%256; //重装计数初值if(yhsh==1){TCNTY++;//用户定时计数if(shw==1){TR0=0;TCNTY=0;}if(TCNTY==200){TR0=0;//关闭T0定时器TCNTY=0;mg=0;//密码个数清零L1=1;for(i=0;i<2;i++)//声光报警电路{L3=0;bjyin(1000);L3=1;delay(1000);}L1=0;}}else if(glsh==1){TCNTG++;//管理员定时计数if(shw==1){TR0=0;TCNTG=0;}if(TCNTG==160){TR0=0;//关闭T0定时器TCNTG=0;mg=0;//密码个数清零L1=1;for(i=0;i<2;i++)//声光报警电路{L3=0;bjyin(1000);L3=1;delay(1000);}L1=0;}}}void main(){uint i;TMOD=0x01; //定时器工作在方式1ET0=1;EA=1;TH0=(65536-50000)/256; //对TH0 TL0赋值TL0=(65536-50000)%256; //使定时器0.05秒中断一次//Read_page24c02(0x00,PSWD1_1,16);//向24c02里读用户初始密码 //i2cWrite24LC16B(0,0X20);/////////////第一次向24c02里写入初始管理员密码、用户密码、开锁次数/////////////////////KSC=i2cRead24LC16B(0X20);loop: L1=0;//上电红灯亮L2=1;//开锁成功后绿灯亮L3=1;//输错时黄灯亮报警OUT=0;//开信号关闭display_0(KSC);//开锁前显示///////////密码输入/////////////////if(SJ==0)//锁键盘标志位为0{do{flag=0;//键盘标志位key();if(flag==1&&num==12) //判断是否为管理员功能键按下{goto gl;}if(flag==1&&num<=9){PSWD0_0[mg]=num;mg++;//密码个数}if(flag==1&&num==14&&mg>=1)//输入错误删除{mg=mg-1;}if(mg==1) //有密码键按下开定时器限时{TR0=1;yhsh=1;}}while(num!=15);if(mg!=16){for(i=mg;i<16;i++){PSWD0_0[i]=0;}}/////////////////密码比较电路//////////////////////////// if(flag==1&&num==15){ flag=0;yhsh=0;shw=1;num=0;for(i=0;i<16;i++) //从24c02里读出16个密码{PSWD1_1[i]=i2cRead24LC16B(i);delay_10ms;}for(i=0;i<16;i++){if(PSWD1_1[i]!=PSWD0_0[i]){BJCB=1;break;}else}}if(BJCB!=0){BJC++;if(BJC!=3){BJCB=0; //第一次和第二次报警delay(500);mg=0;//密码个数清零L1=1;for(i=0;i<3;i++)//声光报警电路{L3=0;display_3();bjyin(1000);L3=1;delay(1000);}goto loop;}else if(BJC==3){BJC=0;BJCB=0;display_5();//三次输入密码失败,自锁SJ=1;//锁键盘标志位mg=0;//密码个数清零L1=1;for(i=0;i<2;i++)//声光报警电路{L3=0;bjyin(1000);L3=1;delay(1000);}goto loop;}}elseif(BJCB==0){display_1(KSC);i2cWrite24LC16B(KSC,0X20);if(KSC==100){SJ=1;}L2=0;L1=1;OUT=1;mg=0;//密码个数清零loop1:do //键盘扫描等待功能键按下{flag=0;key();if(flag){flag=0;switch(num){case 13:{display_2();do{flag=0;//键盘标志位key();if(flag==1&&num<=9){PSWD0_0[mg]=num;mg++;//密码个数}if(flag==1&&num==14&&mg>=1)//输入错误删除{mg=mg-1;}if(mg==16){do //键盘扫描等待功能键按下{flag=0;key();}while(num!=15);}}while(num!=15);if(mg!=16&&num==15){for(i=mg;i<16;i++){PSWD0_0[i]=0;}}if(flag==1&&num==15){flag=0;mg=0;for(i=0;i<16;i++) //用一次写一个向24c02里写{i2cWrite24LC16B(PSWD0_0[i],i);delay_10ms;}display_1(KSC);do //键盘扫描等待功能键按下{flag=0;key();}while(num!=11); //按下返回键,锁锁返回{goto loop;}}};break;case 11: {goto loop;//break;}}}}while(flag!=0);//如果设置密码键按下goto loop1;// i2cWrite24c02_page(0x00,PSWD1_1,mg);}}else{do{flag=0;key();}while(num!=12);//判断是否为管理员功能键按下gl:do//管理员输入密码{flag=0;key();if(flag==1&&num<=9){PSWD0_0[mg]=num;mg++;//密码个数}if(flag==1&&num==14&&mg>=1)//删除键按下{mg=mg-1;}if(mg==1){TR0=1;}//开定时器TO限5秒开锁}while(num!=15);if(mg!=16&&num==15){for(i=mg;i<16;i++){PSWD0_0[i]=0;}}//////////管理员密码比较/////////////////////// //Read_page24c02(0x10,PSWD0_1,16)for(i=0;i<16;i++) //从24c02里读出16个密码{PSWD1_1[i]=i2cRead24LC16B((0x10+i));delay_10ms;}if(flag==1&&num==15){ flag=0;shw=1;num=0;for(i=0;i<mg;i++){if(PSWD1_1[i]!=PSWD0_0[i]){ BJCB=1;break;}elseBJCB=0;}}if(BJCB!=0){BJC++;if(BJC!=3){BJCB=0; //第一次和第二次报警mg=0;//密码个数清零L1=1;for(i=0;i<2;i++)//声光报警电路{L3=0;display_3();bjyin(1000);L3=1;delay(1000);}display_1(KSC);goto loop;}else{BJCB=0;display_5();//三次输入密码失败,自锁mg=0;//密码个数清零delay(10000);display_1(KSC);goto loop;}}else{SJ=0;display_4();//管理员开锁显示mg=0;L2=0;L1=1;L3=0;//密码个数清零do //键盘扫描等待功能键按下{flag=0;key();}while(flag==0); //如果设置密码键按下if(flag==1&&num==13){flag=0;display_2();do{flag=0;//键盘标志位key();if(flag==1&&num<=9){PSWD0_0[mg]=num;mg++;//密码个数}if(flag==1&&num==14&&mg>=1)//输入错误删除 {mg=mg-1;}if(mg==16){do //键盘扫描等待功能键按下{flag=0;key();}while(num!=15);}}while(num!=15);if(mg!=16&&num==15){for(i=mg;i<16;i++){PSWD0_0[i]=0;}}if(flag==1&&num==15){flag=0;mg=0;for(i=0;i<16;i++) //用一次写一个向24c02里写{i2cWrite24LC16B(PSWD0_0[i],(0x10+i));delay_10ms;}display_4();do //键盘扫描等待功能键按下{flag=0;key();}while(num!=11); //按下返回键,锁锁返回{goto loop;}}}if(flag==1&&num==10){KSC=0;i2cWrite24LC16B(KSC,0X20);display_1(KSC);do //键盘扫描等待功能键按下{flag=0;key();}while(num!=11);//按下返回键,锁锁返回goto loop;}if(flag==1&&num==11)//按下返回键,锁锁返回{goto loop;}}}}#ifndef _key_h#define _key_h#include<AT89x51.h>#define uchar unsigned char#define uint unsigned intbit flag=0;//按键按下标志位sbit BEEP=P3^7;//蜂鸣器端口delay(int z)//延时1ms{ int x,y;for (x=z;x>0;x--)for (y=140;y>0;y--);}uchar num;//按键返回值////////按键音程序////////////////// void yin(){int c,n;if(flag==1){for(c=0;c<80;c++){for(n=0;n<50;n++); //延时BEEP=~BEEP; //取反输出到喇叭的信号}}}////////////键盘程序/////////////////// int key(){ uchar temp;P2=0X7f;temp=P2&0x0f;if(temp!=0x0f){delay(5);if(temp!=0x0f){temp=P2;switch(temp){ case 0x77:num=0;break;case 0x7b:num=1;break;case 0x7d:num=2;break;case 0x7e:num=3;}do{ //等待按键抬起 temp=P2;temp=temp&0x0f;}while(temp!=0x0f);flag=1;yin();}}P2=0Xbf;temp=P2&0x0f;if(temp!=0x0f){delay(5);if(temp!=0x0f){temp=P2;switch(temp){ case 0xb7:num=4;break;case 0xbb:num=5;break;case 0xbd:num=6;break;case 0xbe:num=7;break;}do{temp=P2;temp=temp&0x0f;}while(temp!=0x0f);flag=1;yin();}}P2=0Xdf;temp=P2&0x0f;if(temp!=0x0f){delay(5);if(temp!=0x0f){temp=P2;switch(temp){ case 0xd7:num=8;case 0xdb:num=9;break;case 0xdd:num=10;break;case 0xde:num=11;break;}do{temp=P2;temp=temp&0x0f;}while(temp!=0x0f);flag=1;yin();}}P2=0Xef;temp=P2&0x0f;if(temp!=0x0f){delay(5);if(temp!=0x0f){temp=P2;switch(temp){ case 0xe7:num=12;break;case 0xeb:num=13;break;case 0xed:num=14;break;case 0xee:num=15;break;}do{temp=P2;temp=temp&0x0f;}while(temp!=0x0f);flag=1;yin();}}return(num);}#endif#ifndef _xsh_h#define _xsh_h#include<AT89x51.h>#define uchar unsigned char#define uint unsigned intsbit shj=P1^0;//串口数据口sbit sck=P1^1;//串口时钟uchar code tab[20]={ 0x88,/*0*/0xBE,/*1*/0xC4,/*2*/0x94,/*3*/0xB2,/*4*/0x91,/*5*/0x81,/*6*/0xBC,/*7*/0x80,/*8*/0x90,/*9*/0xA0,/*A*/0x83,/*b*/0xC9,/*C*/0x86,/*d*/0xC1,/*E*/0xE1,/*F*/0xA8,/*N*/0xF7,/*-*/0x94,/*反E*/0xE0/*P*/ }; //共阳数码管uchar code sb0[3]={8,8,8},/*开锁后显示*/code sb1[3]={0,15,15},/*开锁前显示*/code sb2[6]={17,17,17,17,17,17},/*修改显示*/code sb3[6]={16,0,16,0,16,0},/*第一二次报警显示*/ code sb4[6]={8,8,8,8,8,8},/*管理员进入显示*/code sb5[6]={18,18,18,18,18,18};/*第三次报警显示*///////////////////////////*显示电路*///////////////////////// void writedata(uchar num)//传送一个字节{uchar temp;int i;temp=tab[num];for(i=0;i<8;i++){ temp=temp<<1;shj=CY;sck=0;sck=1;}}void display_0(uchar temp)//开锁前状态{ int i,g,s,q;uchar m;q=temp/100;s=temp%100/10;g=temp%10;for(i=0;i<3;i++){m=sb1[i];writedata(m);}writedata(q);writedata(s);writedata(g);}void display_1(uchar temp)//开锁后状态{int i,g,s,q;uchar m;q=temp/100;s=temp%100/10;g=temp%10;for(i=0;i<3;i++){m=sb0[i];writedata(m);}writedata(q);writedata(s);writedata(g);}void display_2()//修改密码显示{int i;uchar m;for(i=0;i<6;i++){m=sb2[i];writedata(m);}}void display_3()//报警显示{int i;uchar m;for(i=0;i<6;i++){m=sb3[i];writedata(m);}}void display_4()//管理员模式显示{int i;uchar m;for(i=0;i<6;i++){m=sb4[i];writedata(m);}}void display_5()//管理员模式显示{int i;uchar m;for(i=0;i<6;i++){m=sb5[i];writedata(m);}}#endif#ifndef _24c02_h#define _24c02_h#include<AT89x51.h>#define WriteDeviceAddress 0xa0#define ReadDeviceAddress 0xa1sbit SDA=P1^5;//I2C数据端sbit SCL=P1^6;//I2C时钟端///////////////////////24C0224C08读写驱动程序///////////////////////void DelayMs(unsigned int number) {unsigned char temp;for(;number>=1;number--){for(temp=112;temp>=1;temp--) ;}}void i2cStart(void){SDA=1;SCL=1;_nop_();_nop_();_nop_();_nop_();_nop_();SDA=0;_nop_();_nop_();_nop_();_nop_();_nop_();SCL=0;}void i2cStop(void){SDA=0;SCL=1;_nop_();_nop_();_nop_();_nop_();_nop_();SDA=1;_nop_();_nop_();_nop_();_nop_();_nop_();}void i2cAck(void){SDA=0;SCL=1;_nop_();_nop_();_nop_();_nop_();SDA=1;SCL=0;}void i2cNoAck(void){SDA=1;SCL=1;_nop_();_nop_();_nop_();_nop_();SDA=0;SCL=0;}void i2cWrite8Bit(unsigned char input) {unsigned char temp;for(temp=8;temp!=0;temp--){SDA=(bit)(input&0x80);SCL=1;_nop_();_nop_();_nop_();_nop_();_nop_();SCL=0;input=input<<1;}DelayMs(20);}unsigned char i2cRead8Bit(void){unsigned char temp,rbyte=0;for(temp=8;temp!=0;temp--){SCL=1;_nop_();_nop_();_nop_();rbyte=rbyte<<1;rbyte=rbyte|((unsigned char)(SDA));SCL=0;}return(rbyte);}void i2cWrite24LC16B(unsigned char wdata,unsigned char RomAddress) {i2cStart();i2cWrite8Bit(WriteDeviceAddress);i2cAck();i2cWrite8Bit(RomAddress);i2cAck();i2cWrite8Bit(wdata);i2cAck();i2cStop();DelayMs(20);}//写入多个字节到24c02中//传入参数:地址、待写入的数据的首地址、数据长度bit i2cWrite24c02_page(uchar RomAddress,uchar *WRdata,uchar length) {uint i;i2cStart();i2cWrite8Bit(WriteDeviceAddress);i2cAck();i2cWrite8Bit(RomAddress);i2cAck();for(i=0;i<length;i++){i2cWrite8Bit(*WRdata);i2cAck();WRdata++;}i2cStop();DelayMs(20);return(1);}unsigned char i2cRead24LC16B(unsigned char RomAddress){unsigned char x;i2cStart();i2cWrite8Bit(WriteDeviceAddress);i2cAck();i2cWrite8Bit(RomAddress);i2cAck();i2cStart();i2cWrite8Bit(ReadDeviceAddress);i2cAck();_nop_();_nop_();_nop_();x=0;x=i2cRead8Bit();i2cNoAck();i2cStop();return(x);}//从24c02中读出多个字节bit Read_page24c02(uchar RomAddress,uchar p[],uint n) { uint i;i2cStart();i2cWrite8Bit(WriteDeviceAddress);i2cAck();i2cWrite8Bit(RomAddress);i2cAck();i2cStart();i2cWrite8Bit(ReadDeviceAddress);i2cAck();_nop_();_nop_();_nop_();for(i=0;i<n-1;i++){p[i]=i2cRead8Bit();i2cAck();}p[n-1]=i2cRead8Bit();i2cNoAck();i2cStop();return(1);}。

相关文档
最新文档