亚洲春色中文字幕久久久-三上亚,一吻二脱三床四吻胸,国产真实伦对白视频全集,在线毛片观看,精品成品入口黄网,国产毛aⅴ片久久久,亚洲AV色香蕉一区二区三区老师,萧皇后A级艳片,色情日本视频更新,99久久亚洲精品日本无码

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3854|回復: 8
收起左側

跪求大神給看看1602不顯示是怎么回事啊

[復制鏈接]
ID:306099 發表于 2018-4-23 21:38 | 顯示全部樓層 |閱讀模式
//包含頭文件
#include <REG52.h>
#include<intrins.h>
//宏定義
#define LCM_Data  P0    //將P0口定義為LCM_Data
#define uchar unsigned char
#define uint  unsigned int
//1602的控制腳
sbit lcd1602_rs=P2^7;
sbit lcd1602_rw=P2^6;
sbit lcd1602_en=P2^5;
sbit Scl=P3^4;   //24C02串行時鐘
sbit Sda=P3^5;   //24C02串行數據
sbit ALAM = P2^3;  //報警
sbit KEY = P3^6;  //開鎖
bit  pass=0;   //密碼正確標志
bit  ReInputEn=0;  //重置輸入允許標志
bit  s3_keydown=0;  //3秒按鍵標志位
bit  key_disable=0;  //鎖定鍵盤標志
unsigned char countt0,second; //t0中斷計數器,秒計數器
void Delay5Ms(void);  //聲明延時函數
unsigned char code a[]={0xFE,0xFD,0xFB,0xF7};     //控盤掃描控制表
//液晶顯示數據數組
unsigned char code start_line[] = {"password:       "};
unsigned char code name[]    = {"===Coded Lock==="}; //顯示名稱
unsigned char code Correct[]  = {"     correct    "};  //輸入正確
unsigned char code Error[]    = {"      error     "};   //輸入錯誤
unsigned char code codepass[] = {"      pass      "};
unsigned char code LockOpen[] = {"      open      "};  //OPEN
unsigned char code SetNew[]  = {"SetNewWordEnable"};
unsigned char code Input[]    = {"input:          "};  //INPUT
unsigned char code ResetOK[]  = {"ResetPasswordOK "};
unsigned char code initword[] = {"Init password..."};
unsigned char code Er_try[]  = {"error,try again!"};
unsigned char code again[]  = {"input again     "};
unsigned char InputData[6];         //輸入密碼暫存區
unsigned char CurrentPassword[6]={1,3,1,4,2,0};    //管理員密碼(只可在程序中修改)
unsigned char TempPassword[6];
unsigned char N=0;    //密碼輸入位數記數
unsigned char ErrorCont;   //錯誤次數計數
unsigned char CorrectCont;   //正確輸入計數
unsigned char ReInputCont;    //重新輸入計數
unsigned char code initpassword[6]={0,0,0,0,0,0};   //輸入管理員密碼后將密碼初始為000000

//=====================5ms延時==============================
void Delay5Ms(void)
{
unsigned int TempCyc = 5552;
while(TempCyc--);
}
//===================400ms延時==============================
void Delay400Ms(void)
{
unsigned char TempCycA = 5;
unsigned int TempCycB;
while(TempCycA--)
{
  TempCycB=7269;
  while(TempCycB--);
}
}
//=============================================================================================
//================================24C02========================================================
//=============================================================================================
void mDelay(uint t) //延時
{
uchar i;
    while(t--)
    {
     for(i=0;i<125;i++)
     {;}
    }
}
   
void Nop(void)    //空操作
{
  _nop_();    //僅作延時用一條語句大約1us
  _nop_();
  _nop_();
  _nop_();
}
/*****24c02程序參照24c02時序圖*****/
/*起始條件*/
void Start(void)
{
  Sda=1;
  Scl=1;
  Nop();
  Sda=0;
  Nop();
}

/*停止條件*/
void Stop(void)
{
  Sda=0;
  Scl=1;
  Nop();
  Sda=1;
  Nop();
}
/*應答位*/
void Ack(void)
{
Sda=0;
Nop();
Scl=1;
Nop();
Scl=0;
}
/*反向應答位*/
void NoAck(void)
{
  Sda=1;
  Nop();
  Scl=1;
  Nop();
  Scl=0;
}
/*發送數據子程序,Data為要求發送的數據*/
void Send(uchar Data)
{
    uchar BitCounter=8;
    uchar temp;
    do
    {
     temp=Data;        //將待發送數據暫存temp
     Scl=0;
     Nop();
     if((temp&0x80)==0x80)     //將讀到的數據&0x80
     Sda=1;
     else
     Sda=0;
     Scl=1;
     temp=Data<<1;       //數據左移
     Data=temp;        //數據左移后重新賦值Data
     BitCounter--;       //該變量減到0時,數據也就傳送完成了
    }
    while(BitCounter);       //判斷是否傳送完成
    Scl=0;
}
/*讀一字節的數據,并返回該字節值*/
uchar Read(void)
{
    uchar temp=0;
uchar temp1=0;
uchar BitCounter=8;
Sda=1;
do
{
  Scl=0;
  Nop();
  Scl=1;
  Nop();
  if(Sda)       //數據位是否為1
   temp=temp|0x01;    //為1 temp的最低位為1(|0x01,就是將最低位變為1)
  else       //如果為0
   temp=temp&0xfe;    //temp最低位為0(&0xfe(11111110)最低位就是0)
  if(BitCounter-1)    //BitCounter減1后是否為真
  {
   temp1=temp<<1;    //temp左移
   temp=temp1;
  }
  BitCounter--;     //BitCounter減到0時,數據就接收完了
}
while(BitCounter);     //判斷是否接收完成
return(temp);
}
void WrToROM(uchar Data[],uchar Address,uchar Num)
{
  uchar i;
  uchar *PData;
  PData=Data;
  for(i=0;i<Num;i++)
  {
  Start();
  Send(0xa0);
  Ack();
  Send(Address+i);
  Ack();
  Send(*(PData+i));
  Ack();
  Stop();
  mDelay(20);
  }
}
void RdFromROM(uchar Data[],uchar Address,uchar Num)
{
  uchar i;
  uchar *PData;
  PData=Data;
  for(i=0;i<Num;i++)
  {
  Start();
  Send(0xa0);
  Ack();
  Send(Address+i);
  Ack();
  Start();
  Send(0xa1);
  Ack();
  *(PData+i)=Read();
  Scl=0;
  NoAck();
  Stop();
  }
}

