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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4713|回復: 14
打印 上一主題 下一主題
收起左側

我的萬年歷設計LCD無法顯示,仿真通過

[復制鏈接]
跳轉到指定樓層
樓主
因為我設計的萬年歷還有測試溫度的功能,但是溫度是由另外一塊板無線傳輸過來的,我編寫了單單萬年歷的部分在PROTUES仿真可以工作,將這個單單萬年歷部分的代碼燒寫到單片機中卻無法在整個電路中工作(整個電路是指帶有無線模塊的電路)。請問我這樣的方法是不是不對。我測試了一下LCD的狀態是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"};     //定義字符數組顯示數字
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
/*******************************************************************************
以下是對液晶模塊的操作程序
*******************************************************************************/
sbit RS=P2^5;           //寄存器選擇位,將RS位定義為P2.0引腳
sbit RW=P2^6;           //讀寫選擇位,將RW位定義為P2.1引腳
sbit E=P2^7;            //使能信號位,將E位定義為P2.2引腳
sbit BF=P0^7;           //忙碌標志位,,將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;   //調鬧鐘的小時即x
sbit key2=P3^1;   //調鬧鐘的分鐘即y
sbit key4=P3^5;   //顯示切換
sbit key3=P3^2;
sbit ACC0=ACC^0;
sbit ACC7=ACC^7;
uchar time;   //設置全局變量,專門用于嚴格延時
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--);
}
/*****************************************************
函數功能:延時若干微秒
入口參數:n
***************************************************/
void delaynus(unsigned char n)
{
unsigned char i;
for(i=0;i<n;i++)
;
}
/*****************************************************
函數功能:延時1ms
(3j+2)*i=(3×33+2)×10=1010(微秒),可以認為是1毫秒
***************************************************/
void delay1ms()
{
uchar i,j;
for(i=0;i<10;i++)
  for(j=0;j<33;j++)
    ;   
}
/*****************************************************
函數功能:延時若干毫秒
入口參數:n
***************************************************/
void delaynms(uchar n)
{
   uchar i;
for(i=0;i<n;i++)
    delay1ms();
}
/*****************************************************
函數功能:判斷液晶模塊的忙碌狀態
返回值:result。result=1,忙碌;result=0,不忙
***************************************************/
bit BusyTest(void)
  {
    bit result;
RS=0;       //根據規定,RS為低電平,RW為高電平時,可以讀狀態
    RW=1;
    E=1;        //E=1,才允許讀寫
    _nop_();   //空操作
    _nop_();
    _nop_();
    _nop_();   //空操作四個機器周期,給硬件反應時間
    result=BF;  //將忙碌標志電平賦給result
   E=0;         //將E恢復低電平
   return result;
  }
  /*****************************************************
函數功能:將模式設置指令或顯示地址寫入液晶模塊
入口參數:dictate
***************************************************/
void WriteInstruction (uchar dictate)
{   
    while(BusyTest()==1);   //如果忙就等待
  RS=0;                  //根據規定,RS和R/W同時為低電平時,可以寫入指令
  RW=0;   
  E=0;                   //E置低電平(根據表8-6,寫指令時,E為高脈沖,
                           // 就是讓E從0到1發生正跳變,所以應先置"0"
  _nop_();
  _nop_();               //空操作兩個機器周期,給硬件反應時間
  P0=dictate;            //將數據送入P0口,即寫入指令或地址
  _nop_();
  _nop_();
  _nop_();
  _nop_();               //空操作四個機器周期,給硬件反應時間
  E=1;                   //E置高電平
  _nop_();
  _nop_();
  _nop_();
  _nop_();               //空操作四個機器周期,給硬件反應時間
   E=0;                  //當E由高電平跳變成低電平時,液晶模塊開始執行命令
}
/*****************************************************
函數功能:指定字符顯示的實際地址
入口參數:x
***************************************************/
void WriteAddress(unsigned char x)
{
     WriteInstruction(x|0x80); //顯示位置的確定方法規定為"80H+地址碼x"
}
/*****************************************************
函數功能:將數據(字符的標準ASCII碼)寫入液晶模塊
入口參數:y(為字符常量)
***************************************************/
void WriteData(uchar y)
{
    while(BusyTest()==1);  
   RS=1;           //RS為高電平,RW為低電平時,可以寫入數據
   RW=0;
   E=0;            //E置低電平(根據表8-6,寫指令時,E為高脈沖,
                     // 就是讓E從0到1發生正跳變,所以應先置"0"
   P0=y;           //將數據送入P0口,即將數據寫入液晶模塊
   _nop_();
   _nop_();
    _nop_();
     _nop_();       //空操作四個機器周期,給硬件反應時間
   E=1;           //E置高電平
   _nop_();
   _nop_();
   _nop_();
  _nop_();        //空操作四個機器周期,給硬件反應時間
  E=0;            //當E由高電平跳變成低電平時,液晶模塊開始執行命令
}
/*****************************************************
函數功能:對LCD的顯示模式進行初始化設置
***************************************************/
void LcdInitiate(void)
{
    delaynms(15);               //延時15ms,首次寫指令時應給LCD一段較長的反應時間
    WriteInstruction(0x38);     //顯示模式設置:16×2顯示,5×7點陣,8位數據接口
delaynms(5);                //延時5ms ,給硬件一點反應時間
    WriteInstruction(0x38);
delaynms(5);               //延時5ms ,給硬件一點反應時間
WriteInstruction(0x38);     //連續三次,確保初始化成功
delaynms(5);               //延時5ms ,給硬件一點反應時間
WriteInstruction(0x0c);     //顯示模式設置:顯示開,無光標,光標不閃爍
delaynms(5);               //延時5ms ,給硬件一點反應時間
WriteInstruction(0x06);     //顯示模式設置:光標右移,字符不移
delaynms(5);                //延時5ms ,給硬件一點反應時間
WriteInstruction(0x01);     //清屏幕指令,將以前的顯示內容清除
delaynms(5);             //延時5ms ,給硬件一點反應時間
}
void write_com(uchar com)//向1602寫指令
{
  RS=0;
  RW=0;
  P0=com;
  delaynms(10);
  E=1;
  delaynms(10);
  E=0;
}
/*****************************************************
函數功能:顯示溫度的小數點
***************************************************/
void display_dot(void)
{         
  WriteAddress(0x80+0x40+0x03);   //寫顯示地址,將在第2行第10列開始顯示     
  WriteData('.');      //將小數點的字符常量寫入LCD
  delaynms(50);         //延時1ms給硬件一點反應時間  
}
/*****************************************************
函數功能:顯示溫度的單位(Cent)
***************************************************/
void display_cent(void)
{  
    WriteAddress(0x80+0x40+0x05);        //寫顯示地址,將在第2行第13列開始顯示
WriteData(0xdf);
WriteAddress(0x80+0x40+0x06);
WriteData('C');
}
/*******************************************
向1302寫一個字節
*******************************************/
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讀出一個字節
*******************************************/
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);
}
/*******************************************
寫數據
*******************************************/
void write_1302(uchar add,uchar dat)
{
T_RST=0;   //禁止數據傳輸
T_CLK=0;   //確保寫數據之前SCLK被拉低
T_RST=1;   //啟動數據傳輸
input_BYTE(add);   //寫入命令字
input_BYTE(dat);   //寫數據
T_CLK=1;  //將時鐘電平至于已知狀態
T_RST=0;
}
/*******************************************
讀數據
*******************************************/
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);//關閉寫保護;
// write_1302(0x90,0xaa);//設置充電方式;
write_1302(0x80,0x00);//秒寄存器初始化;
write_1302(0x82,0x29);//分.......
write_1302(0x84,0x08);//時.......
write_1302(0x86,0x10);//日........
write_1302(0x88,0x11);//月.......
write_1302(0x8a,0x02);//星期...
write_1302(0x8c,0x15);//年......   
write_1302(0x8e,0x80);//打開寫保護;  
}
/**********************************
鬧鐘顯示子程序
**********************************/
void show_naozhong(uchar x,uchar y)
{
uchar i,x1,x2,y1,y2;
x1=x/10; //十位
x2=x%10;//個位
WriteAddress(0x80+0x0b);   //顯示鬧鐘的小時部分
WriteData(table1[x1]);
WriteAddress(0x80+0x0c);
WriteData(table1[x2]);

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

WriteAddress(0x80+0x0d);   //顯示小時與分鐘之間的那個冒號
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);        //延時5ms給硬件一點反應時間
// if(Init_DS18B20()==1)
//   display_error();
EA=1;//開總中斷
EX0=1; //開外部中斷1
IT0=0; //下降沿觸發

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);//讀小時 ;
  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();       //顯示溫度的小數點
       display_cent();      //顯示溫度的單位

  WriteAddress(0x80+0x40+0x08); //顯示小時
  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))//若時間到了,則開啟鬧鐘
  {
   beep=0;
  }
  else   //否則,關閉鬧鐘
  {
   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)     //鍵盤掃描.當key1按下時,
  {        //鬧鐘的小時部分加一
   delaynms(10);
   if(key1==0)     //消抖
   {
    delaynms(10);
    while(key1==0); //松手檢測
    x++;
    if(x==24)    //小時部分加到24后自動清零
    x=0;
   }
  }
  while(key2==0)  //鍵盤檢測。當key2按下時,
  {
   delaynms(10); //鬧鐘的分鐘部分加一
   if(key2==0)  //消抖
   {
    delaynms(10);
    while(key2==0);//松手檢測
    y++;
    if(y==60)   //若分鐘部分加到60,則自動清零
    y=0;
   }
  }        
   
  show_naozhong(x,y);   //調用鬧鐘顯示程序
}
write_com(0x01);
}

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

