跪求指点DS18B20程序 一个温控系统的温度传感器部分 结构如下:

全部回答3
默认 最新
  • /***********ds18b20读一个字节**************/ unsigned char readonechar(void){uchar i=0; //定义i用于循环uchar dat = 0; //读取的8位数据for (i=8;i>0;i--) //8次循环{dq = 0; //拉低dq总线开始读时序dat>>=1; //dat左移一位dq = 1; //释放dq总线 if(dq) //如果dq=1,执dat|=0x80;(0x80即第7位为1,如果dq为1,即读取的数据为1,将dat的第7为置1,然后dat>>=1,循环8次结束,dat即为读取的数据) //dq=0,就跳过 dat|=0x80; delay_18b20(4); // 延时以完成此次读时 序,之后再读下一数据 } return(dat); //返回读取的dat}dq = dat&0x01;这句语句是错误的。dq为位变量,而dat为 unsigned char如果真要这么写的话,应该是这样 :dq = (bit)dat&0x01;把我写的给你做个参考吧:extern uchar8 sig; //sig判定温度符号/*延时函数*/void delay (int us) //delay-11.0592mhz 调用程序大约为24us,每次循环为16us{ int s; for(s=0;s} void delayms(int z) //z为毫秒数 { int x,y; for(x=z;x>0;x--) for(y=125;y>0;y--); } /*复位程序*/ unsigned char reset(void) { uchar8 presence; dq=0; //拉低总线。当总线停留在低电平480us-960us ,总线上所以器件都将被复位 delay(30); //保持低电平504us dq=1; //释放总线,让其恢复高电平 delay(3); //等待芯片应答信号 presence=dq; //获取应答信号 delay(25); //延时以完成整个时序 return(presence); //返回应答信号。有芯片应答返回0,否则返回1。 } /*写一位数据*/ void write_bit(char bitval) { dq=0; //拉低dq总线,开始时序 if(bitval==1) //如果写入的为1,则返回高电平 dq=1; delay(5); //延时104us,以完成整个时序 dq=1; } /*写一字节数据*/ void write_byte(char val) { uchar8 i,temp; for (i=0;i<8;i++) //写入一个字节的数据,一个时序中写一次 { temp=val>>i; //右移i位 temp&=0x01; //复制那位数据到temp write_bit(temp); //调用write_bit() } delay(5); //延时104us以完成此次时序,之后再写下一数据 } /*读一位数据*/ uchar8 read_bit(void) { uchar8 i; dq=0; //拉低dq,开始读时序 dq=1; //释放dq总线 for(i=0;i<3;i++); //从时序开始延时15us return(dq); //返回dq值 } /*读一字节数据*/ uchar8 read_byte(void) { uchar8 i,value=0; for(i=0;i<8;i++) { if(read_bit()) //读一字节数据,一个时序中读一次,并作移位处理 value|=0x01< delay(6); //延时以完成此次读时序,之后再读下一数据 } return(value); } /*温度转化*/ void tmconvert(void) { reset(); //复位 delay(1); write_byte(0xcc); //仅一个ds18b20 ,跳过rom write_byte(0x44); //温度变换 } /*读取温度*/ long gettm(void) { uchar8 lsb=0,msb=0; //用于存储读取的温度 long temp; reset(); //复位 write_byte(0xcc); //写指令,跳过rom,仅一个ds18b20 write_byte(0xbe); //写指令,读暂存存储器 lsb = read_byte(); //读lsb msb = read_byte(); //读msb sig=(msb>>4==0x0f); if(sig) //判断符号位是否为负值,是负值了,转去处理 { lsb=~lsb; //温度处理 msb=~msb; lsb=lsb+1; } temp=msb*256+lsb; //十六进制转换为10进制 temp=temp*100/16; //12位精度,最小分辨率为0.0625°c return temp; //获得0.01°c 的精度并返回 }
    0 点赞
  • #ifndef __18B20_H__#define __18B20_H__#include <reg52.h>#define uchar unsigned char#define uint unsigned intsbit DS=P2^2; //数据线uchar Decimals=0; //小数部分void Delay(uchar t){ while(--t);}/******************************************此延时函数针对的是12Mhz的晶振delay(0):延时518us 误差:518-2*256=6delay(1):延时7us (原帖写"5us"是错的)delay(10):延时25us 误差:25-20=5delay(20):延时45us 误差:45-40=5delay(100):延时205us 误差:205-200=5delay(200):延时405us 误差:405-400=5*******************************************/void delay_ms(uint t){ uint i,j; for(i=0;i<t;i++) for(j=0;j<125;j++);}/**********************************************************函数功能:DS18B20初始化函数入口函数:无出口函数:无**********************************************************/void DS18B20_Init(void) { bit n; DS=1; Delay(1); DS=0; Delay(250); // 480~960us DS=1; Delay(20); // 15~60us n=DS; Delay(100); // 60~240us DS=1; Delay(1);}/**********************************************************函数功能:DS18B20写一个字节入口函数:dat--要写的数据出口函数:无**********************************************************/void Write_Byte(uchar dat) { uchar i=0; for(i=0;i<8;i++) { DS=0; DS=dat & 0x01; Delay(10); DS=1; dat>>=1; } Delay(4);}/**********************************************************函数功能:DS18B20读一个字节入口函数:无出口函数:value--读取的数据**********************************************************/uchar Read_Byte(void) { uchar i,value; for(i=0;i<8;i++) { DS=0; value>>=1; DS=1; if(DS) value|=0x80; Delay(10); } return value;}/**********************************************************函数功能:读取18B20内的温度入口函数:无出口函数:temper--温度的整数部分, Decimals--小数部分**********************************************************/uchar Read_Temper(void) //读取温度{ static bit flag=0; uchar a,b,temper; DS18B20_Init(); Write_Byte(0xcc); //跳过匹配ROM Write_Byte(0x44); //开始转换温度 if(flag==0) //第一次温度转化需要给它足够的时间 { delay_ms(1000); //温度转换需要时间 93.75ms flag=1; } DS18B20_Init(); Write_Byte(0xcc); //跳过匹配ROM Write_Byte(0xbe); //读取暂存器中的内容 a=Read_Byte(); //读取高八位 b=Read_Byte(); //读取低八位 temper=b; temper<<=4; temper+=(a & 0xf0)>>4; Decimals=(a&0x0f)*0.0625*100; //小数部分 return temper;}#endif
    0 点赞
  • 这是我之前写的一个程序 希望能帮到你 有问题可以探讨下#include<reg52.h>#include<intrins.h>#define data P0#define uchar unsigned char#define uint unsigned intuchar TEMP;// 温度值的变量;uchar flag1;sbit RS=P2^0;sbit RW=P2^1;sbit LCDE=P2^2;sbit DQ=P2^3;sbit bflag=ACC^7;uchar tab1[]={'0','1','2','3','4','5','6','7','8','9'};uchar idata tab2[2][16]={{"Be careful "},{"temperature: "}};uchar buf[2];void delay1(uchar i){while(--i);}void delay3 (unsigned int count){unsigned int i;while (count){i =200;while (i>0) i--;count--; }}void tmreset (void)// 发送复位和初始化{unsigned int i;DQ = 0;i = 103;while (i>0) i--; // 延时DQ = 1;i = 4;while (i>0) i--;}bit tmpread (void)// 读取数据的一位{ unsigned int i;bit dat;DQ = 0; i++;DQ = 1; i++; i++;//延时dat =DQ;i = 8; while (i>0) i--;// 延时return (dat);}unsigned char tmpread2 (void)//读一个字节{unsigned char i,j,dat;dat = 0;for (i=1;i<=8;i++){j = tmpread ();dat = (j << 7) | (dat >> 1);}return (dat);}void tmpwrite (unsigned char dat)//写一个字节{ unsigned int i;unsigned char j;bit testb;for (j=1;j<=8;j++){testb = dat & 0x01;dat = dat >> 1;if (testb){DQ = 0;// 写0 i++; i++; DQ = 1;i = 8; while (i>0) i--; }else{DQ = 0;// 写0 i = 8; while (i>0) i--; DQ = 1;i++; i++; }}}void tmpchange(void)// ds1820 开始转换{ tmreset ();// 复位//tmpre ();// 等待存在脉冲delay3 (1);// 延时tmpwrite (0xcc);// 跳过序列号命令tmpwrite (0x44);// 发转换命令 44H,}uchar tmp (void)// 读取温度{ unsigned int a,b,t;tmreset ();// 复位delay3 (1);// 延时tmpwrite (0xcc);// 跳过序列号命令tmpwrite (0xbe);a=tmpread2();b=tmpread2();// 发送读取命令b<<=4; b+=(a&0xf0)>>4; t=b;return(t);/*buf[0] = tmpread2 ();// 读取低位温度buf[1] = tmpread2 (); //读取高位温度flag1=buf[1]&0xf8;//若b为1则为负温if(flag1){buf[0]=~buf[0];buf[1]=~buf[1];//如果为负温则去除其补码}buf[0]=(buf[0]>>4);buf[0]=(buf[0]&0x0f);buf[1]=buf[1]<<4;buf[1]=buf[1]&0xf0;TEMP=(buf[0]|buf[1]);if(flag1){TEMP++;}buf[0]=TEMP%10;buf[1]=TEMP/10;*/}rom()// 读取器件序列号子程序{tmreset ();//复位delay3 (1);//延时tmpwrite(0x33);//发送读序列号子程序} busy_check() //忙检查询{ register uchar lcd_start;RS=0;RW=1;LCDE=1;delay1(30);lcd_start=data;LCDE=0;return(lcd_start&0x80);}wr_com(uchar comm) //写控制字命令{ while(busy_check());RS=0;RW=0;LCDE=1;data=comm;LCDE=0;} wr_dat(uchar dat) //写字符到LCD{while(busy_check());RS=1;RW=0;LCDE=1;data=dat;LCDE=0; }void init()//led 初始化{wr_com(0x38); //设置显示模式:8位子行5×7点阵wr_com(0x80); //关闭显示屏wr_com(0x0c); //显示器开、光标开、光标允许闪烁wr_com(0x06); //文字不动,光标自动右移wr_com(0x01);//清屏光标复位}void display1()//温度显示函数{uchar j,k;wr_com(0x80);for(j=0;j<16;j++){wr_dat(tab2[0][j]);}wr_com(0xc0);for(k=0;k<16;k++){wr_dat(tab2[1][k]);}}void main(){uchar temp;delay1(10);init();while(1){tmpchange();// 开始温度转temp=tmp();tab2[1][14]=tab1[temp/10];//读取温度tab2[1][15]=tab1[temp%10];/*tab2[1][14]=tab1[buf[1]];tab2[1][15]=tab1[buf[0]]; */display1();}}
    0 点赞

没有更多内容了

返回顶部
产品求购 求购