久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

專注電子技術學習與研究
當前位置:單片機教程網 >> MCU設計實例 >> 瀏覽文章

門禁系統項目驅動程序(51單片機)

作者:佚名   來源:本站原創   點擊數:  更新時間:2013年03月26日   【字體:

/*****************************************************************************
   門禁系統項目驅動程序

 (1)晶振 11.0592MHZ
 (2)芯片 DS1302,AT24C64,HEF4053BP
 (3)ZIMO21.EXE縱向、字節倒序取字模
(4)完整代碼下載(包含頭文件):http://www.zg4o1577.cn/f/12154f.rar
*****************************************************************************/
#include "reg51.h"
#include "intrins.h"
#include "7041_Door.h"   //字模

#define LCD_DATA P1 //液晶屏數據輸入
#define EEAddr EAddr.All //AT24C64片內地址
#define EAddrH EAddr.array[0]
#define EAddrL EAddr.array[1]

#define uchar unsigned char
#define uint unsigned int

union Add{      //定義EEPROM地址
        uint All;
        uchar array[2];
}EAddr;

uchar Sto = 1,Del = 0;
uint DelCount;  //定時器中斷中用于延時的變量DelCount
uchar Function = 0; //按鍵功能變量Function
uchar SCount = 0; //串行中斷中用于計數卡號信息的循環變量
bit TimeDisFlag = 0,KEndFlag = 0,StoreFlag = 0,DeleteFlag = 0,SwitchFlag = 0,WXFlag = 0,NSK12Flag = 0; //控制時間顯示標志位TimeDisFlag,14位卡號接收完的標志KEndFlag
uchar CardNo[14] = {0},GetTime[7],RD24C64[32] = 0,CardMax = 0,CardNum = 0;//存儲讀到的卡號CardNo[14],存儲從1302讀到的時間GetTime[7],存入卡的個數CardMax

/*---------------------------------定義P口-----------------------------------*/

sbit LCD_RS = P2^7;  //LCD12864
sbit LCD_RW = P2^6;
sbit LCD_E = P2^5;
sbit LCD_CS1 = P2^4;
sbit LCD_CS2 = P2^3;
sbit Busy = P1^7;
sbit Motor2 = P3^7;
sbit Motor1 = P3^6;
sbit SDA_24C64 = P3^5; //AT24C64
sbit SCL_24C64 = P3^4;
sbit CLK_1302 = P2^2; //DS1302
sbit IO_1302 = P2^1;
sbit RST_1302 = P2^0;
sbit RS_485 = P3^2; //485R/S,其為1時允許發送,為0時允許接收
sbit CON_4053 = P3^3; //通信控制,其為1時讀卡,為0時485通信
sbit KEY1 = P0^0; //定義按鍵
sbit KEY2 = P0^1;
sbit KEY3 = P0^2;
sbit KEY4 = P0^3;

/***************************液晶屏驅動程序*********************************/