//==================================================================================================
//=======================================LCD1602====================================================
//==================================================================================================
#define yi 0x80 //LCD第一行的初始位置,因為LCD1602字符地址首位D7恒定為1(100000000=80)
#define er 0x80+0x40 //LCD第二行初始位置(因為第二行第一個字符位置地址是0x40)

//----------------延時函數,后面經常調用----------------------
void delay(uint xms)//延時函數,有參函數
{
uint x,y;
for(x=xms;x>0;x--)
  for(y=110;y>0;y--);
}
//--------------------------寫指令---------------------------
void write_1602com(uchar com)//****液晶寫入指令函數****
{
lcd1602_rs=0;//數據/指令選擇置為指令
lcd1602_rw=0; //讀寫選擇置為寫
P0=com;//送入數據
delay(1);
lcd1602_en=1;//拉高使能端,為制造有效的下降沿做準備
delay(1);
lcd1602_en=0;//en由高變低,產生下降沿,液晶執行命令
}
//-------------------------寫數據-----------------------------
void write_1602dat(uchar dat)//***液晶寫入數據函數****
{
lcd1602_rs=1;//數據/指令選擇置為數據
lcd1602_rw=0; //讀寫選擇置為寫
P0=dat;//送入數據
delay(1);
lcd1602_en=1; //en置高電平,為制造下降沿做準備
delay(1);
lcd1602_en=0; //en由高變低,產生下降沿,液晶執行命令
}
//-------------------------初始化-------------------------
void lcd_init(void)
{
write_1602com(0x38);//設置液晶工作模式,意思:16*2行顯示,5*7點陣,8位數據
write_1602com(0x0c);//開顯示不顯示光標
write_1602com(0x06);//整屏不移動,光標自動右移
write_1602com(0x01);//清顯示
}
//========================================================================================
//=========================================================================================
//==============將按鍵值編碼為數值=========================
unsigned char coding(unsigned char m)  
{
unsigned char k;
switch(m)
{
  case (0x11): k=1;break;
  case (0x21): k=2;break;
  case (0x41): k=3;break;
  case (0x81): k='A';break;
  case (0x12): k=4;break;
  case (0x22): k=5;break;
  case (0x42): k=6;break;
  case (0x82): k='B';break;
  case (0x14): k=7;break;
  case (0x24): k=8;break;
  case (0x44): k=9;break;
  case (0x84): k='C';break;
  case (0x18): k='*';break;
  case (0x28): k=0;break;
  case (0x48): k='#';break;
  case (0x88): k='D';break;
}
return(k);
}
//=====================按鍵檢測并返回按鍵值===============================
unsigned char keynum(void)
{
  unsigned char row,col,i;
  P1=0xf0;
  if((P1&0xf0)!=0xf0)
  {
     Delay5Ms();
        Delay5Ms();
     if((P1&0xf0)!=0xf0)
  {
      row=P1^0xf0;          //確定行線
   i=0;
   P1=a[i];           //精確定位
   while(i<4)
   {
     if((P1&0xf0)!=0xf0)
      {
        col=~(P1&0xff);   //確定列線
        break;            //已定位后提前退出   
      }
    else
      {
        i++;
        P1=a[i];
      }
   }
  }
  else
  {
   return 0;
  }
  while((P1&0xf0)!=0xf0);
  return (row|col);    //行線與列線組合后返回
  }
  else return 0;            //無鍵按下時返回0
}
//=======================一聲提示音,表示有效輸入========================
void OneAlam(void)
{
ALAM=0;
Delay5Ms();
    ALAM=1;
}
//========================二聲提示音,表示操作成功========================
void TwoAlam(void)
{
ALAM=0;
Delay5Ms();
    ALAM=1;
    Delay5Ms();
ALAM=0;
Delay5Ms();
    ALAM=1;
}
//========================三聲提示音,表示錯誤========================
void ThreeAlam(void)
{
ALAM=0;
Delay5Ms();
    ALAM=1;
    Delay5Ms();
ALAM=0;
Delay5Ms();
    ALAM=1;
    Delay5Ms();
ALAM=0;
Delay5Ms();
    ALAM=1;
}
//=======================顯示提示輸入=========================
void DisplayChar(void)
{
unsigned char i;
if(pass==1)
{
  //DisplayListChar(0,1,LockOpen);
  write_1602com(er);       //在二行開始顯示
  for(i=0;i<16;i++)
  {
   write_1602dat(LockOpen[i]);    //顯示open 開鎖成功
  }
}
else
{
  if(N==0)
  {
   //DisplayListChar(0,1,Error);
   write_1602com(er);
   for(i=0;i<16;i++)
   {
    write_1602dat(Error[i]); //顯示錯誤
   }
  }
  else
  {
   //DisplayListChar(0,1,start_line);
   write_1602com(er);
   for(i=0;i<16;i++)
   {
    write_1602dat(start_line[i]);//顯示開始輸入
   }
  }
}
}
//========================重置密碼==================================================
//==================================================================================
void ResetPassword(void)
{
unsigned char i;
unsigned char j;
if(pass==0)
{
  pass=0;      
  DisplayChar();    //顯示錯誤
  ThreeAlam();    //沒開鎖時按下重置密碼報警3聲
}
else       //開鎖狀態下才能進行密碼重置程序
{
     if(ReInputEn==1)   //開鎖狀態下,ReInputEn置1,重置密碼允許
  {
   if(N==6)    //輸入6位密碼
   {
    ReInputCont++;   //密碼次數計數
    if(ReInputCont==2)  //輸入兩次密碼
    {
     for(i=0;i<6;)
     {
      if(TempPassword[i]==InputData[i]) //將兩次輸入的新密碼作對比
       i++;
      else        //如果兩次的密碼不同
      {
       //DisplayListChar(0,1,Error);
       write_1602com(er);
       for(j=0;j<16;j++)
       {
        write_1602dat(Error[j]); //顯示錯誤Error
       }
       ThreeAlam();   //錯誤提示
       pass=0;     //關鎖
       ReInputEn=0;   //關閉重置功能,
       ReInputCont=0;
       DisplayChar();
       break;
      }
     }
     if(i==6)
     {
      //DisplayListChar(0,1,ResetOK);
      write_1602com(er);
      for(j=0;j<16;j++)
      {
       write_1602dat(ResetOK[j]);   //密碼修改成功,顯示
      }
      TwoAlam();    //操作成功提示
       WrToROM(TempPassword,0,6);  //將新密碼寫入24C02存儲
      ReInputEn=0;
     }
     ReInputCont=0;
     CorrectCont=0;
    }
    else       //輸入一次密碼時
    {
     OneAlam();
     //DisplayListChar(0, 1, again);   //顯示再次輸入一次
     write_1602com(er);
     for(j=0;j<16;j++)
     {
      write_1602dat(again[j]);   //顯示再輸入一次
     }     
     for(i=0;i<6;i++)
     {
      TempPassword[i]=InputData[i];  //將第一次輸入的數據暫存起來      
     }
    }
   N=0;      //輸入數據位數計數器清零
     }
     }
}
}
//=======================輸入密碼錯誤超過三過,報警并鎖死鍵盤======================
void Alam_KeyUnable(void)
{
P1=0x00;
{
  ALAM=~ALAM;     //蜂鳴器一直閃爍鳴響
  Delay5Ms();
}
}
//=======================取消所有操作============================================
void Cancel(void)
{
unsigned char i;
unsigned char j;
//DisplayListChar(0, 1, start_line);
write_1602com(er);
for(j=0;j<16;j++)
{
  write_1602dat(start_line[j]);   //顯示開機輸入密碼界面
}
TwoAlam();    //提示音
for(i=0;i<6;i++)
{
  InputData[i]=0;  //將輸入密碼清零
}
KEY=1;     //關閉鎖
ALAM=1;     //報警關
pass=0;     //密碼正確標志清零
ReInputEn=0;   //重置輸入充許標志清零
ErrorCont=0;   //密碼錯誤輸入次數清零
CorrectCont=0;   //密碼正確輸入次數清零
ReInputCont=0;   //重置密碼輸入次數清零
s3_keydown=0;
key_disable=0;   //鎖定鍵盤標志清零
N=0;     //輸入位數計數器清零
}
//==========================確認鍵,并通過相應標志位執行相應功能===============================
void Ensure(void)
{
unsigned char i,j;
RdFromROM(CurrentPassword,0,6);      //從24C02里讀出存儲密碼
    if(N==6)
{
     if(ReInputEn==0)       //重置密碼功能未開啟
  {
   for(i=0;i<6;)
      {     
    if(CurrentPassword[i]==InputData[i]) //判斷輸入密碼和24c02中的密碼是否相同
    {
     i++;        //相同一位 i就+1
    }
    else          //如果有密碼不同
    {         
     ErrorCont++;      //錯誤次數++
     if(ErrorCont==3)   //錯誤輸入計數達三次時,報警并鎖定鍵盤
     {
      write_1602com(er);
      for(i=0;i<16;i++)
      {
       write_1602dat(Error[i]);
      }
      do
      Alam_KeyUnable();
      while(1);
     }
     else      //錯誤次數小于3次時,鎖死鍵盤3秒,然后重新可以輸入
     {
      TR0=1;    //開啟定時
      key_disable=1;   //鎖定鍵盤
      pass=0;     //pass位清零
      break;     //跳出
     }
    }
   }
   if(i==6)      //密碼輸入對時
   {
    CorrectCont++;     //輸入正確變量++
    if(CorrectCont==1)    //正確輸入計數,當只有一次正確輸入時,開鎖
    {
     //DisplayListChar(0,1,LockOpen);
     write_1602com(er);
     for(j=0;j<16;j++)
     {
      write_1602dat(LockOpen[j]);    //顯示open開鎖畫面
     }
     TwoAlam();   //操作成功提示音
     KEY=0;           //開鎖
     pass=1;           //置正確標志位
     TR0=1;           //開啟定時
     for(j=0;j<6;j++)        //將輸入清除
     {
      InputData[i]=0;        //開鎖后將輸入位清零
     }
    }
    else            //當兩次正確輸入時,開啟重置密碼功能
    {
     //DisplayListChar(0,1,SetNew);
     write_1602com(er);
     for(j=0;j<16;j++)
     {
      write_1602dat(SetNew[j]);     //顯示重置密碼界面
     }
     TwoAlam();             //操作成功提示
     ReInputEn=1;         //允許重置密碼輸入
     CorrectCont=0;         //正確計數器清零
    }
     }

   else   //=========================當第一次使用或忘記密碼時可以用131420對其密碼初始化============
   {
    if((InputData[0]==1)&&(InputData[1]==3)&&(InputData[2]==1)&&(InputData[3]==4)&&(InputData[4]==2)&&(InputData[5]==0))
       {
     WrToROM(initpassword,0,6);     //強制將初始密碼寫入24C02存儲
     //DisplayListChar(0,1,initword);   //顯示初始化密碼
     write_1602com(er);
     for(j=0;j<16;j++)
     {
      write_1602dat(initword[j]);    //顯示初始化密碼
     }
     TwoAlam();         //成功提示音
     Delay400Ms();        //延時400ms
     TwoAlam();         //成功提示音
     N=0;          //輸入位數計數器清零
    }
    else           //密碼輸入錯誤
    {
     //DisplayListChar(0,1,Error);
     write_1602com(er);
     for(j=0;j<16;j++)
     {
      write_1602dat(Error[j]);     //顯示錯誤信息
     }
      ThreeAlam();          //錯誤提示音
     pass=0;
    }
   }
  }
  else           //當已經開啟重置密碼功能時,而按下開鎖鍵,
  {
   //DisplayListChar(0,1,Er_try);
   write_1602com(er);
   for(j=0;j<16;j++)
   {
    write_1602dat(Er_try[j]);     //錯誤,請重新輸入
   }
   ThreeAlam();         //錯誤提示音
  }
}
else       //密碼沒有輸入到6位時,按下確認鍵時
{
  //DisplayListChar(0,1,Error);
  write_1602com(er);
  for(j=0;j<16;j++)
  {
   write_1602dat(Error[j]);   //顯示錯誤
  }
   ThreeAlam();          //錯誤提示音
  pass=0;
}

N=0;             //將輸入數據計數器清零,為下一次輸入作準備
}

