找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 4773|回復(fù): 14
打印 上一主題 下一主題
收起左側(cè)

我的萬年歷設(shè)計(jì)LCD無法顯示,仿真通過

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:89734 發(fā)表于 2015-11-29 14:14 | 只看該作者 |只看大圖 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
因?yàn)槲以O(shè)計(jì)的萬年歷還有測試溫度的功能,但是溫度是由另外一塊板無線傳輸過來的,我編寫了單單萬年歷的部分在PROTUES仿真可以工作,將這個(gè)單單萬年歷部分的代碼燒寫到單片機(jī)中卻無法在整個(gè)電路中工作(整個(gè)電路是指帶有無線模塊的電路)。請(qǐng)問我這樣的方法是不是不對(duì)。我測試了一下LCD的狀態(tài)是RS=5V.   RW=0V.     E=0V。
下面是萬年歷部分的代碼:
#include<reg51.h>
#include<intrins.h>
#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
uchar code digit[]={"0123456789"};     //定義字符數(shù)組顯示數(shù)字
uchar code Error[]="Error!Check!";     //說明沒有檢測到DS18B20
uchar code table[]="Alarm Clock";
uchar code table1[]="0123456789";
uchar code table2[]="WEEK";
uchar code table3[]="Today is fine!";
uchar code table4[]="HELLO!";
uchar code table5[]="Made by ";
uchar code table6[]="Happy new year!!";//1.1
//uchar code table7[]="Valentine's Day"; //2.14
/*******************************************************************************
以下是對(duì)液晶模塊的操作程序
*******************************************************************************/
sbit RS=P2^5;           //寄存器選擇位,將RS位定義為P2.0引腳
sbit RW=P2^6;           //讀寫選擇位,將RW位定義為P2.1引腳
sbit E=P2^7;            //使能信號(hào)位,將E位定義為P2.2引腳
sbit BF=P0^7;           //忙碌標(biāo)志位,,將BF位定義為P0.7引腳
sbit T_RST=P1^6;
sbit T_CLK=P1^4;               
sbit T_IO=P1^5;
sbit beep=P1^7;
sbit key1=P3^0;   //調(diào)鬧鐘的小時(shí)即x
sbit key2=P3^1;   //調(diào)鬧鐘的分鐘即y
sbit key4=P3^5;   //顯示切換
sbit key3=P3^2;
sbit ACC0=ACC^0;
sbit ACC7=ACC^7;
uchar time;   //設(shè)置全局變量,專門用于嚴(yán)格延時(shí)
static uchar x=0x08,y=30;
uchar t_sec,sec1,sec2;
uchar t_min,min1,min2;
uchar t_hour,hour1,hour2;
uchar t_mon,mon1,mon2;
uchar t_day,day1,day2;
uchar t_year,year1,year2;
uchar week,week1;
uchar com,inf;

