51单片机两个IO口分别接ds18b20程序

51单片机两个IO口分别接ds18b20程序,第1张

//DS从机程序

#include <reg52h>

#include <intrinsh>

#define uchar unsigned char

#define uint unsigned int

#define SLAVE 0x01

#define BN 6

sbit LCD_RS = P2^5; /定义LCD控制端口/

sbit LCD_RW = P2^6;

sbit LCD_EN = P2^7;

sbit DS1=P1^0;

sbit DS2=P1^1;

sbit key3=P3^5;

sbit tem=P3^3;

sbit win=P3^4;

sbit key1=P3^6;

sbit key2=P3^7;

uint temp1,temp2,tempH,tempL; // variable of temperature

uchar flag1,aa,we;

uchar A1,A2,A3,A4,B1,B2,B3,B4; // sign of the result positive or negative

uchar dis1[16]={76,45,84,'0','0','','0',32,32,72,45,84,'0','0','','0'};

uchar dis2[16]={48,49,32,'0','0','','0',32,32,48,50,32,'0','0','','0'};

uchar code tab[] = {'0','1','2','3','4','5','6','7','8','9'};

uchar trbuf[6];

bit tready;

bit rready;

void str(void);

void sre(void);

void delay(int ms)

{

int i;

while(ms--)

{

for(i = 0; i< 250; i++)

{

_nop_();

_nop_();

_nop_();

_nop_();

}

}

}

//

/ /

/检查LCD忙状态 /

/lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据。 /

/ /

//

bit lcd_busy()

{

bit result;

LCD_RS = 0;

LCD_RW = 1;

LCD_EN = 1;

_nop_();

_nop_();

_nop_();

_nop_();

result = (bit)(P0&0x80);

LCD_EN = 0;

return result;

}

//

/ /

/写指令数据到LCD /

/RS=L,RW=L,E=高脉冲,D0-D7=指令码。 /

/ /

//

void lcd_wcmd(uchar cmd)

{

while(lcd_busy());

LCD_RS = 0;

LCD_RW = 0;

LCD_EN = 0;

_nop_();

_nop_();

P0 = cmd;

_nop_();

_nop_();

_nop_();

_nop_();

LCD_EN = 1;

_nop_();

_nop_();

_nop_();

_nop_();

LCD_EN = 0;

}

//

/ /

/写显示数据到LCD /

/RS=H,RW=L,E=高脉冲,D0-D7=数据。 /

/ /

//

void lcd_wdat(uchar dat)

{

while(lcd_busy());

LCD_RS = 1;

LCD_RW = 0;

LCD_EN = 0;

P0 = dat;

_nop_();

_nop_();

_nop_();

_nop_();

LCD_EN = 1;

_nop_();

_nop_();

_nop_();

_nop_();

LCD_EN = 0;

}

//

/ /

/ 设定显示位置 /

/ /

//

void lcd_pos(uchar pos)

{

lcd_wcmd(pos|0x80); //数据指针=80+地址变量

}

//

/ /

/ LCD初始化设定 /

/ /

//

void lcd_init()

{

lcd_wcmd(0x38); //162显示,57点阵,8位数据

delay(5);

lcd_wcmd(0x38);

delay(5);

lcd_wcmd(0x38);

delay(5);

lcd_wcmd(0x0c); //显示开,关光标

delay(5);

lcd_wcmd(0x06); //移动光标

delay(5);

lcd_wcmd(0x01); //清除LCD的显示内容

delay(5);

lcd_wcmd(0x06); //向右移动光标

delay(5);

}

//

/ /

/ 闪动子程序 /

/ /

//

void flash()

{

delay(600); //控制停留时间

lcd_wcmd(0x08); //关闭显示

delay(200); //延时

lcd_wcmd(0x0c); //开显示

delay(200); //延时

lcd_wcmd(0x08); //关闭显示

delay(200); //延时

lcd_wcmd(0x0c); //开显示

delay(200);

}

/void delay(uint count) //delay

{

uint i;

while(count)

{

i=100;

while(i>0)

i--;

count--;

}

} /

///////功能:串口初始化,波特率9600,方式1///////

void Init(void)

{

TMOD=0x20;

TL1=0xfd;

TH1=0xfd;

PCON=0x00;

TR1=1;

SCON=0xf0;

ES=1;

EA=1;

}

void dsreset(uchar DS) //send reset and initialization command 18B20复位,初始化函数

{

uint i;

if(DS==1)

{

DS1=0;

i=103;

while(i>0)i--;

DS1=1;

i=4;

while(i>0)i--;

}

if(DS==2)

{

DS2=0;

i=103;

while(i>0)i--;

DS2=1;

i=4;

while(i>0)i--;

}

}

bit tmpreadbit(uchar DS) //read a bit 读DS2 1位数据函数