void LCD_BusyCheck(bit BCS){ //檢測忙子程序
 LCD_DATA = 0xff; //LCD_RS = 0,LCD_RW = 1,LCD_E = 高電平。
 LCD_RS = 0;
 LCD_RW = 1;
 if(BCS){  //檢測片1忙狀態
  LCD_CS1 = 1;
  LCD_E = 1;
  while(Busy);
  LCD_E = 0;
  LCD_CS1 = 0;
 }
 else{   //檢測片2忙狀態
  LCD_CS2 = 1;
  LCD_E = 1;
  while(Busy);
  LCD_E = 0;
  LCD_CS2 = 0;
 }
}
void LCD_Write_Code(uchar WCode,bit CS){//寫指令子程序
 LCD_BusyCheck(CS);  //調用忙檢測子程序:寫前檢測
 LCD_DATA = WCode;
 LCD_RS = 0; //LCD_RS = 0,LCD_RW = 0,LCD_E = 高脈沖。
 LCD_RW = 0;
 if(CS){   //檢測片1忙狀態
  LCD_CS1 = 1;
  LCD_E = 1;
  _nop_();
  LCD_E = 0;
  LCD_CS1 = 0;
 }
 else{   //檢測片2忙狀態
  LCD_CS2 = 1;
  LCD_E = 1;
  _nop_();
  LCD_E = 0;
  LCD_CS2 = 0;
 }
}
void LCD_Write_Data(uchar WData,uchar CS){ //寫數據子程序
 LCD_BusyCheck(CS);  //調用忙檢測子程序:寫前忙狀態檢測
 LCD_DATA = WData;
 LCD_RS = 1; //LCD_RS = 1,LCD_RW = 0,LCD_E = 高脈沖。
 LCD_RW = 0;
 if(CS){   //檢測片1忙狀態
  LCD_CS1 = 1;
  LCD_E = 1;
  _nop_();
  LCD_E = 0;
  LCD_CS1 = 0;
 }
 else{   //檢測片2忙狀態
  LCD_CS2 = 1;
  LCD_E = 1;
  _nop_();
  LCD_E = 0;
  LCD_CS2 = 0;
 }
}
void LCD_Write(uchar xpos,uchar ypos,uchar WData){//寫屏子(地址轉換)程序
 uchar WCS;
 if(xpos < 64) WCS = 1; //判斷將要操作片1或片2:WCS = 1操作LCD_CS1
 else  WCS = 0;  //WCS = 2 操作LCD_CS2
 ypos &= 0x07;   //頁地址轉換
 ypos |= 0xb8;
 LCD_Write_Code(ypos,WCS); //寫入頁地址到對應片
 xpos &= 0x3f;   //列地址轉換
 xpos |= 0x40;
 LCD_Write_Code(xpos,WCS); //寫入列地址到對應片
 LCD_Write_Data(WData,WCS); //寫入數據到對應片
}
void LCD_Data_DisWord(uchar xpos,uchar ypos,uchar array[]){//漢字顯示子程序:12*16
 uchar Cnt = 0,x = 0,y = 0;
 for(y = ypos;y < ypos + 2;y ++){
  for(x = xpos;x < xpos + 12;x ++,Cnt ++)
   LCD_Write(x,y,array[Cnt]); //調用寫屏子程序:在對應的地址上寫入要顯示的內容
 }
}
void LCD_Data_DisNum(uchar xpos,uchar ypos,uchar array[]){//數字及符號顯示子程序:6*16
 uchar Cnt = 0,x = 0,y = 0;
 for(y = ypos;y < ypos + 2;y ++){
  for(x = xpos;x < xpos + 6;x ++,Cnt ++)
   LCD_Write(x,y,array[Cnt]); //調用寫屏子程序:在對應的地址上寫入要顯示的內容
 }
}
void LCD_All_Clear(void){//清屏子程序:全屏清0
 uchar x,y;
 for(y = 0;y < 8;y ++)
  for(x = 0;x < 128;x ++)
   LCD_Write(x,y,0x00); //調用寫屏子程序:全屏寫0
}
void LCD_Page_Clear(uchar yPage){//清屏子程序:清除以所給頁坐標為起始的兩頁的內容
 uchar x,y;
 for(y = yPage;y < yPage + 2;y ++)
  for(x = 0;x < 128;x ++)
   LCD_Write(x,y,0x00); //調用寫屏子程序:以所給頁坐標為起始的兩頁寫0
}
void LCD_Reset(void){//液晶屏初始化設置
 LCD_E = 0;
 LCD_Write_Code(0x3f,1);  //開片1顯示
 LCD_Write_Code(0x3f,0);  //開片2顯示
 LCD_Write_Code(0xc0,1);  //設片1起始行顯示
 LCD_Write_Code(0xc0,0);  //設片2起始行顯示
}

/******************************DS1302時鐘程序*******************************/

