|
求位大神幫忙看看是哪里錯了,按照這個電路圖做出來的板子接上電源后,1602只有一個背光燈亮,在proteus上仿真也是這種情況,LCD只有一個背光燈亮,附上程序
#include <AT89X52.h> //調(diào)用51單片機(jī)的頭文件
#include <Intrins.h>
//---------------------------------------
//1602液晶相關(guān)I/O設(shè)置
sbit E=P2^2; //1602液晶的E腳接在P2.2口上
sbit RW=P2^1; //1602液晶的RW腳接在P2.1口上
sbit RS=P2^0; //1602液晶的RS腳接在P2.0口上
//---------------------------------------
sbit ds18b20=P3^7;
//---------------------------------------
//1602液晶寄存器設(shè)置
unsigned char DISbuf; //設(shè)置8位的unsigend char型寄存器用來暫存1602要顯示的內(nèi)容
//---------------------------------------
unsigned char temp1;
unsigned char temp2;
unsigned char code table[16]={0,0,1,2,2,3,4,4,5,6,6,7,8,8,9,9};
void Delay(unsigned int nTimeDelay)
{
unsigned int i;
while (nTimeDelay--)
for (i=0;i<125;i++);
}
bit Reset(void)
{
unsigned int i;
bit k;
ds18b20=0; //拉低DQ總線開始復(fù)位
i=200; //保持DQ低大約870uS,符合不低于48US的要求
while(i>0) //保持DQ低大約870uS,符合不低于48US的要求
i--; //保持DQ低大約870uS,符合不低于48US的要求
ds18b20=1; //拉高準(zhǔn)備接收數(shù)據(jù)
i=18; //大約80uS后
while(i>0) //大約80uS后
i--; //大約80uS后
k=ds18b20; //讀出數(shù)據(jù)并保存
i=91; //維持約400US,符合總讀時隙不低于480US的要求
while(i>0) //維持約400US,符合總讀時隙不低于480US的要求
i--; //維持約400US,符合總讀時隙不低于480US的要求
return k; //k=0為復(fù)位成功,k=1為復(fù)位失敗
}
unsigned char ReadByte(void)
{
unsigned int i;
unsigned char j,buf=0;
for(j=0;j<8;j++) //接收8次還原一個字節(jié)數(shù)據(jù)
{
buf=buf>>1; //接收前,想將接收緩沖區(qū)右移
ds18b20=0; //拉低
_nop_(); //維持2US,符合大于1US小于15US的規(guī)范
_nop_(); //維持2US,符合大于1US小于15US的規(guī)范
_nop_(); //維持2US,符合大于1US小于15US的規(guī)范
_nop_(); //維持2US,符合大于1US小于15US的規(guī)范
ds18b20=1; //拉高,為讀數(shù)據(jù)做準(zhǔn)備
_nop_(); //維持6US,符合大于1US小于15US的規(guī)范
_nop_(); //維持6US,符合大于1US小于15US的規(guī)范
_nop_(); //維持6US,符合大于1US小于15US的規(guī)范
_nop_(); //維持6US,符合大于1US小于15US的規(guī)范
_nop_(); //維持6US,符合大于1US小于15US的規(guī)范
_nop_(); //維持6US,符合大于1US小于15US的規(guī)范
_nop_(); //維持6US,符合大于1US小于15US的規(guī)范
_nop_(); //維持6US,符合大于1US小于15US的規(guī)范
_nop_(); //維持6US,符合大于1US小于15US的規(guī)范
_nop_(); //維持6US,符合大于1US小于15US的規(guī)范
_nop_(); //維持6US,符合大于1US小于15US的規(guī)范
_nop_(); //維持6US,符合大于1US小于15US的規(guī)范
if(ds18b20==1) buf|=0x80; //讀出1位數(shù)據(jù)保存于buf中
i=12; //維持約52US,符合總讀時隙不低于60US的要求
while(i>0) //維持約52US,符合總讀時隙不低于60US的要求
i--; //維持約52US,符合總讀時隙不低于60US的要求
}
return buf; //退出的同時將接收緩沖區(qū)參數(shù)返回
}
void WriteByte(unsigned char dat)
{
unsigned int i;
unsigned char j;
for(j=0;j<8;j++)
{
if(dat&0x01) //如果寫1
{
ds18b20=0; //拉低
_nop_(); //維持2US,符合大于1US小于15US的規(guī)范
_nop_(); //維持2US,符合大于1US小于15US的規(guī)范
_nop_(); //維持2US,符合大于1US小于15US的規(guī)范
_nop_(); //維持2US,符合大于1US小于15US的規(guī)范
ds18b20=1; //拉高
i=14; //維持約63US,符合不低于60US的要求
while(i>0) //維持約63US,符合不低于60US的要求
i--; //維持約63US,符合不低于60US的要求
}
else //如果寫0
{
ds18b20=0; //拉低
i=14; //維持約63US,符合不低于60US的要求
while(i>0) //維持約63US,符合不低于60US的要求
i--; //維持約63US,符合不低于60US的要求
ds18b20=1; //拉高
_nop_(); //維持2US,符合大于1US的規(guī)范
_nop_(); //維持2US,符合大于1US的規(guī)范
_nop_(); //維持2US,符合大于1US的規(guī)范
_nop_(); //維持2US,符合大于1US的規(guī)范
}
dat=dat>>1; //寫入字節(jié)右移1位
}
}
bit Convert(void)
{
if(Reset()==0) //復(fù)位DS18B20
{
WriteByte(0xcc); //寫入跳過序列號命令字 Skip Rom
WriteByte(0x44); //寫入溫度轉(zhuǎn)換命令字 Convert T
return 1; //啟動溫度轉(zhuǎn)換成功
}
else
{
return 0; //啟動溫度轉(zhuǎn)換失敗
}
}
void ReadFlash(void)
{
unsigned char Lsb,Msb;
if(Reset()==0) //復(fù)位DS18B20
{
WriteByte(0xcc); //寫入跳過序列號命令字 Skip Rom
WriteByte(0xbe); //寫入讀取數(shù)據(jù)令字 Read Scratchpad
Lsb=ReadByte(); //讀出第一個字節(jié)暫存于LSB
Msb=ReadByte(); //讀出第二個字節(jié)暫存于MSB
temp1=Lsb&0x0f; //temp1內(nèi)裝溫度參數(shù)的小數(shù)部分
temp2=(Lsb>>4)|(Msb<<4);//temp2內(nèi)裝溫度參數(shù)的整數(shù)部分
}
else
{
temp1=0; //如果復(fù)位失敗,溫度參數(shù)清零
temp2=0; //如果復(fù)位失敗,溫度參數(shù)清零
}
}
void LCD1602_busy(void)
{
P0_7=1; //將P0.7置1,為讀狀態(tài)做準(zhǔn)備
RS=0; //RS=0、RW=1、E=1時,忙信號輸出到DB7,由P0.7讀入
RW=1; //RS=0、RW=1、E=1時,忙信號輸出到DB7,由P0.7讀入
E=1; //RS=0、RW=1、E=1時,忙信號輸出到DB7,由P0.7讀入
while(P0_7==1); //由P0.7讀入1,表示1602液晶忙,需要等待
E=0; //讀完以后,恢復(fù)E的電平
}
void LCD1602_Write_com(unsigned char combuf)
{
RS=0; //選擇指令寄存器
RW=0; //選擇寫狀態(tài)
P0=combuf; //將命令字通過P0口送至DB
E=1; //E高電平將命令字寫入1602液晶
E=0; //寫完以后,恢復(fù)E的電平
}
void LCD1602_Write_com_busy(unsigned char combuf)
{
LCD1602_busy(); //調(diào)用忙檢測函數(shù)
LCD1602_Write_com(combuf); //調(diào)用忙檢測函數(shù)
}
void LCD1602_Write_data_busy(unsigned char databuf)
{
LCD1602_busy(); //調(diào)用忙檢測函數(shù)
RS=1; //選擇數(shù)據(jù)寄存器
RW=0; //選擇寫狀態(tài)
P0=databuf; //將命令字通過P0口送至DB
E=1; //E高電平將命令字寫入1602液晶
E=0; //寫完以后,恢復(fù)E的電平
}
void LCD1602_Write_address(unsigned char x,unsigned char y)
{
x&=0x0f; //列地址限制在0-15間
y&=0x01; //行地址限制在0-1間
if(y==0) //如果是第一行
LCD1602_Write_com_busy(x|0x80); //將列地址寫入
else //如果是第二行
LCD1602_Write_com_busy((x+0x40)|0x80); //將列地址寫入
}
void LCD1602_init(void)
{
Delay(150); //調(diào)用延時函數(shù)
LCD1602_Write_com(0x38); //8位數(shù)據(jù)總線,兩行顯示模式,5*7點(diǎn)陣顯示
Delay(50); //調(diào)用延時函數(shù)
LCD1602_Write_com(0x38); //8位數(shù)據(jù)總線,兩行顯示模式,5*7點(diǎn)陣顯示
Delay(50); //調(diào)用延時函數(shù)
LCD1602_Write_com(0x38); //8位數(shù)據(jù)總線,兩行顯示模式,5*7點(diǎn)陣顯示
LCD1602_Write_com_busy(0x38); //8位數(shù)據(jù)總線,兩行顯示模式,5*7點(diǎn)陣顯示
LCD1602_Write_com_busy(0x08); //顯示功能關(guān),無光標(biāo)
LCD1602_Write_com_busy(0x01); //清屏
LCD1602_Write_com_busy(0x06); //寫入新的數(shù)據(jù)后,光標(biāo)右移,顯示屏不移動
LCD1602_Write_com_busy(0x0C); //顯示功能開,無光標(biāo)
}
void LCD1602_Disp(unsigned char x,unsigned char y,unsigned char buf)
{
LCD1602_Write_address(x,y); //先將地址信息寫入
LCD1602_Write_data_busy(buf); //再寫入要顯示的數(shù)據(jù)
}
void main(void) //主函數(shù),單片機(jī)開機(jī)后就是從這個函數(shù)開始運(yùn)行
{
LCD1602_init(); //調(diào)用1602液晶初始化函數(shù)
while(1) //死循環(huán),單片機(jī)初始化后,將一直運(yùn)行這個死循環(huán)
{
if(Convert()==1) //啟動轉(zhuǎn)換
{
ReadFlash(); //讀取溫度
if(temp2>99) temp2=99;
if(temp1>15) temp1=0;
LCD1602_Disp(0,0,temp2/10+'0'); //溫度整數(shù)部分十位
LCD1602_Disp(1,0,temp2%10+'0'); //溫度整數(shù)部分個位
LCD1602_Disp(2,0,'.'); //.
LCD1602_Disp(3,0,table[temp1]+'0'); //溫度小數(shù)部分
LCD1602_Disp(4,0,0xdf); //.
LCD1602_Disp(5,0,0x43); //C
}
}
}
|
|