//==============================主函數===============================
void main(void)
{
  unsigned char KEY,NUM;
unsigned char i,j;
  P1=0xFF;        //P1口復位
TMOD=0x11;       //定義工作方式
  TL0=0xB0;
  TH0=0x3C;       //定時器賦初值
  EA=1;        //打開中斷總開關
  ET0=1;        //打開中斷允許開關
  TR0=0;        //打開定時器開關
  Delay400Ms();  //啟動等待,等LCM講入工作狀態
  lcd_init();  //LCD初始化
write_1602com(yi);//日歷顯示固定符號從第一行第0個位置之后開始顯示
for(i=0;i<16;i++)
{
  write_1602dat(name[i]);//向液晶屏寫開機畫面
}
write_1602com(er);
for(i=0;i<16;i++)
{
  write_1602dat(start_line[i]);//寫輸入密碼等待界面
}
write_1602com(er+9); //設置光標位置
write_1602com(0x0f); //設置光標為閃爍
  Delay5Ms(); //延時片刻(可不要)
  N=0;              //初始化數據輸入位數
  while(1)   //進入循環
  {
  if(key_disable==1)      //鎖定鍵盤標志為1時
   Alam_KeyUnable();     //報警鍵盤鎖
  else
   ALAM=1;        //關報警
  KEY=keynum();       //讀按鍵的位置碼
  if(KEY!=0)        //當有按鍵按下時
  {
   if(key_disable==1)     //鎖定鍵盤標志為1時
   {
    second=0;      //秒清零
   }
   else        //沒有鎖定鍵盤時
   {
    NUM=coding(KEY);    //根據按鍵的位置將其編碼,編碼值賦值給NUM
    {
     switch(NUM)     //判斷按鍵值
     {
      case ('A'):  ;      break;
      case ('B'):  ;         break;
      case ('C'):
         write_1602com(yi);//日歷顯示固定符號從第一行第0個位置之后開始顯示
         for(i=0;i<16;i++)
         {
          write_1602dat(name[i]);//向液晶屏寫開機畫面
         }
         if(N>=1) N--; OneAlam();        //按鍵提示音      
         //DisplayOneChar(6+N,1,'*');
         for(j=N;j<16;j++)
         {
          write_1602com(er+6+j);
          write_1602dat(' ');
         }
         for(j=0;j<N;j++)
         {
          write_1602com(er+6+j);    //顯示位數隨輸入增加而增加
          write_1602dat('*');     //但不顯示實際數字,用*代替
         }  
         InputData[N]=N+4;
         break;  //ABC是無定義按鍵
      case ('D'): ResetPassword();  break;      //重新設置密碼
      case ('*'): Cancel();    break;      //取消當前輸入
      case ('#'): Ensure();     break;    //確認鍵,
      default:           //如果不是功能鍵按下時,就是數字鍵按下
      {
       //DisplayListChar(0,1,Input);
       if(N<6)                        //當輸入的密碼少于6位時,接受輸入并保存,大于6位時則無效。
       {
        write_1602com(er);
        for(i=0;i<16;i++)
        {
         write_1602dat(Input[i]);    //顯示輸入畫面
        }
        OneAlam();        //按鍵提示音
         for(j=0;j<=N;j++)
        {
         write_1602com(er+6+j);    //顯示位數隨輸入增加而增加
         write_1602dat('*');     //但不顯示實際數字,用*代替
        }
        InputData[N]=NUM;      //將數字鍵的碼賦值給InputData[]數組暫存
        N++;         //密碼位數加
       }
       else          //輸入數據位數大于6后,忽略輸入
       {
        N=6;         //密碼輸入大于6位時,不接受輸入
         break;
       }
      }
     }
    }
   }
   }
}
}
//*********************************中斷服務函數**************************************
void  time0_int(void) interrupt 1      //定時器T0
{
  TL0=0xB0;
  TH0=0x3C;    //定時器重新賦初值
  //TR0=1;
  countt0++;      //計時變量加,加1次時50ms
   if(countt0==20)     //加到20次就是1s
    {
  countt0=0;     //變量清零
  second++;     //秒加
  if(pass==1)     //開鎖狀態時
  {
   if(second==1)   //秒加到1s時
   {
    TR0=0;    //關定時器
    TL0=0xB0;
     TH0=0x3C;   //再次賦初值
    second=0;   //秒清零
   }
  }
  else      //不在開鎖狀態時
  {
   if(second==3)   //秒加到3時
   {
    TR0=0;    //關閉定時器
    second=0;   //秒清零
    key_disable=0;  //鎖定鍵盤清零
    s3_keydown=0;
    TL0=0xB0;
    TH0=0x3C;   //重新賦初值
   }
   else
       TR0=1;    //打開定時器
  }
   
    }
}

回復

使用道具 舉報

ID:306099 發表于 2018-4-23 22:34 | 顯示全部樓層
只顯示一排黑框 硬件沒問題 應該就是軟件的事  但是根本搞不懂啊 求大神指點一下
回復

使用道具 舉報

ID:111634 發表于 2018-4-24 08:30 | 顯示全部樓層
本帖最后由 zl2168 于 2018-4-24 08:32 編輯

給你一個正確有效案例,自己去對照鉆研吧!
實例67  LCD1602顯示屏顯示
實例61 LCD1602顯示屏顯示.rar (49.26 KB, 下載次數: 9)
1602.jpg
Proteus仿真一下,確認有效以上摘自張志良編著《80C51單片機仿真設計實例教程——基于Keil CProteus》清華大學出版社ISBN 978-7-302-41682-1。書中電路和程序設計有詳細說明,程序語句條條有注解。
回復

使用道具 舉報

ID:315067 發表于 2018-4-24 09:15 | 顯示全部樓層
有個調整亮度的RV1  你調整亮度看看
回復

使用道具 舉報

ID:314246 發表于 2018-4-24 09:31 | 顯示全部樓層
只顯示黑框,應該是液晶沒有正常初始化
回復

使用道具 舉報

ID:213173 發表于 2018-4-24 11:12 | 顯示全部樓層
只顯示一排黑塊說明1602初始化失敗,你把與顯示無關的所有代碼屏蔽,單獨調試1602,顯示正常后再逐步加入其它功能,我這樣試的可以正常顯示。 無標題.jpg