void delay1(uchar t)
{
uchar a,b;
for(a=t;a>0;a--)
for(b=110;b>0;b--);
}
/*****************************************************
函數(shù)功能:延時(shí)若干微秒
入口參數(shù):n
***************************************************/
void delaynus(unsigned char n)
{
unsigned char i;
for(i=0;i<n;i++)
;
}
/*****************************************************
函數(shù)功能:延時(shí)1ms
(3j+2)*i=(3×33+2)×10=1010(微秒),可以認(rèn)為是1毫秒
***************************************************/
void delay1ms()
{
uchar i,j;
for(i=0;i<10;i++)
  for(j=0;j<33;j++)
    ;   
}
/*****************************************************
函數(shù)功能:延時(shí)若干毫秒
入口參數(shù):n
***************************************************/
void delaynms(uchar n)
{
   uchar i;
for(i=0;i<n;i++)
    delay1ms();
}
/*****************************************************
函數(shù)功能:判斷液晶模塊的忙碌狀態(tài)
返回值:result。result=1,忙碌;result=0,不忙
***************************************************/
bit BusyTest(void)
  {
    bit result;
RS=0;       //根據(jù)規(guī)定,RS為低電平,RW為高電平時(shí),可以讀狀態(tài)
    RW=1;
    E=1;        //E=1,才允許讀寫
    _nop_();   //空操作
    _nop_();
    _nop_();
    _nop_();   //空操作四個(gè)機(jī)器周期,給硬件反應(yīng)時(shí)間
    result=BF;  //將忙碌標(biāo)志電平賦給result
   E=0;         //將E恢復(fù)低電平
   return result;
  }
  /*****************************************************
函數(shù)功能:將模式設(shè)置指令或顯示地址寫入液晶模塊
入口參數(shù):dictate
***************************************************/
void WriteInstruction (uchar dictate)
{   
    while(BusyTest()==1);   //如果忙就等待
  RS=0;                  //根據(jù)規(guī)定,RS和R/W同時(shí)為低電平時(shí),可以寫入指令
  RW=0;   
  E=0;                   //E置低電平(根據(jù)表8-6,寫指令時(shí),E為高脈沖,
                           // 就是讓E從0到1發(fā)生正跳變,所以應(yīng)先置"0"
  _nop_();
  _nop_();               //空操作兩個(gè)機(jī)器周期,給硬件反應(yīng)時(shí)間
  P0=dictate;            //將數(shù)據(jù)送入P0口,即寫入指令或地址
  _nop_();
  _nop_();
  _nop_();
  _nop_();               //空操作四個(gè)機(jī)器周期,給硬件反應(yīng)時(shí)間
  E=1;                   //E置高電平
  _nop_();
  _nop_();
  _nop_();
  _nop_();               //空操作四個(gè)機(jī)器周期,給硬件反應(yīng)時(shí)間
   E=0;                  //當(dāng)E由高電平跳變成低電平時(shí),液晶模塊開始執(zhí)行命令
}
/*****************************************************
函數(shù)功能:指定字符顯示的實(shí)際地址
入口參數(shù):x
***************************************************/
void WriteAddress(unsigned char x)
{
     WriteInstruction(x|0x80); //顯示位置的確定方法規(guī)定為"80H+地址碼x"
}
/*****************************************************
函數(shù)功能:將數(shù)據(jù)(字符的標(biāo)準(zhǔn)ASCII碼)寫入液晶模塊
入口參數(shù):y(為字符常量)
***************************************************/
void WriteData(uchar y)
{
    while(BusyTest()==1);  
   RS=1;           //RS為高電平,RW為低電平時(shí),可以寫入數(shù)據(jù)
   RW=0;
   E=0;            //E置低電平(根據(jù)表8-6,寫指令時(shí),E為高脈沖,
                     // 就是讓E從0到1發(fā)生正跳變,所以應(yīng)先置"0"
   P0=y;           //將數(shù)據(jù)送入P0口,即將數(shù)據(jù)寫入液晶模塊
   _nop_();
   _nop_();
    _nop_();
     _nop_();       //空操作四個(gè)機(jī)器周期,給硬件反應(yīng)時(shí)間
   E=1;           //E置高電平
   _nop_();
   _nop_();
   _nop_();
  _nop_();        //空操作四個(gè)機(jī)器周期,給硬件反應(yīng)時(shí)間
  E=0;            //當(dāng)E由高電平跳變成低電平時(shí),液晶模塊開始執(zhí)行命令
}
/*****************************************************
函數(shù)功能:對(duì)LCD的顯示模式進(jìn)行初始化設(shè)置
***************************************************/
void LcdInitiate(void)
{
    delaynms(15);               //延時(shí)15ms,首次寫指令時(shí)應(yīng)給LCD一段較長的反應(yīng)時(shí)間
    WriteInstruction(0x38);     //顯示模式設(shè)置:16×2顯示,5×7點(diǎn)陣,8位數(shù)據(jù)接口
delaynms(5);                //延時(shí)5ms ,給硬件一點(diǎn)反應(yīng)時(shí)間
    WriteInstruction(0x38);
delaynms(5);               //延時(shí)5ms ,給硬件一點(diǎn)反應(yīng)時(shí)間
WriteInstruction(0x38);     //連續(xù)三次,確保初始化成功
delaynms(5);               //延時(shí)5ms ,給硬件一點(diǎn)反應(yīng)時(shí)間
WriteInstruction(0x0c);     //顯示模式設(shè)置:顯示開,無光標(biāo),光標(biāo)不閃爍
delaynms(5);               //延時(shí)5ms ,給硬件一點(diǎn)反應(yīng)時(shí)間
WriteInstruction(0x06);     //顯示模式設(shè)置:光標(biāo)右移,字符不移
delaynms(5);                //延時(shí)5ms ,給硬件一點(diǎn)反應(yīng)時(shí)間
WriteInstruction(0x01);     //清屏幕指令,將以前的顯示內(nèi)容清除
delaynms(5);             //延時(shí)5ms ,給硬件一點(diǎn)反應(yīng)時(shí)間
}
void write_com(uchar com)//向1602寫指令
{
  RS=0;
  RW=0;
  P0=com;
  delaynms(10);
  E=1;
  delaynms(10);
  E=0;
}
/*****************************************************
函數(shù)功能:顯示溫度的小數(shù)點(diǎn)
***************************************************/
void display_dot(void)
{         
  WriteAddress(0x80+0x40+0x03);   //寫顯示地址,將在第2行第10列開始顯示     
  WriteData('.');      //將小數(shù)點(diǎn)的字符常量寫入LCD
  delaynms(50);         //延時(shí)1ms給硬件一點(diǎn)反應(yīng)時(shí)間  
}
/*****************************************************
函數(shù)功能:顯示溫度的單位(Cent)
***************************************************/
void display_cent(void)
{  
    WriteAddress(0x80+0x40+0x05);        //寫顯示地址,將在第2行第13列開始顯示
WriteData(0xdf);
WriteAddress(0x80+0x40+0x06);
WriteData('C');
}
/*******************************************
向1302寫一個(gè)字節(jié)
*******************************************/
void input_BYTE(uchar dat)
{
uchar i;
ACC=dat;
for(i=8;i>0;i--)
{
  
  T_IO=ACC0;
  T_CLK=1;

  T_CLK=0;
  ACC=(ACC>>1);
}
}
/*******************************************
1302讀出一個(gè)字節(jié)
*******************************************/
uchar output_BYTE()
{
uchar i;
for(i=8;i>0;i--)
{
    ACC=(ACC>>1);
    ACC7=T_IO;
    T_CLK=1;
  
    T_CLK=0;
  
}
return (ACC);
}
/*******************************************
寫數(shù)據(jù)
*******************************************/
void write_1302(uchar add,uchar dat)
{
T_RST=0;   //禁止數(shù)據(jù)傳輸
T_CLK=0;   //確保寫數(shù)據(jù)之前SCLK被拉低
T_RST=1;   //啟動(dòng)數(shù)據(jù)傳輸
input_BYTE(add);   //寫入命令字
input_BYTE(dat);   //寫數(shù)據(jù)
T_CLK=1;  //將時(shí)鐘電平至于已知狀態(tài)
T_RST=0;
}
/*******************************************
讀數(shù)據(jù)
*******************************************/
uchar read_1302(uchar add)
{
uchar inf;
T_RST=0;
    T_CLK=0;
T_RST=1;
input_BYTE(add);
inf=output_BYTE();
T_CLK=1;
T_RST=0;
return (inf);
}
void init_1302()
{
write_1302(0x8e,0x00);//關(guān)閉寫保護(hù);
// write_1302(0x90,0xaa);//設(shè)置充電方式;
write_1302(0x80,0x00);//秒寄存器初始化;
write_1302(0x82,0x29);//分.......
write_1302(0x84,0x08);//時(shí).......
write_1302(0x86,0x10);//日........
write_1302(0x88,0x11);//月.......
write_1302(0x8a,0x02);//星期...
write_1302(0x8c,0x15);//年......   
write_1302(0x8e,0x80);//打開寫保護(hù);  
}
/**********************************
鬧鐘顯示子程序
**********************************/
void show_naozhong(uchar x,uchar y)
{
uchar i,x1,x2,y1,y2;
x1=x/10; //十位
x2=x%10;//個(gè)位
WriteAddress(0x80+0x0b);   //顯示鬧鐘的小時(shí)部分
WriteData(table1[x1]);
WriteAddress(0x80+0x0c);
WriteData(table1[x2]);

y1=y/10; //十位
y2=y%10;//個(gè)位
WriteAddress(0x80+0x0e);   //顯示鬧鐘的分鐘部分
WriteData(table1[y1]);
WriteAddress(0x80+0x0f);
WriteData(table1[y2]);

WriteAddress(0x80+0x0d);   //顯示小時(shí)與分鐘之間的那個(gè)冒號(hào)
WriteData(':');
WriteAddress(0x80);     //顯示字符串:Alarm Clock
for(i=0;i<11;i++)
{
  WriteData(table[i]);
}
WriteAddress(0x80+0x40);   //顯示字符串:Today is fine!
for(i=0;i<14;i++)
{
  WriteData(table3[i]);
}   
}
void main(void)
{   
    uchar i;
LcdInitiate();         //將液晶初始化
    init_1302();
    delaynms(5);        //延時(shí)5ms給硬件一點(diǎn)反應(yīng)時(shí)間
// if(Init_DS18B20()==1)
//   display_error();
EA=1;//開總中斷
EX0=1; //開外部中斷1
IT0=0; //下降沿觸發(fā)

WriteAddress(0x80+0x50);
for(i=0;i<13;i++)
{
  WriteData(table5[i]);
}
for(i=0;i<30;i++)
{
  write_com(0x18);
  delaynms(250);
}
delaynms(250);
write_com(0x01);
while(1)
{
  t_sec=read_1302(0x81);//讀秒 ;
  sec1=t_sec&0x0f;
  sec2=(t_sec>>4);

  t_min=read_1302(0x83);//讀分 ;
  min1=t_min&0x0f;
  min2=(t_min>>4);

  t_hour=read_1302(0x85);//讀小時(shí) ;
  hour1=t_hour&0x0f;
  hour2=(t_hour>>4);


  t_day=read_1302(0x87);//讀日;
  day1=t_day&0x0f;
  day2=(t_day>>4);

  t_mon=read_1302(0x89);//讀月 ;
  mon1=t_mon&0x0f;
  mon2=(t_mon>>4);

  week=read_1302(0x8b);//讀星期 ;
  week1=week&0x0f;

  t_year=read_1302(0x8d);//讀年 ;
  year1=t_year&0x0f;
  year2=(t_year>>4);

  WriteAddress(0x80+0x06);  
  WriteData('2');
  WriteAddress(0x80+0x07);  
  WriteData('0');
  
  
  WriteAddress(0x80);   //顯示星期(0x80~0x80+0x05)
  for(i=0;i<4;i++)
  {
   WriteData(table2[i]);
  }
  WriteAddress(0x80+0x04);
  WriteData(table1[week1]);
   
  WriteAddress(0x80+0x08);//顯示年  
  WriteData(table1[year2]);
  WriteAddress(0x80+0x09);  
  WriteData(table1[year1]);
   
  WriteAddress(0x80+0x0a); //顯示‘/’
  WriteData('/');

  WriteAddress(0x80+0x0b);//顯示月
  WriteData(table1[mon2]);   
  WriteAddress(0x80+0x0c);
  WriteData(table1[mon1]);
  WriteAddress(0x80+0x0d); //顯示‘/’
  WriteData('/');

  WriteAddress(0x80+0x0e);//顯示日
  WriteData(table1[day2]);   
  WriteAddress(0x80+0x0f);
  WriteData(table1[day1]);
  /*第一行在此顯示完畢*/   
      display_dot();       //顯示溫度的小數(shù)點(diǎn)
       display_cent();      //顯示溫度的單位

  WriteAddress(0x80+0x40+0x08); //顯示小時(shí)
  WriteData(table1[hour2]);   
  WriteAddress(0x80+0x40+0x09);
  WriteData(table1[hour1]);  

  WriteAddress(0x80+0x40+0x0a);  //顯示':'
  WriteData(':');      

  WriteAddress(0x80+0x40+0x0b);  //顯示分鐘
  WriteData(table1[min2]);     
  WriteAddress(0x80+0x40+0x0c);
  WriteData(table1[min1]);   

  WriteAddress(0x80+0x40+0x0d); //顯示':'
  WriteData(':');   

  WriteAddress(0x80+0x40+0x0e); //顯示秒
  WriteData(table1[sec2]);   
  WriteAddress(0x80+0x40+0x0f);
  WriteData(table1[sec1]);
  /*第二行在此顯示完畢*/
  //以下部分是鬧鐘鍵盤檢測程序
  if((x==hour2*10+hour1)&&(y==min2*10+min1))//若時(shí)間到了,則開啟鬧鐘
  {
   beep=0;
  }
  else   //否則,關(guān)閉鬧鐘
  {
   beep=1;
  }
     delaynms(10);

     while(key4==0)
  { delaynms(10);
     if(key4==0)
       {  delaynms(10);
       while(key4==0);
                     }
  }     
}      
}
void exter0()interrupt 0
{
uint k;
write_com(0x01);
for(k=0;k<2000;k++)
{
  while(key1==0)     //鍵盤掃描.當(dāng)key1按下時(shí),
  {        //鬧鐘的小時(shí)部分加一
   delaynms(10);
   if(key1==0)     //消抖
   {
    delaynms(10);
    while(key1==0); //松手檢測
    x++;
    if(x==24)    //小時(shí)部分加到24后自動(dòng)清零
    x=0;
   }
  }
  while(key2==0)  //鍵盤檢測。當(dāng)key2按下時(shí),
  {
   delaynms(10); //鬧鐘的分鐘部分加一
   if(key2==0)  //消抖
   {
    delaynms(10);
    while(key2==0);//松手檢測
    y++;
    if(y==60)   //若分鐘部分加到60,則自動(dòng)清零
    y=0;
   }
  }        
   
  show_naozhong(x,y);   //調(diào)用鬧鐘顯示程序
}
write_com(0x01);
}

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:89734 發(fā)表于 2015-11-29 14:19 | 只看該作者
這個(gè)是去掉無線模塊的萬年歷仿真

