|
6黑幣
編寫了程序但是仿真不成功,溫度顯示不正常而且改變不了溫度,三個按鈕的功能均沒反應!求助大神!
以下是仿真不成功的程序:
#include <reg52.h>
#include<intrins.h>
#include <math.h>
#define uchar unsigned char
#define uint unsigned int
sbit RW = P2^1; //定義LCD的讀、寫選擇端
sbit RS = P2^0; //定義LCD的數據、命令選擇端
sbit EN = P2^2; //定義LCD的使能信號端
sbit DS = P3^3; //定義DS18B20的IO口
sbit L=P2^3; //綠燈
sbit H=P2^6; //紅燈
sbit LS=P3^7; //蜂鳴器
sbit k1=P1^1; //顯示64位的ROM
sbit k2=P1^7; //顯示當前溫度
sbit k3=P1^4; //顯示溫度上限及下線,并支持調節
uchar k=2; //當前溫度顯示標志位
uchar table0[] = " Current Temp : "; //當前溫度
uchar table1[] = " -- ROM CODE -- "; //顯示DS18B20的ROM
uchar table2[] = "ALARM TEMP Hi Lo"; //顯示上下限溫度
uchar table3[] = "Hi: Lo: ";
uchar table4[] = {0,0,0,0,0,0,0,0};
uchar tempHL[] = { 20, 1}; //上下限溫度的初始值
void delayms(uint a) //延時函數
{
uint i,j;
for(i = a; i > 0; i--) for(j = 100; j > 0; j--);
}
void writecom(uchar com) //寫地址,也就是顯示的數據的位置
{
RS = 0;
P0 = com;
EN = 1;
delayms(1);
EN = 0;
}
void writedata(uchar dat) //寫數據,也就是顯示的數據
{
RS = 1;
P0 = dat;
EN = 1;
delayms(1);
EN = 0;
}
void init() //LCD初始化
{
RW = 0;
writecom(0x38); //16*2顯示,5*7點陣
writecom(0x0c);
writecom(0x06);
writecom(0x01); //清除LCD的顯示內容
}
void writestring(uchar * str, uchar length) //寫數據的過度函數。length:長度
{
uchar i;
for(i = 0; i < length; i++)
{
writedata(str[i]);
}
}
void delay(uint num) //延時函數
{
while( --num );
}
DSinit(void) //初始化ds1820
{
DS= 1; //DS復位
delay(8); //稍做延時
DS= 0; //將DS拉低
delay(90); //精確延時 大于 480u
DS= 1; //拉高總線
delay(110);
DS= 1;
}
uchar read_bit(void) //讀一位(bit)
{
uchar i;
DS= 0; //將DS拉低開始讀時間隙
DS= 1; // then return high
for (i=0; i<3; i++); // 延時15μs
return(DS); // 返回 DS線上的電平值
}
uchar readbyte() // 讀一個字節
{
uchar i = 0;
uchar dat = 0;
for (i=0;i<8;i++)
{ // 讀取字節,每次讀取一個字節
if(read_bit()) dat|=0x01<<i; // 然后將其左移
delay(4);
}
return (dat);
}
void write_bit(char bitval) //寫一位
{
DS= 0; // 將DS拉低開始寫時間隙
if(bitval==1) DS=1; // 如果寫1,DS返回高電平
delay(5); // 在時間隙內保持電平值,
DS= 1; // delay函數每次循環延時16μs,因此delay(5) = 104μs
}
void writebyte(uchar dat) //寫一個字節
{
uchar i = 0;
uchar temp;
for (i=0; i<8; i++) // 寫入字節, 每次寫入一位
{
temp = dat>>i;
temp &= 0x01;
write_bit(temp);
}
delay(5);
}
void sendchangecmd() //DS18B20?開始獲取溫度并轉換
{
DSinit(); //DS18B20復位
delayms(1);
writebyte(0xcc); //寫跳過讀ROM指令
writebyte(0x44); //寫溫度轉換指令
}
void sendreadcmd() //讀取寄存器中存儲的溫度數據
{
DSinit(); //DS18B20復位
delayms(1);
writebyte(0xcc); //寫跳過讀ROM指令
writebyte(0xbe); //讀取暫存器的內容
}
int gettmpvalue()
{
uint tmpvalue;
float t;
uchar low, high;
sendreadcmd(); //讀取寄存器中存儲的溫度數據
low = readbyte(); //讀取低八位
high = readbyte(); //讀取高八位
tmpvalue = high;
tmpvalue <<= 8; //高八位左移八位
tmpvalue |= low; //兩個字節組合為1個字
t = tmpvalue * 0.0625 * 100; //分辨率為0.0625,在此將值擴大100倍
return t;
}
void display(int v) //顯示子函數
{
uchar i;
uchar datas[] = {0, 0, 0, 0, 0, 0, 0, 0}; //定義緩存數組datas
uint tmp = abs(v); //abs是求絕對值函數
datas[0] = tmp % 10000 / 1000;
datas[1] = tmp % 1000 / 100;
datas[2] = tmp % 100 / 10;
datas[3] = tmp % 10;
datas[4] = 80; //空格的前30的ASCALL碼
datas[5] = 175; //溫度符號的前30的ASCALL碼
datas[6] = 19; //C的前30的ASCALL碼
writecom(0xc0+3);
if(v < 0) //當V小于0則輸出負號
{
writestring("- ", 2);
}
else
{
writestring("+ ", 2); //當V大于0則輸出正號
}
for(i = 0; i != 7; i++)
{
writedata('0'+datas[i]); //顯示溫度
if(i == 1)
{
writedata('.'); //顯示溫度的小數點
}
}
}
void Read_RomCord() //讀取64位序列碼
{
unsigned char j;
DSinit();
writebyte(0x33); // 讀序列碼的操作
for (j = 0; j < 8; j++)
{
table4[j] = readbyte();
}
}
void Disp_RomCode() //數據轉換與顯示
{
uchar j,i;
writecom(0xc0); //LCD第二行初始位置
for(j=0;j<8;j++)
{
i=((table4[j]&0xf0)>>4);
if(i>9)
{ i=i+0x37;}
else{i=i+0x30;}
writedata(i); //高位數顯示
i=(table4[j]&0x0f);
if(i>9)
{i=i+0x37;}
else {i=i+0x30;}
writedata(i); //低位數顯示
}
}
void lcd_display() //按鍵掃描
{
uchar i,m;
uchar hl[]={0, 0, 0, 0, 0};
if(k1 == 0) k = 1;
if(k2 == 0) k = 2;
if(k3 == 0) k = 3;
if(tempHL[0]<=gettmpvalue()/100)
delayms(100),LS=!LS,H=~H;
else
LS=1,H=1;
if(m==1)
{
if(tempHL[1]>=gettmpvalue()/100)
delayms(100),LS=!LS,L=~L;
else
LS=1,L=1;
}
switch(k)
{
case 1: //顯示64位的ROM
writecom(0x01);
writecom(0x80);
writestring(table1, 16);
Read_RomCord(); //讀取64位序列碼
Disp_RomCode(); //顯示64位序列
delayms(750); //溫度轉換時間需要750ms以上
break;
case 2: //顯示當前溫度
delayms(750); //溫度轉換時間需要750ms以上
sendchangecmd();
writecom(0x01);
writecom(0x80);
writestring(table0, 16);
display(gettmpvalue());
break;
case 3: //顯示溫度上限及下線,并支持調節
writecom(0x80);
writestring(table2, 16);
writecom(0xC0);
writestring(table3, 16);
hl[0] = tempHL[0] / 10;
hl[1] = tempHL[0] % 10;
if(m==1) hl[2] = 80;
if(m==0) hl[2] = 128;
hl[3] = tempHL[1] / 10;
hl[4] = tempHL[1] % 10;
writecom(0xC0+4);
for(i = 0; i != 2; i++)
{
writedata('0'+hl[i]); //顯示上限溫度
}
writecom(0xC0+11);
for(i = 2; i != 5; i++)
{
writedata('0'+hl[i]); //顯示下限溫度
}
break;
}
}
void main()
{
sendchangecmd(); //讀取寄存器中存儲的溫度數據
init(); //LCD初始化
writecom(0x80); //選擇LCD第一行
writestring(table0, 16); //顯示當前溫度的英文字母
while(1)
{
lcd_display(); //掃描按鍵
}
}
|
|