PIC单片机DS18B20温度报警程序及仿真

2019-04-15 12:21发布

1、采用直插式数字温度传感器DS18B20;
2、本程序只显示正数部分,负数部分请自行解决,而且精度保留后两位;
3、使用DS18B20的跳过ROM指令,不支持单总线多个传感器的采集;
4、采用pic18f45k22芯片及共阴极数码管显示;
5、源程序如下:
*#include “p18f45k22.h”
*#define uchar unsigned char
*#define DQ PORTBbits.RB0
*#define DQ_HIGH() TRISBbits.RB0=1
*#define DQ_LOW() TRISBbits.RB0=0;DQ=0
uint tempr;
uchar a1,a2,a3,a4;//鏁扮爜绠℃樉绀虹殑鍊?
const uchar table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
const uchar table1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};
void delayus(uchar x);
void disp(uchar num1,uchar num2,uchar num3,uchar num4);
void init();
void reset();
void write_byte(uchar date);
uchar read_byte();
void get_tem();
int main(int argc, char const *argv[])
{
/* code */
init();
PORTA=0;
while(1){
get_tem();
if((tempr/100)>30)
PORTA=1;
else
PORTA=0;
} return 0; }
void init(){
ANSELA=0;
ANSELB=0;
ANSELC=0;
ANSELD=0;
TRISA=0;
TRISC=0;
TRISD=0;
}
void reset(){
uchar st=1;
DQ_HIGH();
Nop();Nop();
while(st){
DQ_LOW();
delayus(121);//750us
DQ_HIGH();
delayus(8);//70us
if(DQ==1)
st=1;
else
st=0;
delayus(80);
}
}
void write_byte(uchar date){
uchar i,temp;
DQ_HIGH();
Nop();Nop();
for(i=8;i>0;i–){
temp=date&0x01;
DQ_LOW();
delayus(0);//20us~15us
if(temp==1)
DQ_HIGH();
delayus(4);//45us
DQ_HIGH();
date=date>>1;
}
}
uchar read_byte(){
uchar i,date;
//static bit j;
for(i=8;i>0;i–){
date=date>>1;
DQ_HIGH();
Nop();Nop();
DQ_LOW();
Nop();Nop();Nop();Nop();Nop();Nop();
DQ_HIGH();
Nop();Nop();Nop();Nop();
//j=DQ;
//if(j==1)
if(DQ==1)
date=date|0x80;
delayus(1);
}
return (date);
}
void get_tem(){
uchar tem1,tem2;
uint i;
reset();
write_byte(0xcc);//璺宠繃 rom
write_byte(0x44);//娓╁害杞崲
// delayus(121);//750us for(i=125;i>0;i--){ disp(a1,a2,a3,a4); } reset(); write_byte(0xcc); write_byte(0xbe);//璇昏浆鎹㈢粨鏋?鍏堣鐨勬槸浣庡瓧鑺? tem1=read_byte(); tem2=read_byte(); tempr=(tem2*256+tem1)*6.25; a1=tempr/1000; a2=tempr%1000/100; a3=tempr%100/10; a4=tempr%10; }
void delayus(uchar x){
uchar i;
for(i=x;i>0;i–);
// delayus(0);//22
// delayus(1);//29
// delayus(4);//47
// delayus(8);//71
// delayus(80);//503
// delayus(121);//751
}
void disp(uchar num1,uchar num2,uchar num3,uchar num4)
{
PORTC=table[num1];//显示第一个数码管
PORTD=0xfe;//0010 0000
delayus(250);
PORTD=0xff;
PORTC=table1[num2];//显示第二个数码管
PORTD=0xfd;//0001 0000
delayus(250);
PORTD=0xff;
PORTC=table[num3];//显示第三个数码管
PORTD=0xfb;//0000 1000
delayus(250);
PORTD=0xff;
PORTC=table[num4];//显示第四个数码管
PORTD=0xf7;//0000 0100
delayus(250);
PORTD=0xff;
delayus(250);
}//部分文字乱码,不兼容,没办法;
6、仿真图:
这里写图片描述
7、这里补充说明一下,由于编译器的版本较低不能使用bit类型,没有配置状态字;
8、对于18B20的使用主要注意通信协议:延时有2us到750us不等,所以需要注意,这里以read_byte()函数为例,读取每个18B20的byte,首先我们要一个位一个位的读取,使用右移指令来或0x80这样就可以得到一个8位数据,最后返回date;