//包含頭文件
#include <REG52.h>
#include<intrins.h>
//宏定義
#define yi 0x80 //LCD第一行的初始位置,因為LCD1602字符地址首位D7恒定為1(100000000=80)
#define er 0x80+0x40 //LCD第二行初始位置(因為第二行第一個字符位置地址是0x40)
//#define LCM_Data  P0    //將P0口定義為LCM_Data
#define uchar unsigned char
#define uint  unsigned int
//1602的控制腳
sbit lcd1602_rs=P2^7;
sbit lcd1602_rw=P2^6;
sbit lcd1602_en=P2^5;

//sbit Scl=P3^4;   //24C02串行時鐘
//sbit Sda=P3^5;   //24C02串行數據
//sbit ALAM = P2^3;  //報警
//sbit KEY = P3^6;  //開鎖
//bit  pass=0;   //密碼正確標志
//bit  ReInputEn=0;  //重置輸入允許標志
//bit  s3_keydown=0;  //3秒按鍵標志位
//bit  key_disable=0;  //鎖定鍵盤標志
//unsigned char countt0,second; //t0中斷計數器,秒計數器
//void Delay5Ms(void);  //聲明延時函數
//unsigned char code a[]={0xFE,0xFD,0xFB,0xF7};     //控盤掃描控制表
//液晶顯示數據數組
unsigned char code start_line[] = {"password:       "};
unsigned char code name[]    = {"===Coded Lock==="}; //顯示名稱
//unsigned char code Correct[]  = {"     correct    "};  //輸入正確
//unsigned char code Error[]    = {"      error     "};   //輸入錯誤
//unsigned char code codepass[] = {"      pass      "};
//unsigned char code LockOpen[] = {"      open      "};  //OPEN
//unsigned char code SetNew[]  = {"SetNewWordEnable"};
//unsigned char code Input[]    = {"input:          "};  //INPUT
//unsigned char code ResetOK[]  = {"ResetPasswordOK "};
//unsigned char code initword[] = {"Init password..."};
//unsigned char code Er_try[]  = {"error,try again!"};
//unsigned char code again[]  = {"input again     "};
//unsigned char InputData[6];         //輸入密碼暫存區
//unsigned char CurrentPassword[6]={1,3,1,4,2,0};    //管理員密碼(只可在程序中修改)
//unsigned char TempPassword[6];
//unsigned char N=0;    //密碼輸入位數記數
//unsigned char ErrorCont;   //錯誤次數計數
//unsigned char CorrectCont;   //正確輸入計數
//unsigned char ReInputCont;    //重新輸入計數
//unsigned char code initpassword[6]={0,0,0,0,0,0};   //輸入管理員密碼后將密碼初始為000000
/*
//=====================5ms延時==============================
void Delay5Ms(void)
{
unsigned int TempCyc = 5552;
while(TempCyc--);
}
//===================400ms延時==============================
void Delay400Ms(void)
{
unsigned char TempCycA = 5;
unsigned int TempCycB;
while(TempCycA--)
{
  TempCycB=7269;
  while(TempCycB--);
}
}
//=============================================================================================
//================================24C02========================================================
//=============================================================================================
void mDelay(uint t) //延時
{
uchar i;
    while(t--)
    {
     for(i=0;i<125;i++)
     {;}
    }
}

void Nop(void)    //空操作
{
  _nop_();    //僅作延時用一條語句大約1us
  _nop_();
  _nop_();
  _nop_();
}
*/
/*****24c02程序參照24c02時序圖*****/
/*起始條件*/
/*
void Start(void)
{
  Sda=1;
  Scl=1;
  Nop();
  Sda=0;
  Nop();
}
*/
/*停止條件*/
/*
void Stop(void)
{
  Sda=0;
  Scl=1;
  Nop();
  Sda=1;
  Nop();
}
*/
/*應答位*/
/*
void Ack(void)
{
Sda=0;
Nop();
Scl=1;
Nop();
Scl=0;
}*/
/*反向應答位*/
/*
void NoAck(void)
{
  Sda=1;
  Nop();
  Scl=1;
  Nop();
  Scl=0;
}*/
/*發送數據子程序,Data為要求發送的數據*/
/*
void Send(uchar Data)
{
    uchar BitCounter=8;
    uchar temp;
    do
    {
     temp=Data;        //將待發送數據暫存temp
     Scl=0;
     Nop();
     if((temp&0x80)==0x80)     //將讀到的數據&0x80
     Sda=1;
     else
     Sda=0;
     Scl=1;
     temp=Data<<1;       //數據左移
     Data=temp;        //數據左移后重新賦值Data
     BitCounter--;       //該變量減到0時,數據也就傳送完成了
    }
    while(BitCounter);       //判斷是否傳送完成
    Scl=0;
}*/
/*讀一字節的數據,并返回該字節值*/
/*
uchar Read(void)
{
    uchar temp=0;
uchar temp1=0;
uchar BitCounter=8;
Sda=1;
do
{
  Scl=0;
  Nop();
  Scl=1;
  Nop();
  if(Sda)       //數據位是否為1
   temp=temp|0x01;    //為1 temp的最低位為1(|0x01,就是將最低位變為1)
  else       //如果為0
   temp=temp&0xfe;    //temp最低位為0(&0xfe(11111110)最低位就是0)
  if(BitCounter-1)    //BitCounter減1后是否為真
  {
   temp1=temp<<1;    //temp左移
   temp=temp1;
  }
  BitCounter--;     //BitCounter減到0時,數據就接收完了
}
while(BitCounter);     //判斷是否接收完成
return(temp);
}
void WrToROM(uchar Data[],uchar Address,uchar Num)
{
  uchar i;
  uchar *PData;
  PData=Data;
  for(i=0;i<Num;i++)
  {
  Start();
  Send(0xa0);
  Ack();
  Send(Address+i);
  Ack();
  Send(*(PData+i));
  Ack();
  Stop();
  mDelay(20);
  }
}
void RdFromROM(uchar Data[],uchar Address,uchar Num)
{
  uchar i;
  uchar *PData;
  PData=Data;
  for(i=0;i<Num;i++)
  {
  Start();
  Send(0xa0);
  Ack();
  Send(Address+i);
  Ack();
  Start();
  Send(0xa1);
  Ack();
  *(PData+i)=Read();
  Scl=0;
  NoAck();
  Stop();
  }
}
*/
//==================================================================================================
//=======================================LCD1602====================================================
//==================================================================================================


