单片机课设 

题目是DS18B20的通信,用CH452搭配数码管显示。DS18B20最主要的是单总线协议,这个我之前没有接触过。上来只好老老实实的看数据手册。

对于DS18B20来说,有下面的这些特点:

( 1 )采用单总线的接口方式 与微处理器连接时仅需要一条口线即可实现微处理器与 DS18B20 的双向通讯。单总线具有经济性好,抗干扰能力强,适合于恶劣环境的现场温度测量,使用方便等优点,使用户可轻松地组建传感器网络,为测量系统的构建引入全新概念。

( 2 )测量温度范围宽,测量精度高 DS18B20 的测量范围为 -55 ℃ ~+ 125 ℃ ; 在 -10~+ 85°C范围内,精度为 ± 0.5°C 。

( 3 )在使用中不需要任何外围元件。

( 4 )持多点组网功能 多个 DS18B20 可以并联在惟一的单线上,实现多点测温。

( 5 )供电方式灵活 DS18B20 可以通过内部寄生电路从数据线上获取电源。因此,当数据线上的时序满足一定的要求时,可以不接外部电源,从而使系统结构更趋简单,可靠性更高。

( 6 )测量参数可配置 DS18B20 的测量分辨率可通过程序设定 9~12 位。

( 7 ) 负压特性电源极性接反时,温度计不会因发热而烧毁,但不能正常工作。

( 8 )掉电保护功能 DS18B20 内部含有 EEPROM ,在系统掉电以后,它仍可保存分辨率及报警温度的设定值。

这里面需要注意的主要是内部的寄生电路,这个电路可以不接电源来实现工作。但是转换温度的时间会增加。在老师给我们的板子上接了电源。同时也给信号端口接了上拉电阻。所以也是在程序上简化了一些。

下面来一一介绍DS18B20的工作通信协议、DS18B20的配置以及CH452的显示部分。

DS18B20的工作通信协议:

DS18B20是单总线协议,结构上的简单一定会导致时序上的复杂。在时序上要求严格按照数据手册上面的要求来完成。对于每

一次的写命令来说都要按照下面的步骤来执行:

即 初始化命令——>Rom命令——>函数命令(主要是温度转换)之所以把这个写在前面,是因为这个非常的重要而且很容易被忽视。在自己写初步的程序的时候,一直没有正常的通讯。看了别人的程序才恍然大悟。主要是一开始这个步骤忽略了。介绍完了命令的步骤。下面开始说明初始化,写0 、写1和读0、读1这几步。

(初始化时序)

(读写1 0)

这里的话没有什么好说的,需要注意的主要是三点:(1)注意时序的要求,不同的单片机延时也不一样,我用的是STC15的和89的就不同。(2)注意释放总线   (3)可以利用初始化后面的应答信号确定是否响应,有时候会用到。

DS18B20的配置:

DS18B20内部有48位的唯一ID,这个ID在只有一个芯片的时候没有什么用。但是要是实现多个DS18B20挂载在一个总线的时候这个是不可缺少的。所以我们首先要读出来这个ID。ID可以通过CRC校验确定是否正确。

我读出的芯片ID是{0x28,0x79,0xA9,0xE6,0x05,0x00,0x00,0xA5}和{0x28,0xd8,0x60,0xc0,0x06,0x00,0x00,0x82}这样就通过不同的ID来确定不同新片了。