void DS1302_WriteByte(uchar WData){    //寫入一個字節
 uchar Cnt;
    for(Cnt=0;Cnt<8;Cnt++){
         WData >>= 1; //寫入數據時先寫低位再寫高位(D0---D7)
         CLK_1302 = 0;
         IO_1302 = CY;
  CLK_1302 = 1;  //上升沿將數據寫入1302
    }
}
uchar DS1302_ReadByte(){       //讀出一個字節
    uchar Cnt,RData = 0;
        for(Cnt = 0;Cnt < 8;Cnt ++){
  RData >>= 1; //讀數據時先讀低位再讀高位(D0---D7)
                CLK_1302 = 1;
         CLK_1302 = 0;  //下降沿將數據讀出來
         if(IO_1302)
   RData |= 0x80;
  else RData &= 0x7f;
 }
 return RData;
}
void DS1302_WriteData(uchar Waddr,uchar Wdata){  //向某地址中寫入一個字節的數據
 RST_1302 = 0;
 CLK_1302 = 0;
 RST_1302 = 1;
 DS1302_WriteByte(Waddr);//寫入地址
 DS1302_WriteByte(Wdata);//寫入數據
 CLK_1302 = 0;
 RST_1302 = 0;
}
uchar DS1302_ReadData(uchar RAddr){   //讀取1302某地址中一個字節的數據
     uchar Rdata;
 RST_1302 = 0;
 CLK_1302 = 0;
 RST_1302 = 1;
 DS1302_WriteByte(RAddr); //寫入讀取數據的地址
 Rdata = DS1302_ReadByte(); //讀取數據
 RST_1302 = 0;
 IO_1302 = 1;
 return(Rdata);
}
void DS1302_SetTime(){      //設置1302時間
      uchar Cnt,Add = 0x80;//秒 寄存器的寫地址0x80
        // 秒   分   時   日   月 星期 年
 uchar STime[7] = {0x00,0x19,0x14,0x18,0x07,5,0x08};

      DS1302_WriteData(0x8e,0x00); //禁止寫保護(可寫入數據)
      for(Cnt = 0;Cnt < 7;Cnt ++,Add += 2)//循環寫入秒,分,時,日,月,星期,年
       DS1302_WriteData(Add,STime[Cnt]);
     DS1302_WriteData(0x8e,0x80); //寫保護(不能寫入數據)
}
void DS1302_GetTime(){    //讀取1302中當前時間
 uchar Cnt,Addr = 0x81;//秒 寄存器的讀地址0x81
   for(Cnt = 0;Cnt < 7;Cnt ++,Addr += 2)//循環讀取秒,分,時,日,月,星期,年
    GetTime[Cnt] = DS1302_ReadData(Addr);
}

/**************************液晶屏顯示程序******************************/