{

uint i;

bit dat;

if(DS==1)

{

DS1=0;i++; //i++ for delay

DS1=1;i++;i++;

dat=DS1;

i=8;while(i>0)i--;

}

if(DS==2)

{

DS2=0;i++; //i++ for delay

DS2=1;i++;i++;

dat=DS2;

i=8;while(i>0)i--;

}

return (dat);

}

uchar tmpread(uchar DS) //read a byte date 读1字节函数

{

uchar i,j,dat;

dat=0;

if(DS==1)

{

for(i=1;i<=8;i++)

{

j=tmpreadbit(1);

dat=(j<<7)|(dat>>1); //读出的数据最低位在最前面,这样刚好一个字节在DAT里

}

}

if(DS==2)

{

for(i=1;i<=8;i++)

{

j=tmpreadbit(2);

dat=(j<<7)|(dat>>1); //读出的数据最低位在最前面,这样刚好一个字节在DAT里

}

}

return(dat);

}

void tmpwritebyte(uchar dat,uchar DS) //write a byte to ds18b20 向1820写一个字节数据函数

{

uint i;

uchar j;

bit testb;

for(j=1;j<=8;j++)

{

testb=dat&0x01;

dat=dat>>1;

if(DS==1)

{

if(testb) //write 1

{

DS1=0;

i++;i++;

DS1=1;

i=8;while(i>0)i--;

}

else

{

DS1=0; //write 0

i=8;while(i>0)i--;

DS1=1;

i++;i++;

}

}

if(DS==2)

{

if(testb) //write 1

{

DS2=0;

i++;i++;

DS2=1;

i=8;while(i>0)i--;

}

else

{

DS2=0; //write 0

i=8;while(i>0)i--;

DS2=1;

i++;i++;

}

}

}

}

void tmpchange(uchar DS) //DS18B20 begin change 开始获取数据并转换

{

if(DS==1)

{

dsreset(1);

delay(1);

tmpwritebyte(0xcc,1); // address all drivers on bus 写跳过读ROM指令

tmpwritebyte(0x44,1);

} // initiates a single temperature conversion 写温度转换指令

if(DS==2)

{

dsreset(2);

delay(1);

tmpwritebyte(0xcc,2); // address all drivers on bus 写跳过读ROM指令

tmpwritebyte(0x44,2);

} // initiates a single temperature conversion 写温度转换指令

}

uint tmp1(void) //get the temperature 读取寄存器中存储的温度数据

{

float tt;

uchar a,b;

dsreset(1);

delay(1);

tmpwritebyte(0xcc,1);

tmpwritebyte(0xbe,1);

a=tmpread(1); //读低8位

b=tmpread(1); //读高8位

temp1=b;

temp1<<=8; //two byte compose a int variable 两个字节组合为1个字

temp1=temp1|a;

tt=temp100625; //温度在寄存器中是12位,分辨率是00625

temp1=tt10+05; //乘10表示小数点后只取1位,加05是四折五入

//temp1=temp1+5; //误差补偿

return temp1;

}

uint tmp2( void) //get the temperature 读取寄存器中存储的温度数据

{

float tt;

uchar a,b;

dsreset(2);

delay(1);

tmpwritebyte(0xcc,2);

tmpwritebyte(0xbe,2);

a=tmpread(2); //读低8位

b=tmpread(2); //读高8位

temp2=b;

temp2<<=8; //two byte compose a int variable 两个字节组合为1个字

temp2=temp2|a;

tt=temp200625; //温度在寄存器中是12位,分辨率是00625

temp2=tt10+05; //乘10表示小数点后只取1位,加05是四折五入

//temp2=temp2+5; //误差补偿

return temp2;

}

void delay10ms() //delay

{

uchar a,b;

for(a=10;a>0;a--)

for(b=60;b>0;b--);

}

uchar display(uint temp1,uint temp2) //显示程序

{

uchar i;

A1=temp1/100;

A2=temp1%100/10;

A3=temp1%100%10;

B1=temp2/100;

B2=temp2%100/10;

B3=temp2%100%10;

trbuf[0]=A1;

trbuf[1]=A2;

trbuf[2]=A3;

trbuf[3]=B1;

trbuf[4]=B2;

trbuf[5]=B3;

dis1[3]=tab[tempL10/100];

dis1[4]=tab[tempL10%100/10];

dis1[6]=tab[tempL10%100%10];

dis1[12]=tab[tempH10/100];

dis1[13]=tab[tempH10%100/10];

dis1[15]=tab[tempH10%100%10];

dis2[3]=tab[A1];

dis2[4]=tab[A2];

dis2[6]=tab[A3];

dis2[12]=tab[B1];

dis2[13]=tab[B2];

dis2[15]=tab[B3];

delay(1);

lcd_pos(0); //设置显示位置为第一行的第1个字符

delay(2);

for(i=0;i<16;i++)

{

lcd_wdat(dis1[i]);

}

delay(2);

lcd_pos(0x40);

delay(2);

for(i=0;i<16;i++)

{

lcd_wdat(dis2[i]);

}

return (A1,A2,A3,B1,B2,B3);

}