uchar CRC8()
{ uchar i,x; uchar crcbuff;crc=0;for(x = 0; x <8; x++){crcbuff=fCode[x];for(i = 0; i < 8; i++) { if(((crc ^ crcbuff)&0x01)==0) crc >>= 1; else { crc ^= 0x18;   //CRC=X8+X5+X4+1crc >>= 1; crc |= 0x80; }         crcbuff >>= 1;       }}return crc;
}

(CRC校验程序)

CH452的显示部分:

CH452是键盘扫描和显示芯片。我参照的是官方的例程,(ˇˍˇ) 向里面写数据就可自动的实现显示和键盘读写。下面贴出原理图

最后给出源程序,希望有借鉴的价值。

#include<reg52.h>
#include "intrins.h"
#define uchar unsigned char
#define uint unsigned int
#define FOSC 11059200L          //系统频率
#define BAUD 115200             //串口波特率
//命令定义
#define CH452_NOP       0x0000                  // 空操作
#define CH452_RESET     0x0201                  // 复位
#define CH452_LEVEL     0x0100                  // 加载光柱值,需另加7位数据
#define CH452_CLR_BIT   0x0180                  // 段位清0,需另加6位数据
#define CH452_SET_BIT   0x01C0                  // 段位置1,需另加6位数据
#define CH452_SLEEP     0x0202                  // 进入睡眠状态
#define CH452_LEFTMOV   0x0300            // 设置移动方式-左移
#define CH452_LEFTCYC   0x0301            // 设置移动方式-左循环
#define CH452_RIGHTMOV  0x0302            // 设置移动方式-右移
#define CH452_RIGHTCYC  0x0303            // 设置移动方式-右循环
#define CH452_SELF_BCD  0x0380                  // 自定义BCD码,需另加7位数据
#define CH452_SYSOFF    0x0400                  // 关闭显示、关闭键盘
#define CH452_SYSON1    0x0401                  // 开启显示
#define CH452_SYSON2    0x0403                  // 开启显示、键盘
#define CH452_SYSON2W   0x0423                  // 开启显示、键盘, 真正2线接口
#define CH452_NO_BCD    0x0500                  // 设置默认显示方式,可另加3位扫描极限
#define CH452_BCD       0x0580                  // 设置BCD译码方式,可另加3位扫描极限
#define CH452_TWINKLE   0x0600            // 设置闪烁控制,需另加8位数据
#define CH452_GET_KEY   0x0700                  // 获取按键,返回按键代码
#define CH452_DIG0      0x0800                  // 数码管位0显示,需另加8位数据
#define CH452_DIG1      0x0900            // 数码管位1显示,需另加8位数据
#define CH452_DIG2      0x0a00            // 数码管位2显示,需另加8位数据
#define CH452_DIG3      0x0b00            // 数码管位3显示,需另加8位数据
#define CH452_DIG4      0x0c00            // 数码管位4显示,需另加8位数据
#define CH452_DIG5      0x0d00                  // 数码管位5显示,需另加8位数据
#define CH452_DIG6      0x0e00                  // 数码管位6显示,需另加8位数据
#define CH452_DIG7      0x0f00            // 数码管位7显示,需另加8位数据
#define RADIX           0x02            //小数点
// 显示部分引脚定义
sbit   din = P2^6;                     // 串行数据输出,接CH451的数据输入
sbit   load=P3^3;                        //串行命令加载,上升延激活
sbit   dout=P2^7;                        //INT1,键盘中断和键值数据输入,接CH451的数据输出
sbit   dclk = P2^5;
sbit   DS=P1^3;           //define interface
sbit   beep = P1^7;
sfr    AUXR  = 0x8e;               //辅助寄存器                    //串行数据时钟上升延激活
unsigned char code number[]={0xbd,0x18,0xd5,0xd9,0x78,0xe9,0xed,0x98,0xfd,0xf9};
uchar i,j,cmd1,keycode;
uint temp;               // variable of temperature
uint temped;            // 源码
uchar flag1;            // sign of the result positive or negative
uchar flag_key;
uchar ch451_key;
uchar flag_wendu;
uint cmd;
bit busy;
bit presence;
unsigned char  crc;
uchar fCode[8];                         //序列号数组
uchar DSrom1[8]={0x28,0x79,0xA9,0xE6,0x05,0x00,0x00,0xA5}; //板子上的              //2个器件每个64位序列号
uchar DSrom2[8]={0x28,0xd8,0x60,0xc0,0x06,0x00,0x00,0x82}; //ROM1                     //2个器件每个64位序列号
uint   f[2]; //温度数组
uint   e[2]; //原温度数组
void CH452_Write(unsigned short cmd);   // ch452写程序
void CH452_Read(void);                  // ch452读程序
void Delay500us();                      //延时
void Delay30us();                       //延时
void Delay240us();                      //延时
void Delay5us();                        //延时
void Delay60us();                       //延时
void Delay2us();                        //延时
void Delay1000us();                     //延时
void Delay100ms();                      //延时
void Delay80us();
void Delay20us();
void Delay1ms();
void delay_b20(uint n);                 //单片机定时1us    不准!!!!!!
void uartinit(void);                    //串口初始化
void SendData(uint dat);                //发送数据
void SendString(char *s);               //发送字符串
void dsreset(void);                     // Ds1820初始化
bit tmpreadbit(void);                   //read a bit
uchar tmpread(void);                    //read a byte date
void tmpwritebyte(uchar dat);           //write a byte to ds18b20
void tmpchange(void);                   //DS18B20 begin change
void display(uint temp);                    //显示程序
void exti1init ();
void DispCode();                        // 读序列号
void read_dealtemp0();                  // 读多个温度
void read_dealtemp1();                  //读取温度
uchar CRC8() ;
void delay_b20(uint n)//STC12C5A单片机定时1us
{ while(n--){_nop_();}
}
void exti1init (){INT0 = 1;IT0 = 1;                    //设置INT0的中断类型 (1:仅下降沿 0:上升沿和下降沿)EX0 = 1;                    //使能INT0中断EA = 1;
}
void display(uint temp)         //显示程序
{uchar A1,A2,A3,A4;A1 =  temp/1000;A2 = temp % 1000 / 100;A3 = temp % 100 / 10;A4 = temp % 10;CH452_Write(CH452_DIG4 | number[ A1 ]);CH452_Write(CH452_DIG5 | number[ A2]|RADIX);CH452_Write(CH452_DIG6 | number[A3]);CH452_Write(CH452_DIG7 | number[A4]);
}
void tmpchange(void)  //DS18B20 begin change
{dsreset();Delay240us();tmpwritebyte(0xcc);  // 跳过ROM tmpwritebyte(0x44);  //  initiates a single temperature conversion
}/*
响应多个温度 首先是复位 然后ROM 接着RAm最后计算
*/
void read_dealtemp0(){    //读多个温度uchar i,j; uchar a,b;float tt; j = 0;dsreset();Delay240us()   ;tmpwritebyte(0x55);      //输入序列号for(i=0;i<8;i++) { tmpwritebyte(DSrom1[i]);//发送64位序列号 } tmpwritebyte(0xbe);a=tmpread();b=tmpread();temp=b;temp<<=8;             //two byte  compose a int variabletemp=temp|a;temped=temp;      // 源码tt=temp*0.0625;       temp=tt*100+0.5;f[j]=temp;e[j]=temped;Delay100ms();}
void read_dealtemp1(){    //读多个温度uchar i,j; uchar a,b;float tt; j = 1;dsreset();Delay240us()   ;tmpwritebyte(0x55);      //输入序列号for(i=0;i<8;i++) { tmpwritebyte(DSrom2[i]);//发送64位序列号 } tmpwritebyte(0xbe);a=tmpread();b=tmpread();temp=b;temp<<=8;             //two byte  compose a int variabletemp=temp|a;temped=temp;      // 源码tt=temp*0.0625;       temp=tt*100+0.5;f[j]=temp;e[j]=temped;Delay100ms();}
uint tmp()               //get the temperature
{float tt;uchar a,b;dsreset();Delay240us()  ;tmpwritebyte(0xcc);tmpwritebyte(0xbe);a=tmpread();b=tmpread();temp=b;temp<<=8;             //two byte  compose a int variabletemp=temp|a;temped=temp;     // 源码tt=temp*0.0625;       temp=tt*100+0.5;return temp;        // 转换的温度
}
void tmpwritebyte(uchar dat)   //write a byte to ds18b20
{uchar j;bit testb;for(j=1;j<=8;j++){testb=dat&0x01;dat=dat>>1;if(testb)     //write 1{DS=0;Delay5us();DS=1;Delay60us();}else{DS=0;       //write 0Delay60us();DS=1;Delay5us();}}
}
void DispCode()//读取序列号
{ uchar i; dsreset(); tmpwritebyte(0x33); for (i=0;i<8;i++) {fCode[i]=tmpread(); }
}
uchar tmpread(void)   //read a byte date
{uchar i,j,dat;dat=0;for(i=1;i<=8;i++){j=tmpreadbit();dat=(j<<7)|(dat>>1);   //读出的数据最低位在最前面,这样刚好一个字节在DAT里}return(dat);
}
bit tmpreadbit(void)       //read a bit
{bit dat;DS=0;//i++ for delayDelay2us();DS=1;Delay2us();dat=DS;Delay60us();return (dat);
}
void dsreset(void)       //send reset and initialization command
{DS = 1; //DQ复位 Delay2us();//延时 DS = 0; //DQ拉低 Delay500us(); //精确延时大于480us DS = 1; //拉高 Delay30us(); presence = DS;Delay60us();DS = 1;
}void SendString(char *s)
{while (*s)                  //检测字符串结束标志{SendData(*s++);         //发送当前字符}
}
void SendData(uint dat)
{while (busy);               //等待前面的数据发送完成busy = 1;SBUF = dat;                 //写数据到UART数据寄存器
}
void uartinit(void){SCON = 0x50;                //8位可变波特率AUXR = 0x40;                //定时器1为1T模式TMOD = 0x20;                //定时器1为模式2(8位自动重载)TL1 = (256 - (FOSC/32/BAUD));   //设置波特率重装值TH1 = (256 - (FOSC/32/BAUD));TR1 = 1;                    //定时器1开始工作ES = 1;                     //使能串口中断EA = 1;
}
void Delay1ms()     //@11.0592MHz
{unsigned char i, j;_nop_();_nop_();_nop_();i = 11;j = 190;do{while (--j);} while (--i);
}void Delay100ms()      //@11.0592MHz
{unsigned char i, j, k;_nop_();_nop_();i = 5;j = 52;k = 195;do{do{while (--k);} while (--j);} while (--i);
}
void Delay20us()        //@11.0592MHz
{unsigned char i;_nop_();_nop_();_nop_();i = 52;while (--i);
}
void Delay80us()        //@11.0592MHz
{unsigned char i, j;_nop_();i = 1;j = 217;do{while (--j);} while (--i);
}
void Delay1000us()      //@11.0592MHz
{unsigned char i, j;_nop_();_nop_();_nop_();i = 11;j = 190;do{while (--j);} while (--i);
}
void Delay2us()     //@11.0592MHz
{unsigned char i;i = 3;while (--i);
}
void Delay60us()        //@11.0592MHz
{unsigned char i, j;i = 1;j = 162;do{while (--j);} while (--i);
}
void Delay5us()     //@11.0592MHz
{unsigned char i;_nop_();i = 11;while (--i);
}
void Delay240us()       //@11.0592MHz
{unsigned char i, j;_nop_();_nop_();i = 3;j = 145;do{while (--j);} while (--i);
}
void Delay500us()       //@11.0592MHz
{unsigned char i, j;_nop_();_nop_();i = 6;j = 93;do{while (--j);} while (--i);
}
void Delay30us()        //@11.0592MHz
{unsigned char i;_nop_();_nop_();i = 80;while (--i);
}
uchar CRC8()
{ uchar i,x; uchar crcbuff;crc=0;for(x = 0; x <8; x++){crcbuff=fCode[x];for(i = 0; i < 8; i++) { if(((crc ^ crcbuff)&0x01)==0) crc >>= 1; else { crc ^= 0x18;   //CRC=X8+X5+X4+1crc >>= 1; crc |= 0x80; }         crcbuff >>= 1;       }}return crc;
}
void CH452_Write(unsigned short cmd){load=0; //命令开始,LOAD=0for(i=0;i!=12;i++) //送入12位数据,低位在前{dclk=0;din=cmd&1;dclk=1; //上升沿有效cmd=cmd>>1;}load=1; //加载数据,LOAD上升沿}
void CH452_Read(void){cmd1=0x07; //读按键的命令字load=0;for(i=0;i!=4;i++) // 只需要发出高4位,多发也可以,但应该确保最后留下的4位是该命令码{din=cmd1&1;dclk=0;cmd1>>=1; //往右移一位dclk=1; //产生时钟上升沿锁通知CH451输入位数据}load=1; //产生加载上升沿通知CH451处理命令数据for(j=0;j<100;j++){ }keycode=0; //清除keycodefor(i=0;i!=7;i++){keycode<<=1; //数据移入keycode,高位在前,低位在后if (dout){ keycode++;} //从高到低读入451的数据// keycode|=CH452_DOUT;dclk=0; //产生时钟下升沿通知CH451输出下一位dclk=1;}}
//中断服务程序
void exint0() interrupt 0       //INT0中断入口{}
/*----------------------------
UART 中断服务程序
-----------------------------*/
void Uart() interrupt 4 using 1{if (RI){RI = 0;                 //清除RI位}if (TI){TI = 0;                 //清除TI位busy = 0;               //清忙标志}}
void main(void){uchar path1;path1 = 0; CH452_Write(CH452_RESET);CH452_Write(CH452_SYSON2); //CH452初始化  flag_wendu=1;                   // 显示温度标记//    presence =0;           // 响应信号  0是OK// DispCode();             //读序列号 读的时候只能是单线的操作//   CRC8();                //校验crc, 0 是ok
while (1){CH452_Read();if (keycode==0x44){path1 =0 ;beep=0;Delay100ms();beep=1;}if (keycode==0x45){path1 =1; beep=0;Delay100ms();beep=1;}if (keycode==0x46){path1 =2; beep=0;Delay100ms();beep=1;}if (keycode==0x47){path1 =3; beep=0;Delay100ms();beep=1;}keycode=0;switch(path1) {case 0: display(f[0]); break;case 1: display(e[0]); break;case 2: display(f[1]); break;case 3: display(e[1]); break;}tmpchange();//初始化 read_dealtemp0();//读取温度tmpchange();//初始化 read_dealtemp1();//读取温度
}
}

DS18B20单总线协议相关推荐

  1. DS18B20数字温度传感器及单总线协议规定

    1,DS18B20数字温度传感器的主要特点 通信采用1-Wire接口 每个DS18B20都有唯一的64位序列码储存在板载ROM中 无需外部元件 可从数据线供电,电源范围为3.0V ~ 5.5V. 可测 ...

  2. [stc89c52] DS18B20基于单总线协议的温度测量

    一.单总线协议(1-wire) 1.定义:主机和从机用一根总线进行通信,是一种半双工的通信方式,单线=时钟线+数据线+控制线( +电源线).理想状况下一条总线上的从器件数量几乎不受数量限制. 2.特点 ...

  3. 解析单总线协议(1-wire)

    一.单总线协议(1-wire) 1.定义:主机和从机通过1根线进行通信,在一条总线上可挂接的从器件数量几乎不受限制. 2.特点:这是由达拉斯半导体公司推出的一项通信技术.它采用单根信号线,既可传输时钟 ...

  4. 单总线协议(1—wire)

    一.单总线协议(1-wire) 1.定义:主机和从机通过1根线进行通信,在一条总线上可挂接的从器件数量几乎不受限制. 2.特点:这是由达拉斯半导体公司推出的一项通信技术.它采用单根信号线,既可传输时钟 ...

  5. 一文看懂单总线协议(1-wire)

    文章目录 一.什么是单总线协议? 1.单总线协议概念及特点 2.硬件结构 3.单总线协议应用 二.单总线协议时序(以DS18B20为例) 1.初始化(复位脉冲 + 存在脉冲) 2.读/写时序 (1)写 ...

  6. 《嵌入式 - 嵌入式大杂烩》深入理解单总线协议

    1单总线简介 目前常用的微机与外设之间进行数据传输的串行总线主要有I2C总线.SPI总线和SCI总线.其中I2C总线以同步串行2线方式进行通信(一条时钟线,一条数据线),SPI总线则以同步串行3线方式 ...

  7. 通信协议--单总线协议

    文章目录 一.单总线简介 二.单总线协议 单总线初始化 单总线写入 单总线读取 DS18B20用法 读取温度(仅仅包含整数部分) 读取温度(含小数部分) 一.单总线简介 1.定义:主机和从机通过1根线 ...

  8. 【51单片机快速入门指南】6.3:DS18B20 单总线数字温度计的多路读取

    目录 硬知识 DS18B20介绍 时序 初始化时序 写时序 读时序 命令 ROM 操作命令 ROM 搜索举例 存贮器操作命令 示例程序 DS18B20.c DS18B20.h 测试程序 定时器中断服务 ...

  9. 蓝桥杯单片机DS18b20单总线测温模块常见问题解决

    蓝桥杯单片机DS18b20单总线测温模块常见问题解决 有道是:"溪水声声留我住,梅花朵朵唤人回" DS18b20测温模块作为一个比较简单.稳定的蓝桥杯单片机外设模块, 使用时却经常 ...

  10. 单总线协议-以DS18B20举例

    一.概述 1-wire 单总线是Maxim 全资子公司 Dallas 的一项专有技术.与目前多数标准串行数据通信方式,如SPI/I2C/MICROWIRE 不同,它采用单根信号线,既传输时钟,又传输数 ...

最新文章

  1. java中关键字volatile的作用(转载)
  2. Linux文件权限符号含义
  3. wukong引擎源码分析之索引——part 3 文档评分 无非就是将docid对应的fields信息存储起来,为搜索结果rank评分用...
  4. Python数据分析,抓取京东商品价格
  5. pc调试微信h5页面
  6. 退出循环:break 跳过当前的这次循环,直接开始下一次循环:continue
  7. 基于Unity的阿里云短信SDK接入流程
  8. 深度森林实现时间序列预测(Python)
  9. html 长度vm,css vm是什么单位?
  10. 基于MATLAB的疲劳检测系统研究解析
  11. 数据治理之IT系统存量信息梳理
  12. 【Python 爬虫实践】:《战狼2》豆瓣影评分析
  13. “千亿市值”巨无霸的膨胀 腾讯靠什么撬动下一个1000亿美金?
  14. 美国签证和加拿大签证申请及自驾游攻略合辑
  15. python excel单元格 剪切清除粘贴复制_Excel复制粘贴时弹出“不能清除剪贴板”的解决方法...
  16. 电路硬件设计——PCB布局和布线
  17. 《BREW进阶与精通——3G移动增值业务的运营、定制与开发》连载之11---什么是BREW
  18. 三自由度机器人运动学matlab仿真实验报告,3自由度机器人的正运动学建模研究...
  19. Uni-app 课程详情页 获取课程详情 + 收藏 + 加入购物车
  20. 计算机控制技术实验报告pid,东南大学计算机控制技术实验报告二.docx

热门文章

  1. EPLAN 教育版超详细安装说明
  2. linux ping 测试网速,怎么ping网速 ping命令简单测试网速方法【详解】
  3. 基于Mybatis的语音播报随机点到系统
  4. acl 影响因子_计算机领域EI和SCI收录期刊及影响因子
  5. 求对着目标物体环绕拍摄的相机参数lookAt
  6. 只要方向正确,路远不是事
  7. 微博html5版开视频怎么退出,微博怎么取消视频号?微博视频号怎么关闭
  8. 华硕天选3笔记本电脑WiFi功能消失
  9. C++ 算术平均数及几何平均数
  10. 名词用作动词举例_名词作动词的句子