void LCD_DisTime(){  //顯示從1302讀取的時間
 DS1302_GetTime();
 LCD_Data_DisNum(32,0,num[GetTime[6] >> 4]); //年(由1302循環讀出顯示)
 LCD_Data_DisNum(38,0,num[GetTime[6] & 0x0f]);
        LCD_Data_DisNum(50,0,num[GetTime[4] >> 4]); //月
 LCD_Data_DisNum(56,0,num[GetTime[4] & 0x0f]);
 LCD_Data_DisNum(68,0,num[GetTime[3] >> 4]); //日
        LCD_Data_DisNum(74,0,num[GetTime[3] & 0x0f]);
 LCD_Data_DisNum(122,0,num[GetTime[5]]); //星期
 LCD_Data_DisNum(32,2,num[GetTime[2] >> 4]); //時
 LCD_Data_DisNum(38,2,num[GetTime[2] & 0x0f]);
        LCD_Data_DisNum(50,2,num[GetTime[1] >> 4]); //分
 LCD_Data_DisNum(56,2,num[GetTime[1] & 0x0f]);
 LCD_Data_DisNum(68,2,num[GetTime[0] >> 4]); //秒
        LCD_Data_DisNum(74,2,num[GetTime[0] & 0x0f]);
}
void LCD_DisCell(){//顯示固定不變的內容(日期,時間等漢字及符號的顯示)(圖1~4)
 LCD_Data_DisWord(2,0,ri);
 LCD_Data_DisWord(14,0,qi);
        LCD_Data_DisNum(26,0,maohao);
        LCD_Data_DisNum(44,0,heng);
        LCD_Data_DisNum(62,0,heng);
        LCD_Data_DisWord(92,0,xing);
 LCD_Data_DisWord(104,0,qi);
 LCD_Data_DisNum(116,0,maohao);
        LCD_Data_DisWord(2,2,shi);
 LCD_Data_DisWord(14,2,jian);
        LCD_Data_DisNum(26,2,maohao);
        LCD_Data_DisNum(44,2,heng);
        LCD_Data_DisNum(62,2,heng);
}
void LCD_Display1(){  //無操作狀態時顯示內容
 LCD_DisCell();
        LCD_Data_DisWord(34,4,wu); //無操作狀態
 LCD_Data_DisWord(46,4,cao);
 LCD_Data_DisWord(58,4,zuo);
 LCD_Data_DisWord(70,4,zhuang);
 LCD_Data_DisWord(82,4,tai);
}
void LCD_Display2(){ //刷卡后顯示此卡有效或無效
        LCD_Data_DisWord(2,4,ka); //顯示刷卡后的卡號
 LCD_Data_DisWord(14,4,hao);
 LCD_Data_DisNum(26,4,maohao);
}
void LCD_Display3(){ //顯示電機狀態:打開或關閉
 //LCD_DisCell();  //顯示固定不變的內容
        LCD_Data_DisWord(2,4,dian); //電機狀態
 LCD_Data_DisWord(14,4,ji);
 LCD_Data_DisWord(26,4,zhuang);
 LCD_Data_DisWord(38,4,tai);
 LCD_Data_DisNum(50,4,maohao);
}
void LCD_Display4(){  //顯示數據上傳過程:上傳成功或失敗
        LCD_Data_DisWord(2,4,shu); //數據上傳
 LCD_Data_DisWord(14,4,ju);
 LCD_Data_DisWord(26,4,shang);
 LCD_Data_DisWord(38,4,chuan);
 LCD_Data_DisNum(50,4,maohao);

 LCD_Data_DisWord(56,4,kuang1);
 LCD_Data_DisWord(68,4,kuang1);
 LCD_Data_DisWord(80,4,kuang1);
 LCD_Data_DisWord(92,4,kuang1);
 LCD_Data_DisWord(104,4,kuang1);
 LCD_Data_DisWord(116,4,kuang1);

  LCD_Data_DisWord(35,6,cheng);
  LCD_Data_DisWord(47,6,gong);

  LCD_Data_DisWord(75,6,shibai);
  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);
}

/******************************AT24C64存儲程序*******************************/

void I2C_Start(void){ //I2C總線啟動
 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;
  else RData &= 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的地址初始化到首地址
}

/******************************按鍵控制程序*********************************/

void KeyScan(){  //按鍵掃描
 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]);
            else LCD_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;
      else EEAddr -= 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]);
               else LCD_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]);
                else LCD_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]);
               else LCD_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;  //開中斷總開關
}

/***************************主程序******************************/