void TemC()

{

if(temp1<=(tempL10)||temp2<=(tempL10)) tem=0;

else tem=1;

if (temp1>=(tempH10)||temp2>=(tempH10)) win=0;

else win=1;

}

uchar chan()

{

if(key1==0)

{

tempL++;

while(key1==0);

if(tempL>35)

tempL=0;

}

if(key2==0)

{

tempH++;

while(key2==0);

if(tempH>35)

tempH=0;

}

return (tempH,tempL);

}

//

void main()

{ //uchar a;

//uchar i;

delay(10);

lcd_init();

Init();

tempH=35;

tempL=15;

while(1)

{

tmpchange(1);

tmpchange(2);

tmp1();

tmp2();

chan();

TemC();

display(temp1,temp2);

tready=1;

rready=1;

}

}

void ssio(void)interrupt 4

{

uchar a;

RI=0;

ES=0;

if(SBUF!=SLAVE)

{

ES=1;

goto reti;

}

SM2=0;

SBUF=SLAVE;

while(TI!=1);

TI=0;

while(RI!=1);

RI=0;

if(RB8==1)

{

SM2=1;

ES=1;

goto reti;

}

a=SBUF;

if(a==0x02)

{

if(tready==1)

SBUF=0x02;

else

SBUF=0x00;

while(TI!=1);

TI=0;

str();

goto reti;

}

else

{

SBUF=0x08;

while(TI!=1);

TI=0;

SM2=1;

ES=1;

}

reti:RI=0;

SM2=1;

ES=1;

}

void str(void)

{

uchar i;

tready=0;

while(1)

{

tmpchange(1);

tmpchange(2);

tmp1();

tmp2();

chan();

TemC();

display(temp1,temp2);

for(i=0;i<BN;i++)

{

SBUF=trbuf[i];

while(TI!=1);

TI=0;

}

while(RI!=1);

RI=0;

if(RB8==1)goto loop;

}

loop:SM2=1;

ES=1;

}

第一读取18B20的时候关闭任务切换,不进行任务调度第二通过任务通讯互斥量或者邮箱让其他任务挂起第三关闭中断第四将 *** 作18b20的任务优先级设置高点或者 *** 作时提升其任务优先级延时的话可以用ucos的延时函数也可以自己写,不过还是用ucos的好

/

必要 *** 作:连接传感器DS18B20到U6

/

#pragma db code

#include<AT89X52H>

#include "INTRINSH"

#define BUSY1 (DQ1==0) //定义busy信号

sbit LED_0=P1^0; //定义数码管控制脚为P1口的0-3脚

sbit LED_1=P1^1;

sbit LED_2=P1^2;

sbit LED_3=P1^3;

sbit DQ1=P3^5; //定义18B20单总线引脚

void display(unsigned char d1,unsigned char d2,unsigned char d3,unsigned char d4);//声明显示函数

void ds_reset_1(void); //声明18B20复位函数

void wr_ds18_1(char dat); //声明18B20写入函数

void time_delay(unsigned char time);//声明延时函数

int get_temp_1(void); //声明18B20读入温度函数

void delay(unsigned int x); //声明延时函数

void read_ROM(void); //声明18B20读ROM函数

int get_temp_d(void); //声明获取温度函数

void ds_init(void); //声明18B20初始化函数

void ds_getT(void); //声明18B20获得温度显示值函数

/定义数码管段码=====0-9=====A-G=====/

unsigned char a[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,

0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};

//共阳极数码管的段码0 1 2 3 4 5 6 7 8 9 A B C D E F

/以下定义各种变量/

unsigned char ResultSignal;

int ResultTemperatureLH,ResultTemperatureLL,ResultTemperatureH;

unsigned char ROM[8];

unsigned char idata TMP;

unsigned char idata TMP_d;

unsigned char f;

unsigned char rd_ds18_1();

unsigned int TemH,TemL; //温度的整数部分和小数部分

unsigned int count; //定义小数计算部分

void main()

{

ds_init(); //18B20初始化

while(1)

{

ds_getT(); //使用该函数获得温度,整数部分存储到TemH,小数部分存储到count的低8位

display((TemH/10)%10,TemH%10,((count/10)%10),(count%10));

//温度发送到数码管显示

}

}

/18B20初始化函数/

void ds_init(void)

{

unsigned int k=0;

ds_reset_1();

ds_reset_1(); //reset

wr_ds18_1(0xcc); //skip rom

_nop_();

wr_ds18_1(0x7f);

ds_reset_1();

wr_ds18_1(0xcc);

_nop_();

wr_ds18_1(0x44);

for(k=0;k<11000;k++)

time_delay(255);

ds_reset_1();

}