QQ圖片20151129142634.png (23.87 KB, 下載次數(shù): 130)

QQ圖片20151129142634.png
回復(fù)

使用道具 舉報(bào)

板凳
ID:96682 發(fā)表于 2015-11-29 15:56 | 只看該作者

回帖獎(jiǎng)勵(lì) +5

看不出你你把DS18B20放在哪個(gè)引腳上,源代碼也沒發(fā)現(xiàn),出現(xiàn)如此現(xiàn)象實(shí)屬正常。
回復(fù)

使用道具 舉報(bào)

地板
ID:89734 發(fā)表于 2015-11-29 17:09 | 只看該作者
wc86110 發(fā)表于 2015-11-29 15:56
看不出你你把DS18B20放在哪個(gè)引腳上,源代碼也沒發(fā)現(xiàn),出現(xiàn)如此現(xiàn)象實(shí)屬正常。

我溫度測試是放在另一個(gè)板上啊,我現(xiàn)在是想先實(shí)現(xiàn)萬年歷的部分,我放仿真圖的意思是我仿真是正常的我想要的效果,但是實(shí)物作品LCD是完全不顯示任何東西的,只有背光。。。。。。
回復(fù)

使用道具 舉報(bào)

5#
ID:89734 發(fā)表于 2015-11-29 17:10 | 只看該作者
wc86110 發(fā)表于 2015-11-29 15:56
看不出你你把DS18B20放在哪個(gè)引腳上,源代碼也沒發(fā)現(xiàn),出現(xiàn)如此現(xiàn)象實(shí)屬正常。

