?? ds1820.txt
字號:
#define uchar unsigned char
#define ulong unsigned long int
#define DS18b20io P2_0 //DS18B20數據線
sbit ACC0=ACC^0;
sbit ACC7=ACC^7;
uchar DS18b20_temp[2]; //讀出的18b20溫度值存放地
uchar display_date[4]; //要顯示的四位數據的存放地
uchar dispaly_dot; //LED顯示小數點位置
uchar *display_point; //LED顯示數據存放地指針
void delay_5us(uchar y) //(2.17*y+5)us延時,11.0592M晶振
{
while(--y);
}
void delay(uint v) //1ms單位延時(實際是0.998ms)。50是49ms;500是490ms,還算準. 晶振11.0592M
{
uchar i;
while(v--)
{
for(i=0;i<111;i++);
}
}
void display(uchar *z,uchar spot) //數碼管顯示子程序。入口是要顯示的4位數字(0、1、2、3。。。)及小數點位置,0/1/2/3四個位置,其他數字表示無小數點。BCD碼轉換等應由前期解決。
{ //為避免閃爍,應在主程序里不停調用這個子程序.它大約耗時4ms.因此凡是需要4ms以上延時的地方,最好都用它來延時.
uchar i;
for(i=0;i<4;i++)
{
P2|=0xf0; //關所有4個數碼管
switch(*(z+i))
{
case 0:P0=0xc0;break; //共陽的段碼表。若LED共陰,則碼表取反。
case 1:P0=0xf9;break;
case 2:P0=0xa4;break;
case 3:P0=0xb0;break;
case 4:P0=0x99;break;
case 5:P0=0x92;break;
case 6:P0=0x82;break;
case 7:P0=0xf8;break;
case 8:P0=0x80;break;
case 9:P0=0x90;break;
case 12:P0=0xbf;break; //“-”,表示零下溫度
case 13:P0=0xa7;break; //“c”,表示溫度
case 15:P0=0xff;break; //不亮
default:P0=0xff; //不亮
}
if(spot==i)
P0&=0x7f;
P2&=~(0x80>>i);
delay(1); //亮1mS
}
P2|=0xf0; //關所有4個數碼管,否則最后一位就會格外亮.
}
void DS18b20_w_byte(uchar x) //向18b20寫一個字節.x是要寫的內容
{
uchar i;
for(i=0;i<8;i++)
{
DS18b20io=0;
_nop_(); //要求>1us,但又不能超過15us
_nop_();
if(0x01&x)
DS18b20io=1;
delay_5us(30); //要求總時間在60-120us
DS18b20io=1; //釋放總線
_nop_(); //要求>1us
x=x>>1;
}
}
uchar DS18b20_r_byte(void) //從18b20讀一個字節.返回讀到的內容
{
uchar i,j;
j=0;
for(i=0;i<8;i++)
{
j=j>>1;
DS18b20io=0;
_nop_(); //要求>1us,但又不能超過15us
_nop_();
DS18b20io=1; //釋放總線
_nop_();
_nop_();
if(DS18b20io)
j|=0x80;
delay_5us(30); //要求總時間在60-120us
DS18b20io=1; //釋放總線
_nop_(); //要求>1us
}
return j;
}
void DS18b20_int(void) //每次上電都給18b20初始化,設置18b20的參數.
{
DS18b20io=0;
delay_5us(255); //要求480-960us
DS18b20io=1; //釋放總線
delay_5us(30); //要求60-120us
if(DS18b20io==0)
{
delay_5us(200); //要求釋放總線后480us內結束復位
DS18b20io=1; //釋放總線
DS18b20_w_byte(0xcc); //發送Skip ROM命令
DS18b20_w_byte(0x4e); //發送"寫"暫存RAM命令
DS18b20_w_byte(0x00); //溫度報警上限設為0
DS18b20_w_byte(0x00); //溫度報警下限設為0
DS18b20_w_byte(0x3f); //將18b20設為10位,精度就是0.25度
DS18b20io=0;
delay_5us(255); //要求480-960us
DS18b20io=1; //釋放總線
delay_5us(240); //要求釋放總線后480us內結束復位
DS18b20io=1; //釋放總線
}
}
void DS18b20_readTemp(void) //讀18b20溫度值
{
uchar i;
DS18b20io=0;
delay_5us(255); //要求480-960us
DS18b20io=1; //釋放總線
delay_5us(30); //要求60-120us
if(DS18b20io==0)
{
delay_5us(200); //要求釋放總線后480us內結束復位
DS18b20io=1; //釋放總線
DS18b20_w_byte(0xcc); //發送Skip ROM命令
DS18b20_w_byte(0x44); //發送溫度轉換命令
DS18b20io=1; //釋放總線
for(i=0;i<50;i++) //10位方式需要180ms.這里用顯示子程序代替延時,可以避免LED閃爍,一舉兩得
display(display_point,dispaly_dot);
DS18b20io=0;
delay_5us(255); //要求480-960us
DS18b20io=1; //釋放總線
delay_5us(30); //要求60-120us
if(DS18b20io==0)
{
delay_5us(200); //要求釋放總線后480us內結束復位
DS18b20io=1; //釋放總線
DS18b20_w_byte(0xcc); //發送Skip ROM命令
DS18b20_w_byte(0xbe); //發送"讀"暫存RAM命令
DS18b20_temp[0]=DS18b20_r_byte(); //讀溫度低字節
DS18b20_temp[1]=DS18b20_r_byte(); //讀溫度高字節
DS18b20io=0;
delay_5us(255); //要求480-960us
DS18b20io=1; //釋放總線
delay_5us(240); //要求釋放總線后480us內結束復位
DS18b20io=1; //釋放總線
}
}
}
void main(void)
{
uchar zz;
uint DS18b20_tempdate; //為整理讀到的溫度值而設的中間結果存放地
display_point=&display_date[0];
EA=0;
DS18b20_int();
EA=1;
while(1)
{
EA=0;
DS18b20_readTemp();
EA=1;
if(DS18b20_temp[1]&0xf8) //顯示零下溫度,小數不顯示,有負標志
{
DS18b20_tempdate=DS18b20_temp[1]<<8;
DS18b20_tempdate+=DS18b20_temp[0];
DS18b20_tempdate&=0x03ff;
DS18b20_tempdate=DS18b20_tempdate>>2;
DS18b20_tempdate-=1;
DS18b20_tempdate=~DS18b20_tempdate; //以上是將18b20里的負溫度補碼轉換為原碼
DS18b20_tempdate=DS18b20_tempdate/4;
zz=(uchar)(DS18b20_tempdate&0x00ff); //這是整數位,小數位忽略不顯示
display_date[0]=12; //負溫度標志“-”
display_date[1]=zz/10; //溫度十位數
display_date[2]=zz%10; //溫度個位數
dispaly_dot=9;
}
else
{
DS18b20_tempdate=(((DS18b20_temp[1]&0x07)<<8)+DS18b20_temp[0])>>2;
DS18b20_temp[1]=DS18b20_tempdate>>2; //這是整數位
DS18b20_temp[0]=DS18b20_tempdate&0x03; //這是小數位
if(DS18b20_temp[1]>=100) //如果超過100度,就不顯示小數位
{ //顯示100度以上溫度,無小數位
display_date[0]=DS18b20_temp[1]/100; //溫度百位數
display_date[1]=(DS18b20_temp[1]-100)/10; //溫度十位數
display_date[2]=(DS18b20_temp[1]-100)%10; //溫度個位數
dispaly_dot=9;
}
else //0-100度,顯示一位小數
{
display_date[0]=DS18b20_temp[1]/10; //溫度十位數
display_date[1]=DS18b20_temp[1]%10; //溫度個位數
switch(DS18b20_temp[0])
{
case 0:display_date[2]=0;break;
case 1:display_date[2]=2;break;
case 2:display_date[2]=5;break;
case 3:display_date[2]=8;break;
default:display_date[2]=0;
}
dispaly_dot=1;
}
}
display_date[3]=13; //顯示溫度符號“c”
display(display_point,dispaly_dot); //實際顯示溫度
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -