原理圖和程序是買實物時送的,但我照原理圖搭了仿真,把hex文件導進去LCD沒有顯示,大哥們這是為啥?這是單片機程序:
#include <REG52.H> //器件配置文件 #include <intrins.h> #define uint unsigned int #define uchar unsigned char
sbit RX = P2^1; sbit TX = P2^0;
sbit LCM_RW = P2^6; //定義LCD引腳 sbit LCM_RS = P2^5; sbit LCM_E =P2^7; #define LCM_Data P0
sbit K1= P3^2; //定義Keyboard引腳 sbit K2= P3^3; uchar Slong=30; // 報警距離值 如果需要修改報警距離,則改此處數(shù)值就可。 sbit speak=P1^7; //蜂鳴器報警的口線定義
#define Busy 0x80 //用于檢測LCM狀態(tài)字中的Busy標識
void LCMInit(void); void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData); void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData); void Delay5Ms(void); void Delay400Ms(void); void Decode(unsigned char ScanCode); void WriteDataLCM(unsigned char WDLCM); void WriteCommandLCM(unsigned char WCLCM,BuysC);
unsigned char ReadDataLCM(void); unsigned char ReadStatusLCM(void); unsigned char code juli[] ={"The distance is"}; unsigned char code kaiji[] = {" "};
unsigned char code ASCII[15] = {'0','1','2','3','4','5','6','7','8','9','.','-','M','S'};
static unsigned char DisNum = 0; //顯示用指針 unsigned int time=0; unsigned char timer=0; unsigned char pinlv=0; unsigned char cishu=0; unsigned long S=0; bit flag =0; bit flag_one=0; bit flag_two=0; unsigned char disbuff[4]={ 0,0,0,0,};
#include "eeprom52.h"
void delayms(unsigned int ms) { unsigned char i=100,j; for(;ms;ms--) { while(--i) { j=10; while(--j); } } }
/******************把數(shù)據(jù)保存到單片機內(nèi)部eeprom中******************/ void write_eeprom() { SectorErase(0x2000); byte_write(0x2001, Slong); byte_write(0x2060, a_a); }
/******************把數(shù)據(jù)從單片機內(nèi)部eeprom中讀出來*****************/ void read_eeprom() {
Slong = byte_read(0x2001); a_a = byte_read(0x2060); }
/**************開機自檢eeprom初始化*****************/ void init_eeprom() { read_eeprom(); //先讀 if(a_a != 2) //新的單片機初始單片機內(nèi)問eeprom { Slong = 30; a_a = 2; write_eeprom(); } }
//寫數(shù)據(jù) void WriteDataLCM(unsigned char WDLCM) { ReadStatusLCM(); //檢測忙 LCM_Data = WDLCM; LCM_RS = 1; LCM_RW = 0; LCM_E = 0; //若晶振速度太高可以在這后加小的延時 LCM_E = 0; //延時 LCM_E = 1; }
//寫指令 void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC為0時忽略忙檢測 { if (BuysC) ReadStatusLCM(); //根據(jù)需要檢測忙 LCM_Data = WCLCM; LCM_RS = 0; LCM_RW = 0; LCM_E = 0; LCM_E = 0; LCM_E = 1; }
//讀數(shù)據(jù) unsigned char ReadDataLCM(void) { LCM_RS = 1; LCM_RW = 1; LCM_E = 0; LCM_E = 0; LCM_E = 1; return(LCM_Data); }
//讀狀態(tài) unsigned char ReadStatusLCM(void) { LCM_Data = 0xFF; LCM_RS = 0; LCM_RW = 1; LCM_E = 0; LCM_E = 0; LCM_E = 1; while (LCM_Data & Busy); //檢測忙信號 return(LCM_Data); }
void LCMInit(void) //LCM初始化 {
WriteCommandLCM(0x38);//設置模式 WriteCommandLCM(0x0c);//不顯示光標 WriteCommandLCM(0x06);//設置指針自加 WriteCommandLCM(0x01);//清屏 }
//按指定位置顯示一個字符 void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData) { Y &= 0x1; X &= 0xF; //限制X不能大于15,Y不能大于1 if (Y) X |= 0x40; //當要顯示第二行時地址碼+0x40; X |= 0x80; //算出指令碼 WriteCommandLCM(X, 1); //發(fā)命令字 WriteDataLCM(DData); //發(fā)數(shù)據(jù) }
//按指定位置顯示一串字符 void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData) { unsigned char ListLength;
ListLength = 0; Y &= 0x1; X &= 0xF; //限制X不能大于15,Y不能大于1 while (DData[ListLength]>0x19) //若到達字串尾則退出 { if (X <= 0xF) //X坐標應小于0xF { DisplayOneChar(X, Y, DData[ListLength]); //顯示單個字符 ListLength++; X++; } } }
//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--); }; }
void key() { if(!K1) //按下按鍵 { delayms(5); //延時去抖 if(!K1) { Slong+=1; //每按下一次,數(shù)值加10 write_eeprom(); //保存數(shù)據(jù) flag_one=0; } while(!K1); //等待按鍵彈起 }
if(!K2) //按下按鍵 { delayms(5); //延時去抖 if(!K2) { Slong-=1; //每按下一次,數(shù)值加10 write_eeprom(); //保存數(shù)據(jù) flag_one=0; } while(!K2); //等待按鍵 彈起 }
if(flag_one==0) { flag_one=1; disbuff[0]=Slong%1000/100; disbuff[1]=Slong%1000%100/10; disbuff[2]=Slong%1000%10 %10; DisplayOneChar(9, 1, ASCII[13]); //顯示S DisplayOneChar(10, 1, ':'); //顯示M DisplayOneChar(11, 1, ASCII[disbuff[0]]); DisplayOneChar(12, 1, ASCII[10]); //顯示點 DisplayOneChar(13, 1, ASCII[disbuff[1]]); DisplayOneChar(14, 1, ASCII[disbuff[2]]); DisplayOneChar(15, 1, ASCII[12]); //顯示M
}
}
warn() //報警函數(shù) { if( S>Slong*4/5 && S<=Slong*5/5 ) //當距離小于等于設定的報警值時 { pinlv=1; //蜂嚀器報警等級 }
if( S>Slong*3/5 && S<=Slong*4/5 ) //當距離小于等于設定的報警值時 { pinlv=2; //蜂嚀器報警等級 }
if( S>Slong*2/5 && S<=Slong*3/5 ) //當距離小于等于設定的報警值時 { pinlv=3; //蜂嚀器報警等級 }
if( S>Slong*1/5 && S<=Slong*2/5 ) //當距離小于等于設定的報警值時 { pinlv=4; //蜂嚀器報警等級 }
if( S<=Slong*1/5 ) //當距離小于等于設定的報警值時 { pinlv=5; //蜂嚀器報警等級 }
if(S>Slong) //當距離大于設定的報警值時 { pinlv=0; // 蜂嚀器不報警。 } }
/********************************************************/ void Conut(void) { time=TH0*256+TL0; TH0=0; TL0=0;
S=(time*1.7)/100; //算出來是CM if((S>=700)||flag==1) //超出測量范圍顯示“-” { flag=0;
DisplayOneChar(0, 1, ASCII[11]); DisplayOneChar(1, 1, ASCII[10]); //顯示點 DisplayOneChar(2, 1, ASCII[11]); DisplayOneChar(3, 1, ASCII[11]); DisplayOneChar(4, 1, ASCII[12]); //顯示M } else { disbuff[0]=S%1000/100; disbuff[1]=S%1000%100/10; disbuff[2]=S%1000%10 %10; DisplayOneChar(0, 1, ASCII[disbuff[0]]); DisplayOneChar(1, 1, ASCII[10]); //顯示點 DisplayOneChar(2, 1, ASCII[disbuff[1]]); DisplayOneChar(3, 1, ASCII[disbuff[2]]); DisplayOneChar(4, 1, ASCII[12]); //顯示M } } /********************************************************/ void zd0() interrupt 1 //T0中斷用來計數(shù)器溢出,超過測距范圍 { flag=1; //中斷溢出標志 } /********************************************************/ void StartModule() //啟動模塊 { TX=1; //啟動一次模塊 _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); TX=0; } /********************************************************/
/*********************************************************/ void main(void) {
unsigned char TempCyc; Delay400Ms(); //啟動等待,等LCM講入工作狀態(tài) LCMInit(); //LCM初始化 Delay5Ms(); //延時片刻(可不要) DisplayListChar(0, 0, juli); DisplayListChar(0, 1, kaiji); //ReadDataLCM();//測試用句無意義 //for (TempCyc=0; TempCyc<10; TempCyc++) Delay400Ms(); //延時 init_eeprom(); //讀eeprom數(shù)據(jù) while(1) { TMOD=0x11; //設T0為方式1,GATE=1; TH0=0; TL0=0; TH1=0xf8; //2MS定時 TL1=0x30; ET0=1; //允許T0中斷 ET1=1; //允許T1中斷 TR1=1; //開啟定時器 EA=1; //開啟總中斷
while(1) { key(); if(flag_two==0) { flag_two=1; StartModule(); while(!RX); //當RX為零時等待 TR0=1; //開啟計數(shù) while(RX); //當RX為1計數(shù)并等待 TR0=0; //關(guān)閉計數(shù) Conut(); //計算 warn(); } } } }
void zd3() interrupt 3 // { TH1=0x3c; TL1=0xb0; cishu++; timer++; if(timer>=10) //500ms刷新一次 { flag_two=0; }
if(pinlv==0) { speak=1; }
if(pinlv==1) { if(cishu>=5) { cishu=0; speak=~speak; } }
if(pinlv==2) { if(cishu>=4) { cishu=0; speak=~speak; } }
if(pinlv==3) { if(cishu>=3) { cishu=0; speak=~speak; } }
if(pinlv==4) { if(cishu>=2) { cishu=0; speak=~speak; } }
if(pinlv==5) { if(cishu>=1) { cishu=0; speak=~speak; } }
}
|