我說的是我實(shí)物不行,仿真確實(shí)已經(jīng)是我要的效果了,溫度是另一個(gè)板傳過來的,我還沒把那個(gè)溫度的代碼加進(jìn)去啊,,,,實(shí)物L(fēng)CD只有背光沒有任何數(shù)據(jù),,,,
回復(fù)

使用道具 舉報(bào)

6#
ID:96682 發(fā)表于 2015-11-30 00:54 | 只看該作者
檢查硬件電路是否有問題,要是沒問題的話,就在液晶屏的第(3)引腳接入可變電阻器看看,還是不行就只能使用置換法來排除是否與使用的液晶屏有關(guān)了。
回復(fù)

使用道具 舉報(bào)

7#
ID:97831 發(fā)表于 2015-12-1 14:52 | 只看該作者

回帖獎(jiǎng)勵(lì) +5

我也出現(xiàn)相似問題
回復(fù)

使用道具 舉報(bào)

8#
ID:97867 發(fā)表于 2015-12-1 16:07 | 只看該作者
檢查你液晶顯示不 寫個(gè)小程序  讓液晶固定顯示一個(gè)字母 然后死循環(huán) 看能顯示嗎 ?
回復(fù)

使用道具 舉報(bào)

9#
ID:18867 發(fā)表于 2015-12-1 20:55 | 只看該作者
把測忙程序去掉試試!
回復(fù)