void ds_getT(void)

{

wr_ds18_1(0xcc);

wr_ds18_1(0xbe);

TemH=get_temp_1();

TemL=get_temp_d();

TemH&=0x00ff;

TemL&=0x00ff;

count=(TemH256+TemL)625;

}

/延时程序,单位us,大于10us/

void time_delay(unsigned char time)

{

time=time-10;

time=time/6;

while(time!=0)time--;

}

//

/ reset ds18b20 /

//

void ds_reset_1(void)

{

unsigned char idata count=0;

DQ1=0;

time_delay(240);

time_delay(240);

DQ1=1;

return;

}

void check_pre_1(void)

{

while(DQ1);

while(~DQ1);

time_delay(30);

}

void read_ROM(void)

{

int n;

ds_reset_1();

check_pre_1();

wr_ds18_1(0x33);

for(n=0;n<8;n++){ROM[n]=rd_ds18_1();}

}

//

/ Read a bit from 1820 位读取 /

//

bit tmrbit_1(void)

{

idata char i=0;

bit dat;

DQ1=0;_nop_();

DQ1=1;

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

dat = DQ1;

time_delay(50);

return dat;

}

//

/ read a bety from ds18b20 字节读取 /

//

unsigned char rd_ds18_1()

{

unsigned char idata i,j,dat=0;

for(i=1;i<=8;i++)

{

j=tmrbit_1();

dat=(j<<(i-1))|dat;

}

return dat;

}

//

/ write a bety from ds18b20 写字节 /

//

void wr_ds18_1(char dat)

{

signed char idata i=0;

unsigned char idata j;

bit testb;

for(j=1;j<=8;j++)

{

testb=dat & 0x01;

dat = dat>>1;

if(testb)

{

DQ1=0;

_nop_();

_nop_();

DQ1=1;

time_delay(60);

}

else

{

DQ1=0;

time_delay(50);

DQ1=1;

_nop_();

_nop_();

}

}

}

int get_temp_1(void)

{

unsigned char idata a=0,b=0;

unsigned char idata i;

EA=0;

ds_reset_1();

check_pre_1();

wr_ds18_1(0xcc);

wr_ds18_1(0x44);

while(BUSY1);

ds_reset_1();

check_pre_1();

wr_ds18_1(0xcc);

wr_ds18_1(0xbe);

a=rd_ds18_1();

b=rd_ds18_1();

i=b; /若b为1则为负温 /

i=(i>>4);

if(i==0)

{

f=0;

TMP=((a>>4)|(b<<4));

a=(a&0x0f);

if (a>8)

{

TMP=(TMP+1);

}

}

else

{

f=1;

a=a>>4;

b=b<<4;

TMP=(a|b);

TMP=~TMP;

TMP=(TMP+1);

}

EA=1;

return(TMP);

}

int get_temp_d(void)

{

unsigned char idata a=0,b=0;

unsigned char idata i,m;

EA=0;

ds_reset_1();//复位

check_pre_1();

wr_ds18_1(0xcc);

wr_ds18_1(0x44);

while(BUSY1);

ds_reset_1();

check_pre_1();

wr_ds18_1(0xcc);

wr_ds18_1(0xbe);

a=rd_ds18_1();

b=rd_ds18_1();

i=b; /若b为1则为负温 /

i=(i>>4);

if(i==0)

{

f=0;

TMP=((a>>4)|(b<<4));

a=(a&0x0f);

TMP_d=a;

}

else

{

f=1;

a=~a;

a=(a+1);

b=~b;

b=(b+1);

m=a;

a=a>>4;

b=b<<4;

TMP=(a|b);

m=(m&0x0f);

TMP_d=m;

}

EA=1;

return(TMP_d);

}void delay(unsigned int x)

{

unsigned int i;

for(i=0;i<x;i++);

}

void display(unsigned char d1,unsigned char d2,unsigned char d3,unsigned char d4)

{

P0=a[d1];

LED_0=0;

delay(100);

LED_0=1;

P0=a[d2] & 0x7f;

LED_1=0;

delay(100);

LED_1=1;

P0=a[d3];

LED_2=0;

delay(100);

LED_2=1;

P0=a[d4];

LED_3=0;

delay(100);

LED_3=1;

}

以上就是关于51单片机两个I/O口分别接ds18b20程序全部的内容,包括:51单片机两个I/O口分别接ds18b20程序、如何用STM32 DB18B20多点测温,求程序、51单片机温度传感器ds18b20、lcd1602液晶C程序等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zz/9968373.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-03
下一篇2023-05-03

发表评论

登录后才能评论

评论列表(0条)

    保存