main(){
 uchar Cnt;
 bit ComFlag = 0;
 CON_4053 = 1;//允許讀卡
 Motor1 = 1; //電機正轉停止
 Motor2 = 1; //電機反轉停止
 TimeInit();  //定時器,串口初始化
 LCD_Reset();  //液晶屏初始化設置
 LCD_All_Clear(); //清全屏
 DS1302_SetTime(); //1302設置初始時間
 AT24C64Init(); //24C64初始化
 while(1){
  if(!TimeDisFlag){
   LCD_Display1();
          LCD_DisTime();
  }
         KeyScan(); //按鍵掃描
         KeyFunc(); //按鍵功能分配
         if(KEndFlag){  //卡號接收完畢
          //KEndFlag = 0;
          LCD_Page_Clear(4);//清除4,5頁的顯示內容
          LCD_Display2();
          for(Cnt = 1;Cnt < 11;Cnt ++){ //顯示讀取的卡號
           if(CardNo[Cnt] >= 0x40)
            LCD_Data_DisNum(32 + Cnt * 6,4,num[CardNo[Cnt]-0x40+10]);
           else LCD_Data_DisNum(32 + Cnt * 6,4,num[CardNo[Cnt]-0x30]);
          }
                        Cnt = 0;//顯示卡號后Cnt已經是11,故先清零,以便下邊比較卡號時使用Cnt == 11
          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){ //一組數據比較過程中全部相等時,顯示有效并推出比較
            ComFlag = 1;//比較后的卡號相同
            LCD_Data_DisWord(70,6,you); //顯示“有效”
     LCD_Data_DisWord(82,6,xiao);
     DelCount = 0; //延時100ms
     while(DelCount < 20);
     LCD_Page_Clear(4);//清除4,5頁的顯示內容
     LCD_Page_Clear(6);//清除6,7頁的顯示內容
     break;
           }
          }
          LCD_DisTime(); //若比較卡號時耗時較長,及時讀取時間顯示
          if(!ComFlag){ //比較無此卡號時顯示“無效”
    LCD_Data_DisWord(100,6,wu);
    LCD_Data_DisWord(112,6,xiao);
    DelCount = 0;
           while(1){
            LCD_DisTime(); //讀取時間顯示
            if(DelCount > 400){
             LCD_Page_Clear(4);//清除4,5頁的顯示內容
             LCD_Page_Clear(6);//清除6,7頁的顯示內容
             break;
            }
           }
          }
          if(ComFlag){
           LCD_Display3();
    LCD_Data_DisWord(60,4,da);
    LCD_Data_DisWord(72,4,kai);
    Motor1 = 0; //電機正轉
    DelCount = 0;
    while(1){ //電機正轉中
     LCD_DisTime(); //時間顯示
     if(DelCount > 600)
      break;
    }
    Motor1 = 1; //電機正轉停止
    LCD_Data_DisWord(60,4,guan);
    LCD_Data_DisWord(72,4,bi);
    DelCount = 0;
    while(1){ //等待人過去
     LCD_DisTime(); //時間顯示
     if(DelCount > 600)
      break;
    }
    Motor2 = 0; //電機反轉
    LCD_Data_DisWord(60,4,da);
    LCD_Data_DisWord(72,4,kai);
    DelCount = 0;
    while(1){ //電機反轉中
     LCD_DisTime(); //時間顯示
     if(DelCount > 600)
      break;
    }
    Motor2 = 1; //電機反轉停止
    DelCount = 0;
    LCD_Data_DisWord(60,4,guan);
    LCD_Data_DisWord(72,4,bi);
    while(1){ //門關上上后延時2s
     LCD_DisTime(); //時間顯示
     if(DelCount > 400)
      break;
    }
    LCD_Page_Clear(4);
    LCD_Page_Clear(6);
          }
          ComFlag = 0;
          KEndFlag = 0;
         }
 }
}
void Serial() interrupt 4{ //串行中斷入口地址
 if(RI){
  CardNo[SCount] = SBUF;
  RI = 0;
  SCount ++;
  if(SCount == 14){
   KEndFlag = 1;
   SCount = 0;
  }
 }
}
void Time0() interrupt 1{ //定時器0入口地址
 TH0 = 0xec; // 5ms
 TL0 = 0x78;
 DelCount ++;
}
 

關閉窗口

相關文章

主站蜘蛛池模板: 亚洲一区视频 | 日本三级精品 | 国产小视频在线观看 | 国产区精品视频 | 亚洲精品一区二区三区在线观看 | 狠狠色综合久久丁香婷婷 | 亚洲 欧美 激情 另类 校园 | 欧美专区在线 | 国产精品爱久久久久久久 | 91伊人 | 国产欧美精品区一区二区三区 | 欧美日韩综合 | 欧美成人精品 | 亚洲情侣视频 | 精品国产乱码久久久久久1区2区 | 国产一区二区三区在线 | 一级黄色影片在线观看 | 黄色一级大片在线免费看产 | 神马久久久久久久久久 | 91大神xh98xh系列全部 | 国产精品免费一区二区三区四区 | 91社区视频 | 色婷婷久久 | 在线a视频网站 | 日韩国产中文字幕 | 欧美xxxx网站 | 日韩网站在线观看 | 久久亚 | 欧美精品日韩精品国产精品 | 国产91精品在线 | 日韩欧美在线观看视频网站 | 亚洲精品在线视频 | 超碰导航| 黄色在线观看网站 | 一区二区福利视频 | 亚洲精品一区二三区不卡 | 欧美视频成人 | 最新中文字幕在线 | www.国产.com| 九九久久久 | 免费视频二区 |