使用道具 舉報(bào)

10#
ID:89734 發(fā)表于 2015-12-1 22:19 | 只看該作者
PLA 發(fā)表于 2015-12-1 20:55
把測忙程序去掉試試!

試了,還是不行,顯示的是一行黑塊
回復(fù)

使用道具 舉報(bào)

11#
ID:89734 發(fā)表于 2015-12-1 22:22 | 只看該作者
解放君 發(fā)表于 2015-12-1 16:07
檢查你液晶顯示不 寫個(gè)小程序  讓液晶固定顯示一個(gè)字母 然后死循環(huán) 看能顯示嗎 ?

我換了可調(diào)電阻之后顯示的是一行黑塊,然后怎么調(diào)都是顯示黑塊
回復(fù)

使用道具 舉報(bào)

12#
ID:97867 發(fā)表于 2015-12-3 13:17 | 只看該作者
顯示 一行 黑塊 就是你 程序的問題了曬   你看哈 你讀寫 命令的延時(shí) 什么的   你在其他寫個(gè)c  或者把你當(dāng)前c 全部屏蔽了 寫個(gè) lcd 在第一行 第一個(gè)位置顯示一個(gè)a 字符 看 能不能顯示
回復(fù)

使用道具 舉報(bào)

13#
ID:79544 發(fā)表于 2015-12-4 13:01 | 只看該作者
適當(dāng)延長E由高電平變成低電平的時(shí)間,—nop_()多些或者加延時(shí)。驅(qū)動(dòng)忙檢測
回復(fù)

使用道具 舉報(bào)

14#
ID:98452 發(fā)表于 2015-12-5 15:50 | 只看該作者
我也想做一個(gè)萬年歷,來學(xué)習(xí)學(xué)習(xí)!
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表