门禁系统项目驱动程序
LCD_Data_DisWord(35,6,cheng); LCD_Data_DisWord(75,6,shibai); /******************************AT24C64存储程序*******************************/ void I2C_Start(void){//I2C总线启动 /******************************按键控制程序*********************************/ void KeyScan(){//按键扫描
LCD_Data_DisWord(47,6,gong);
LCD_Data_DisWord(87,6,bai);
}
void LCD_Display5(){//显示存卡过程:存入或取消存储
LCD_Data_DisWord(2,0,cun);//存卡
LCD_Data_DisWord(14,0,ka);
LCD_Data_DisWord(2,2,ka);//卡号
LCD_Data_DisWord(14,2,hao);
LCD_Data_DisNum(26,2,maohao);
}
void LCD_Display6(){//显示卡号删除过程:确认删除或取消删除
LCD_Data_DisWord(2,0,liu);//浏览卡号
LCD_Data_DisWord(14,0,lan);
LCD_Data_DisWord(26,0,ka);
LCD_Data_DisWord(38,0,hao);
LCD_Data_DisWord(2,2,ka);//卡号显示
LCD_Data_DisWord(14,2,hao);
LCD_Data_DisNum(26,2,maohao);
LCD_Data_DisWord(35,4,shan);
LCD_Data_DisWord(47,4,chu);
LCD_Data_DisWord(75,4,qu);
LCD_Data_DisWord(87,4,quxiao);
}
SCL_24C64 = 1;
_nop_();
SDA_24C64 = 1;
_nop_();
SDA_24C64 = 0;
}
void I2C_Stop(void){//I2C总线通信结束
SCL_24C64 = 0;
SDA_24C64 = 0;
_nop_();
SCL_24C64 = 1;
SDA_24C64 = 1;
}
void I2C_ACK_Send(bit ack){//发送返回帧
SDA_24C64 = ack;
SCL_24C64 = 1;
_nop_();
SCL_24C64 = 0;
SDA_24C64 = 1;//释放总线
}
bit I2C_ACK_Receive(){//接收返回帧
bit ACKR;
SDA_24C64 = 1;//释放总线
SCL_24C64 = 1;
_nop_();
ACKR = SDA_24C64;
SCL_24C64 = 0;
return ACKR;
}
void I2C_SendByte(uchar WData){//写入一个字节的数据
uchar Count;
SCL_24C64 = 0;
for(Count = 0;Count < 8;Count ++){
WData <= 1;
SDA_24C64 = CY;
SCL_24C64 = 1;//下降沿写入数据
_nop_();
SCL_24C64 = 0;
}
}
uchar I2C_ReceiveByte(){//读出一个字节的数据
uchar Count,RData;
SCL_24C64 = 0;
for(Count = 0;Count < 8;Count ++){
RData <= 1;
SCL_24C64 = 1;//高电平读出数据
_nop_();
if(SDA_24C64)
RData |= 0x01;
elseRData &= 0xfe;
SCL_24C64 = 0;
}
return RData;
}
void I2C_Write_AT24C64(uchar WAddrH,uchar WAddrL,uchar *Point,uchar WNum){//向WAddrH,WAddrL为首地址的页中写入WNum个字节
bit ACK;uchar Cnt;
I2C_Start();//启动通信
do{
I2C_SendByte(0xa0);//AT24C64的写地址
ACK = I2C_ACK_Receive();
}while(ACK);
do{
I2C_SendByte(WAddrH); //写字节高地址
ACK = I2C_ACK_Receive();
}while(ACK);
do{
I2C_SendByte(WAddrL); //写字节低地址
ACK = I2C_ACK_Receive();
}while(ACK);
for(Cnt = 0;Cnt < WNum;Cnt ++,Point ++){//循环写入WNum个字节
do{
I2C_SendByte(*Point); //写的内容
ACK = I2C_ACK_Receive();
}while(ACK);
}
I2C_Stop(); //通信结束
}
uchar I2C_Read_AT24C64(uchar WAddrH,uchar WAddrL,uchar RNum){//从WAddrH,WAddrL为首地址的页中读取RNum个字节
uchar Cnt;//一页最多32个字节
bit ACK;
I2C_Start();//启动通信
do{
I2C_SendByte(0xa0);//AT24C64的写地址
ACK = I2C_ACK_Receive();
}while(ACK);
do{
I2C_SendByte(WAddrH);//写入地址的高5位
ACK = I2C_ACK_Receive();
}while(ACK);
do{
I2C_SendByte(WAddrL);//写入地址的低8位
ACK = I2C_ACK_Receive();
}while(ACK);
I2C_Start();//再次启动通信
do{
I2C_SendByte(0xa1);//AT24C64的读地址
ACK = I2C_ACK_Receive();
}while(ACK);
for(Cnt = 0;Cnt < RNum;Cnt ++){//循环读取RNum个字节
RD24C64[Cnt] = I2C_ReceiveByte();
if(Cnt != RNum - 1)
I2C_ACK_Send(0);
}
I2C_ACK_Send(1);//读取最后一个字节的数据后的返回帧
I2C_Stop();//通信结束
}
void AT24C64Init(){//24C64初始化
//I2C_Write_AT24C64(0x00,0x1f,&CardMax,1);//将存储卡的最大数目初始化为0
//I2C_Write_AT24C64(0x00,0x1e,&CardNum,1);//将存储卡的数目初始化为0
I2C_Read_AT24C64(0x00,0x1f,1);//读取0x00,0x1f地址中的内容,其为存储卡过程中曾存卡的最多个数
CardMax = RD24C64[0];//将读取的数据存入卡数目最大值变量CardMax中
I2C_Read_AT24C64(0x00,0x1e,1);//读取0x00,0x1e地址中的内容,其为存储卡的数目
CardNum = RD24C64[0];//将读取的数据存入卡数目变量CardNum中
EEAddr = 0x0000;//将24C64的地址初始化到首地址
}
if(!KEY1){
DelCount = 0;
while(DelCount < 2);
if(!KEY1){
while(!KEY1);
Function = 1;
}
}
if(!KEY2){
DelCount = 0;
while(DelCount < 2);
if(!KEY2){
while(!KEY2);
Function = 2;
}
}
if(!KEY3){
DelCount = 0;
while(DelCount < 2);
if(!KEY3){
while(!KEY3);
Function = 3;
}
}
if(!KEY4){
DelCount = 0;
while(DelCount < 2);
if(!KEY4){
while(!KEY4);
Function = 4;
}
}
}
void KeyFunc(){//按键功能分配
uchar Cnt = 0;
bit CFlag = 0;//待存入的卡与EEPROM中的卡号比较标志位
switch(Function){//具体按键功能分配程序
case 1:if(!SwitchFlag){//切换标志位,用于存卡及浏览卡号时上翻
TimeDisFlag = 1;//存储卡号期间主函数运行时不再显示时间
KEndFlag = 0;//确认在进入存卡系统后刷卡有效,否则无效
WXFlag = 1;//按下KEY1后,接着按key2无效
StoreFlag = 1;//存储标志位,0为无效,1为存储
LCD_All_Clear();//清全屏
LCD_Display5();//显示存卡界面
while(!KEndFlag);//等待刷卡后读取卡信息结束
KEndFlag = 0;//确认在进入存卡系统后刷卡有效,否则无效
for(Cnt = 1;Cnt < 11;Cnt ++){//显示读取的卡号
if(CardNo[Cnt] >= 0x40)
LCD_Data_DisNum(32 + Cnt * 6,2,num[CardNo[Cnt]-0x40+10]);
elseLCD_Data_DisNum(32 + Cnt * 6,2,num[CardNo[Cnt]-0x30]);
}
LCD_Data_DisWord(35,4,cun);//显示汉字“存入”“取消”
LCD_Data_DisWord(47,4,ru);
LCD_Data_DisWord(75,4,qu);
LCD_Data_DisWord(87,4,quxiao);
}
if(SwitchFlag){//浏览卡号时上翻功能
if(!NSK12Flag){
while(1){
if(EEAddr == 0x0000)
EEAddr = 0x0000 + (CardMax - 1) * 0x20;
elseEEAddr -= 0x20;//24C64存储时一页存储一张卡号
I2C_Read_AT24C64(EAddrH,EAddrL,12);//读取24C64中存储的卡号
if(RD24C64[0] == 1){//从24C64EEAddr地址中读取的卡号有效
for(Cnt = 2;Cnt < 12;Cnt ++){//显示读取的卡号
if(RD24C64[Cnt] >= 0x40)
LCD_Data_DisNum(32 + (Cnt - 1) * 6,2,num[RD24C64[Cnt]-0x40+10]);
elseLCD_Data_DisNum(32 + (Cnt - 1) * 6,2,num[RD24C64[Cnt]-0x30]);
}
break;//显示一个有效的卡号后退出
}
}
}
}
break;
case 2:if(!WXFlag){
if(SwitchFlag){//浏览卡号时下翻功能
if(!NSK12Flag){
while(1){
EEAddr += 0x20;//往下翻页
if(EEAddr == 0x0000 + CardMax * 0x20)
EEAddr = 0x0000;
I2C_Read_AT24C64(EAddrH,EAddrL,12);
if(RD24C64[0] == 1){//读取的卡号有效
for(Cnt = 2;Cnt < 12;Cnt ++){//显示读取的卡号
if(RD24C64[Cnt] >= 0x40)
LCD_Data_DisNum(32 + (Cnt - 1) * 6,2,num[RD24C64[Cnt]-0x40+10]);
elseLCD_Data_DisNum(32 + (Cnt - 1) * 6,2,num[RD24C64[Cnt]-0x30]);
}
break;
}
}
}
}
if(!SwitchFlag){//删除卡号
TimeDisFlag = 1;//删除卡号期间主函数运行时不再显示时间
DeleteFlag = 1;//删除标志位,0为无效,1为存储
SwitchFlag = 1;
LCD_All_Clear();//清全屏
I2C_Read_AT24C64(0x00,0x1e,1);
CardNum = RD24C64[0];
if(CardNum == 0)NSK12Flag = 1;
for(EEAddr = 0x0000;EEAddr < 0x0000 + CardMax * 0x20;EEAddr += 0x20){//读出卡号和存储器中的卡号进行比较
I2C_Read_AT24C64(EAddrH,EAddrL,12);
if(RD24C64[0] == 1){
for(Cnt = 2;Cnt < 12;Cnt ++){//显示读取的卡号
if(RD24C64[Cnt] >= 0x40)
LCD_Data_DisNum(32 + (Cnt - 1) * 6,2,num[RD24C64[Cnt]-0x40+10]);
elseLCD_Data_DisNum(32 + (Cnt - 1) * 6,2,num[RD24C64[Cnt]-0x30]);
}
break;
}
}
LCD_Display6();//显示存卡界面
}
}
break;
case 3:if(StoreFlag){//存储卡号
Cnt = 0;
for(EEAddr = 0x0000;EEAddr < 0x0000 + CardMax * 0x20;EEAddr += 0x20){//读出卡号和存储器中的卡号进行比较
I2C_Read_AT24C64(EAddrH,EAddrL,12);
if(RD24C64[0] == 1){
for(Cnt = 0;Cnt < 11;Cnt ++){//11位卡号进行比较
if(CardNo[Cnt] != RD24C64[Cnt + 1])//比较过程中有不相等的就读下一内存
break;
}
}
if(Cnt == 11){//一组数据比较过程中全部相等时,此卡已存在
CFlag = 1;
LCD_Page_Clear(4);//清除4,5页的显示内容
LCD_Data_DisWord(34,4,ci);//显示“此卡已存在”
LCD_Data_DisWord(46,4,ka);
LCD_Data_DisWord(58,4,yi);
LCD_Data_DisWord(70,4,cun);
LCD_Data_DisWord(82,4,zai);
break;
}
}
if(!CFlag){
I2C_Read_AT24C64(0x00,0x1e,1);
CardNum = RD24C64[0];
I2C_Read_AT24C64(0x00,0x1f,1);
CardMax = RD24C64[0];
if(CardNum == CardMax){//往后边空间存储
EEAddr = 0x0000 + CardMax * 0x20;
I2C_Write_AT24C64(EAddrH,EAddrL,&Sto,1);//存入标志位,表示此页已存入卡号
DelCount = 0;//延时10ms
while(DelCount < 2);
I2C_Write_AT24C64(EAddrH,EAddrL + 1,CardNo,11);//存入11位卡号
DelCount = 0;//延时10ms
while(DelCount < 2);
CardMax ++;
CardNum ++;
I2C_Write_AT24C64(0x00,0x1f,&CardMax,1);
DelCount = 0;//延时10ms
while(DelCount < 2);
I2C_Write_AT24C64(0x00,0x1e,&CardNum,1);
}
else if(CardMax > CardNum){//在CardMax范围内找空间存储
for(EEAddr = 0x0000;EEAddr < 0x0000 + CardMax * 0x20;EEAddr += 0x20){//读出卡号和存储器中的卡号进行比较
I2C_Read_AT24C64(EAddrH,EAddrL,12);
if(RD24C64[0] == 0){
I2C_Write_AT24C64(EAddrH,EAddrL,&Sto,1);//存入标志位,表示此页已存入卡号
DelCount = 0;//延时10ms
while(DelCount < 2);
I2C_Write_AT24C64(EAddrH,EAddrL + 1,CardNo,11);//存入11位卡号
CardNum ++;
DelCount = 0;//延时10ms
while(DelCount < 2);
I2C_Write_AT24C64(0x00,0x1e,&CardNum,1);
break;
}
}
}
LCD_Page_Clear(4);//清除4,5页的显示内容
LCD_Data_DisWord(34,4,cun);//显示“存入成功”
LCD_Data_DisWord(46,4,ru);
LCD_Data_DisWord(58,4,cheng);
LCD_Data_DisWord(70,4,gong);
}
DelCount = 0;//延时2s
StoreFlag = 0;
TimeDisFlag = 0;//返回后继续显示时间,时间显示标志为清零
while(DelCount < 400);
LCD_All_Clear();//清全屏
}
if(DeleteFlag){//删除
I2C_Read_AT24C64(0x00,0x1e,1);
CardNum = RD24C64[0];
if(CardNum != 0){
I2C_Write_AT24C64(EAddrH,EAddrL,&Del,1);
DelCount = 0;//延时10ms
while(DelCount < 2);
CardNum --;//删除一张卡后卡的数量减1
I2C_Write_AT24C64(0x00,0x1e,&CardNum,1);//存入标志位,表示此页已存入卡号
LCD_Page_Clear(4);//清除4,5页的显示内容
LCD_Data_DisWord(34,4,shan);//显示“删除成功”
LCD_Data_DisWord(46,4,chu);
LCD_Data_DisWord(58,4,cheng);
LCD_Data_DisWord(70,4,gong);
DelCount = 0;//延时2s
while(DelCount < 400);
}
DeleteFlag = 0;
SwitchFlag = 0;
TimeDisFlag = 0;//返回后继续显示时间,时间显示标志为清零
LCD_All_Clear();//清全屏
}
NSK12Flag = 0;
WXFlag = 0;
break;
case 4:if(StoreFlag || DeleteFlag){
TimeDisFlag = 0;//推出存储或删除,显示时间
StoreFlag = 0;
WXFlag = 0;
DeleteFlag = 0;
NSK12Flag = 0;
SwitchFlag = 0;
LCD_All_Clear();//清全屏
}
break;
default:break;
}
Function = 0;
}
void TimeInit(void){//定时器,串口初始化(定时器1作为波特率发生器[9600BPS],定时器0作为程序中的延时)
TMOD = 0x21;//定时器0,工作方式1,定时器1,工作方式2
TH0 = 0xec;//定时器赋初值:5ms
TL0 = 0x78;
TR0 = 1;//启动定时器0
ET0 = 1;//开定时器0中断
TH1 = 0xfd;//波特率发生器:9600BPS
TL1 = 0xfd;
TR1 = 1;
SCON = 0x50;//串行工作方式1,允许接收
PCON = 0x00;//SMOD = 0
ES = 1;//开串行通信中断
EA = 1;//开中断总开关
}
门禁系统驱动程序51单片 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)