使用道具 舉報

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

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

QQ圖片20151129142634.png
回復

使用道具 舉報

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

回帖獎勵 +5

看不出你你把DS18B20放在哪個引腳上,源代碼也沒發現,出現如此現象實屬正常。
回復

使用道具 舉報

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

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

使用道具 舉報

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

我說的是我實物不行,仿真確實已經是我要的效果了,溫度是另一個板傳過來的,我還沒把那個溫度的代碼加進去啊,,,,實物LCD只有背光沒有任何數據,,,,
回復

使用道具 舉報

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

使用道具 舉報

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

回帖獎勵 +5

我也出現相似問題
回復

使用道具 舉報

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

使用道具 舉報

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

使用道具 舉報

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

試了,還是不行,顯示的是一行黑塊
回復

使用道具 舉報

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

我換了可調電阻之后顯示的是一行黑塊,然后怎么調都是顯示黑塊
回復

使用道具 舉報

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

使用道具 舉報

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

使用道具 舉報

14#
ID:98452 發表于 2015-12-5 15:50 | 只看該作者
我也想做一個萬年歷,來學習學習!
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 狠狠涩 | 成人免费xxxxx在线视频 | 国产精品视频yy9299一区 | 国产日韩欧美精品一区二区 | 中文字幕精品一区二区三区精品 | 亚洲综合无码一区二区 | 日本在线精品视频 | 欧美多人在线 | 精品美女视频在线观看免费软件 | 精产国产伦理一二三区 | 91成人精品 | 成人在线国产 | 在线国产一区 | 亚洲一区二区不卡在线观看 | 欧美一区二区三区在线免费观看 | 亚洲一区二区久久久 | www.日本三级 | 81精品国产乱码久久久久久 | 日韩成人av在线 | 久久69精品久久久久久久电影好 | 成人免费在线网 | 日韩成人一区 | 久久精品国产99国产精品 | 精品欧美乱码久久久久久 | 久久综合婷婷 | 国产福利资源 | 日韩色在线 | 中文字幕一区二区三区在线观看 | 日韩欧美国产一区二区 | 国产一级免费视频 | 综合五月| 天天射影院| 久久久久一区二区 | 久久综合九色综合欧美狠狠 | 日韩综合一区 | 性色综合| 人人澡人人射 | 久久综合av | 国产精品揄拍一区二区 | 久久99精品久久久久久秒播九色 | 亚洲国产成人精品久久 |