//----------------延時函數,后面經常調用----------------------
void delay(uint xms)//延時函數,有參函數
{
        uint x,y;
        for(x=xms;x>0;x--)
                for(y=110;y>0;y--);
}
//--------------------------寫指令---------------------------
void write_1602com(uchar com)//****液晶寫入指令函數****
{
        lcd1602_rs=0;//數據/指令選擇置為指令
        lcd1602_rw=0; //讀寫選擇置為寫
        P0=com;//送入數據
        delay(1);
        lcd1602_en=1;//拉高使能端,為制造有效的下降沿做準備
        delay(1);
        lcd1602_en=0;//en由高變低,產生下降沿,液晶執行命令
}
//-------------------------寫數據-----------------------------
void write_1602dat(uchar dat)//***液晶寫入數據函數****
{
        lcd1602_rs=1;//數據/指令選擇置為數據
        lcd1602_rw=0; //讀寫選擇置為寫
        P0=dat;//送入數據
        delay(1);
        lcd1602_en=1; //en置高電平,為制造下降沿做準備
        delay(1);
        lcd1602_en=0; //en由高變低,產生下降沿,液晶執行命令
}
//-------------------------初始化-------------------------
void lcd_init(void)
{
        write_1602com(0x38);//設置液晶工作模式,意思:16*2行顯示,5*7點陣,8位數據
        write_1602com(0x0c);//開顯示不顯示光標
        write_1602com(0x06);//整屏不移動,光標自動右移
        write_1602com(0x01);//清顯示
}
//========================================================================================
//=========================================================================================
//==============將按鍵值編碼為數值=========================
/*
unsigned char coding(unsigned char m)  
{
unsigned char k;
switch(m)
{
  case (0x11): k=1;break;
  case (0x21): k=2;break;
  case (0x41): k=3;break;
  case (0x81): k='A';break;
  case (0x12): k=4;break;
  case (0x22): k=5;break;
  case (0x42): k=6;break;
  case (0x82): k='B';break;
  case (0x14): k=7;break;
  case (0x24): k=8;break;
  case (0x44): k=9;break;
  case (0x84): k='C';break;
  case (0x18): k='*';break;
  case (0x28): k=0;break;
  case (0x48): k='#';break;
  case (0x88): k='D';break;
}
return(k);
}*/
//=====================按鍵檢測并返回按鍵值===============================
/*
unsigned char keynum(void)
{
  unsigned char row,col,i;
  P1=0xf0;
  if((P1&0xf0)!=0xf0)
  {
     Delay5Ms();
        Delay5Ms();
     if((P1&0xf0)!=0xf0)
  {
      row=P1^0xf0;          //確定行線
   i=0;
   P1=a;           //精確定位
   while(i<4)
   {
     if((P1&0xf0)!=0xf0)
      {
        col=~(P1&0xff);   //確定列線
        break;            //已定位后提前退出   
      }
    else
      {
        i++;
        P1=a;
      }
   }
  }
  else
  {
   return 0;
  }
  while((P1&0xf0)!=0xf0);
  return (row|col);    //行線與列線組合后返回
  }
  else return 0;            //無鍵按下時返回0
}
//=======================一聲提示音,表示有效輸入========================
void OneAlam(void)
{
        ALAM=0;
        Delay5Ms();
        ALAM=1;
}
//========================二聲提示音,表示操作成功========================
void TwoAlam(void)
{
        ALAM=0;
        Delay5Ms();
        ALAM=1;
        Delay5Ms();
        ALAM=0;
        Delay5Ms();
        ALAM=1;
}
//========================三聲提示音,表示錯誤========================
void ThreeAlam(void)
{
        ALAM=0;
        Delay5Ms();
        ALAM=1;
        Delay5Ms();
        ALAM=0;
        Delay5Ms();
        ALAM=1;
        Delay5Ms();
        ALAM=0;
        Delay5Ms();
        ALAM=1;
}
//=======================顯示提示輸入=========================
void DisplayChar(void)
{
        unsigned char i;
        if(pass==1)
        {
        //DisplayListChar(0,1,LockOpen);
                write_1602com(er);       //在二行開始顯示
                for(i=0;i<16;i++)
                {
                        write_1602dat(LockOpen);    //顯示open 開鎖成功
                }
        }
        else
        {
        if(N==0)
        {
        //DisplayListChar(0,1,Error);
        write_1602com(er);
        for(i=0;i<16;i++)
        {
        write_1602dat(Error); //顯示錯誤
        }
        }
        else
        {
        //DisplayListChar(0,1,start_line);
        write_1602com(er);
        for(i=0;i<16;i++)
        {
        write_1602dat(start_line);//顯示開始輸入
        }
        }
        }
}*/
//========================重置密碼==================================================
//==================================================================================
/*
void ResetPassword(void)
{
unsigned char i;
unsigned char j;
if(pass==0)
{
  pass=0;      
  DisplayChar();    //顯示錯誤
  ThreeAlam();    //沒開鎖時按下重置密碼報警3聲
}
else       //開鎖狀態下才能進行密碼重置程序
{
     if(ReInputEn==1)   //開鎖狀態下,ReInputEn置1,重置密碼允許
  {
   if(N==6)    //輸入6位密碼
   {
    ReInputCont++;   //密碼次數計數
    if(ReInputCont==2)  //輸入兩次密碼
    {
     for(i=0;i<6;)
     {
      if(TempPassword==InputData) //將兩次輸入的新密碼作對比
       i++;
      else        //如果兩次的密碼不同
      {
       //DisplayListChar(0,1,Error);
       write_1602com(er);
       for(j=0;j<16;j++)
       {
        write_1602dat(Error[j]); //顯示錯誤Error
       }
       ThreeAlam();   //錯誤提示
       pass=0;     //關鎖
       ReInputEn=0;   //關閉重置功能,
       ReInputCont=0;
       DisplayChar();
       break;
      }
     }
     if(i==6)
     {
      //DisplayListChar(0,1,ResetOK);
      write_1602com(er);
      for(j=0;j<16;j++)
      {
       write_1602dat(ResetOK[j]);   //密碼修改成功,顯示
      }
      TwoAlam();    //操作成功提示
       WrToROM(TempPassword,0,6);  //將新密碼寫入24C02存儲
      ReInputEn=0;
     }
     ReInputCont=0;
     CorrectCont=0;
    }
    else       //輸入一次密碼時
    {
     OneAlam();
     //DisplayListChar(0, 1, again);   //顯示再次輸入一次
     write_1602com(er);
     for(j=0;j<16;j++)
     {
      write_1602dat(again[j]);   //顯示再輸入一次
     }     
     for(i=0;i<6;i++)
     {
      TempPassword=InputData;  //將第一次輸入的數據暫存起來      
     }
    }
   N=0;      //輸入數據位數計數器清零
     }
     }
}
}
//=======================輸入密碼錯誤超過三過,報警并鎖死鍵盤======================
void Alam_KeyUnable(void)
{
P1=0x00;
{
  ALAM=~ALAM;     //蜂鳴器一直閃爍鳴響
  Delay5Ms();
}
}
//=======================取消所有操作============================================
void Cancel(void)
{
unsigned char i;
unsigned char j;
//DisplayListChar(0, 1, start_line);
write_1602com(er);
for(j=0;j<16;j++)
{
  write_1602dat(start_line[j]);   //顯示開機輸入密碼界面
}
TwoAlam();    //提示音
for(i=0;i<6;i++)
{
  InputData=0;  //將輸入密碼清零
}
KEY=1;     //關閉鎖
ALAM=1;     //報警關
pass=0;     //密碼正確標志清零
ReInputEn=0;   //重置輸入充許標志清零
ErrorCont=0;   //密碼錯誤輸入次數清零
CorrectCont=0;   //密碼正確輸入次數清零
ReInputCont=0;   //重置密碼輸入次數清零
s3_keydown=0;
key_disable=0;   //鎖定鍵盤標志清零
N=0;     //輸入位數計數器清零
}
//==========================確認鍵,并通過相應標志位執行相應功能===============================
void Ensure(void)
{
unsigned char i,j;
RdFromROM(CurrentPassword,0,6);      //從24C02里讀出存儲密碼
    if(N==6)
{
     if(ReInputEn==0)       //重置密碼功能未開啟
  {
   for(i=0;i<6;)
      {     
    if(CurrentPassword==InputData) //判斷輸入密碼和24c02中的密碼是否相同
    {
     i++;        //相同一位 i就+1
    }
    else          //如果有密碼不同
    {         
     ErrorCont++;      //錯誤次數++
     if(ErrorCont==3)   //錯誤輸入計數達三次時,報警并鎖定鍵盤
     {
      write_1602com(er);
      for(i=0;i<16;i++)
      {
       write_1602dat(Error);
      }
      do
      Alam_KeyUnable();
      while(1);
     }
     else      //錯誤次數小于3次時,鎖死鍵盤3秒,然后重新可以輸入
     {
      TR0=1;    //開啟定時
      key_disable=1;   //鎖定鍵盤
      pass=0;     //pass位清零
      break;     //跳出
     }
    }
   }
   if(i==6)      //密碼輸入對時
   {
    CorrectCont++;     //輸入正確變量++
    if(CorrectCont==1)    //正確輸入計數,當只有一次正確輸入時,開鎖
    {
     //DisplayListChar(0,1,LockOpen);
     write_1602com(er);
     for(j=0;j<16;j++)
     {
      write_1602dat(LockOpen[j]);    //顯示open開鎖畫面
     }
     TwoAlam();   //操作成功提示音
     KEY=0;           //開鎖
     pass=1;           //置正確標志位
     TR0=1;           //開啟定時
     for(j=0;j<6;j++)        //將輸入清除
     {
      InputData=0;        //開鎖后將輸入位清零
     }
    }
    else            //當兩次正確輸入時,開啟重置密碼功能
    {
     //DisplayListChar(0,1,SetNew);
     write_1602com(er);
     for(j=0;j<16;j++)
     {
      write_1602dat(SetNew[j]);     //顯示重置密碼界面
     }
     TwoAlam();             //操作成功提示
     ReInputEn=1;         //允許重置密碼輸入
     CorrectCont=0;         //正確計數器清零
    }
     }

   else   //=========================當第一次使用或忘記密碼時可以用131420對其密碼初始化============
   {
    if((InputData[0]==1)&&(InputData[1]==3)&&(InputData[2]==1)&&(InputData[3]==4)&&(InputData[4]==2)&&(InputData[5]==0))
       {
     WrToROM(initpassword,0,6);     //強制將初始密碼寫入24C02存儲
     //DisplayListChar(0,1,initword);   //顯示初始化密碼
     write_1602com(er);
     for(j=0;j<16;j++)
     {
      write_1602dat(initword[j]);    //顯示初始化密碼
     }
     TwoAlam();         //成功提示音
     Delay400Ms();        //延時400ms
     TwoAlam();         //成功提示音
     N=0;          //輸入位數計數器清零
    }
    else           //密碼輸入錯誤
    {
     //DisplayListChar(0,1,Error);
     write_1602com(er);
     for(j=0;j<16;j++)
     {
      write_1602dat(Error[j]);     //顯示錯誤信息
     }
      ThreeAlam();          //錯誤提示音
     pass=0;
    }
   }
  }
  else           //當已經開啟重置密碼功能時,而按下開鎖鍵,
  {
   //DisplayListChar(0,1,Er_try);
   write_1602com(er);
   for(j=0;j<16;j++)
   {
    write_1602dat(Er_try[j]);     //錯誤,請重新輸入
   }
   ThreeAlam();         //錯誤提示音
  }
}
else       //密碼沒有輸入到6位時,按下確認鍵時
{
  //DisplayListChar(0,1,Error);
  write_1602com(er);
  for(j=0;j<16;j++)
  {
   write_1602dat(Error[j]);   //顯示錯誤
  }
   ThreeAlam();          //錯誤提示音
  pass=0;
}

N=0;             //將輸入數據計數器清零,為下一次輸入作準備
}
*/
//==============================主函數===============================
void main()
{
//        unsigned char KEY,NUM;
        unsigned char i;//j;
//        P1=0xFF;        //P1口復位
//        TMOD=0x11;       //定義工作方式
//        TL0=0xB0;
//        TH0=0x3C;       //定時器賦初值
//        EA=1;        //打開中斷總開關
//        ET0=1;        //打開中斷允許開關
//        TR0=0;        //打開定時器開關
//        Delay400Ms();  //啟動等待,等LCM講入工作狀態
        lcd_init();  //LCD初始化
        write_1602com(yi);//日歷顯示固定符號從第一行第0個位置之后開始顯示
        for(i=0;i<16;i++)
        {
                write_1602dat(name);//向液晶屏寫開機畫面
        }
        write_1602com(er);
        for(i=0;i<16;i++)
        {
                write_1602dat(start_line);//寫輸入密碼等待界面
        }
        write_1602com(er+9); //設置光標位置
        write_1602com(0x0f); //設置光標為閃爍
//        Delay5Ms(); //延時片刻(可不要)
//        N=0;              //初始化數據輸入位數
  while(1)   //進入循環
  {
/*  if(key_disable==1)      //鎖定鍵盤標志為1時
   Alam_KeyUnable();     //報警鍵盤鎖
  else
   ALAM=1;        //關報警
  KEY=keynum();       //讀按鍵的位置碼
  if(KEY!=0)        //當有按鍵按下時
  {
   if(key_disable==1)     //鎖定鍵盤標志為1時
   {
    second=0;      //秒清零
   }
   else        //沒有鎖定鍵盤時
   {
    NUM=coding(KEY);    //根據按鍵的位置將其編碼,編碼值賦值給NUM
    {
     switch(NUM)     //判斷按鍵值
     {
      case ('A'):  ;      break;
      case ('B'):  ;         break;
      case ('C'):
         write_1602com(yi);//日歷顯示固定符號從第一行第0個位置之后開始顯示
         for(i=0;i<16;i++)
         {
          write_1602dat(name);//向液晶屏寫開機畫面
         }
         if(N>=1) N--; OneAlam();        //按鍵提示音      
         //DisplayOneChar(6+N,1,'*');
         for(j=N;j<16;j++)
         {
          write_1602com(er+6+j);
          write_1602dat(' ');
         }
         for(j=0;j<N;j++)
         {
          write_1602com(er+6+j);    //顯示位數隨輸入增加而增加
          write_1602dat('*');     //但不顯示實際數字,用*代替
         }  
         InputData[N]=N+4;
         break;  //ABC是無定義按鍵
      case ('D'): ResetPassword();  break;      //重新設置密碼
      case ('*'): Cancel();    break;      //取消當前輸入
      case ('#'): Ensure();     break;    //確認鍵,
      default:           //如果不是功能鍵按下時,就是數字鍵按下
      {
       //DisplayListChar(0,1,Input);
       if(N<6)                        //當輸入的密碼少于6位時,接受輸入并保存,大于6位時則無效。
       {
        write_1602com(er);
        for(i=0;i<16;i++)
        {
         write_1602dat(Input);    //顯示輸入畫面
        }
        OneAlam();        //按鍵提示音
         for(j=0;j<=N;j++)
        {
         write_1602com(er+6+j);    //顯示位數隨輸入增加而增加
         write_1602dat('*');     //但不顯示實際數字,用*代替
        }
        InputData[N]=NUM;      //將數字鍵的碼賦值給InputData[]數組暫存
        N++;         //密碼位數加
       }
       else          //輸入數據位數大于6后,忽略輸入
       {
        N=6;         //密碼輸入大于6位時,不接受輸入
         break;
       }
      }
     }
    }
   }
   }*/
        }
}
//*********************************中斷服務函數**************************************
/*
void  time0_int(void) interrupt 1      //定時器T0
{
  TL0=0xB0;
  TH0=0x3C;    //定時器重新賦初值
  //TR0=1;
  countt0++;      //計時變量加,加1次時50ms
   if(countt0==20)     //加到20次就是1s
    {
  countt0=0;     //變量清零
  second++;     //秒加
  if(pass==1)     //開鎖狀態時
  {
   if(second==1)   //秒加到1s時
   {
    TR0=0;    //關定時器
    TL0=0xB0;
     TH0=0x3C;   //再次賦初值
    second=0;   //秒清零
   }
  }
  else      //不在開鎖狀態時
  {
   if(second==3)   //秒加到3時
   {
    TR0=0;    //關閉定時器
    second=0;   //秒清零
    key_disable=0;  //鎖定鍵盤清零
    s3_keydown=0;
    TL0=0xB0;
    TH0=0x3C;   //重新賦初值
   }
   else
       TR0=1;    //打開定時器
  }

    }
}*/


回復

使用道具 舉報

ID:306099 發表于 2018-4-26 22:49 | 顯示全部樓層
wulin 發表于 2018-4-24 11:12
只顯示一排黑塊說明1602初始化失敗,你把與顯示無關的所有代碼屏蔽,單獨調試1602,顯示正常后再逐步加入其 ...

大神  你用的 什么牌子的開發板
回復

使用道具 舉報

ID:306099 發表于 2018-4-26 22:51 | 顯示全部樓層
zl2168 發表于 2018-4-24 08:30
給你一個正確有效案例,自己去對照鉆研吧!
實例67  LCD1602顯示屏顯示
先Proteus仿真一下,確認有效以上 ...

請問   自己怎么焊接1602外部電路  求指點
回復

使用道具 舉報

ID:213173 發表于 2018-4-27 06:22 | 顯示全部樓層
燒友分分分 發表于 2018-4-26 22:49
大神  你用的 什么牌子的開發板

是郭天祥的TX-1C開發板,除了rw固定接地,其他沒有差別。1602這部分與用什么開發板關系不大,關鍵是時序要正確,有的開發板使用了STC的1T單片機,速度快許多,不能直接套用這個程序,需要修改Delay延時參數。
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表