#include
#include
__CONFIG(0x3F32); //芯片配置字
#define LCDRS RB2
#define LCDRW RB1
#define LCDE RB0
#define LCDDA TA PORTD
#define DS18B20 RE0
#define TRIS_B20 TRISE0
void LCD1602_INIT(void);
void WRITE_LCD_CMD (char cmd);
void WRITE_LCD_DA TA (char data);
void LCD_Display(char *s);
void LCD_Display_location (char line, char col);
void LCD1602_BUSY();
void US_delay ( int t);
void itoa10(unsigned char *buf, int i);
int strlen (const char *s);
void DS18B20_INIT();
void WRITE_DS18B20_CMD(char cmd);
float READ_DS18B20 ();
char bank1 DA T_BUFF1[]= "Temperature:";
char Found_DS18B20[]="DS1820 FOUND";
char DS18B20_NOT_Found[]="DS1820 NOT FOUND"; char bank1 DA T_BUFF2[]= " ";
#define CLRLCD 0X01 //清屏命令
#define LCDMOD 0X38 //8位,两行,5*7点
#define TURNON 0X0F //
#define CURMODE 0X06 //
#define ORG1 0X80 //LCD 第一行首地址
#define ORG2 0XC0 //LCD 第二行首地址
#define SKIPROM 0XCC
#define READSCRACHPAD 0XBE
#define TCONVERT 0X44
#define DS18b20_RESET 10
#define DSRECOVER 1
float temperature;
char bank1 atemperature[10]; // used for store ascii code of digital temperature */
void main()
{
int len;
ADCON1=0X07;
LCD1602_INIT();
LCD_Display(DA T_BUFF1);
LCDE=0;
LCD_Display_location (1,0);
while (1)
{
DS18B20_INIT();
WRITE_DS18B20_CMD(SKIPROM);
WRITE_DS18B20_CMD(TCONVERT);
TRIS_B20=0;
DS18B20=0;
TRIS_B20=1;
while(1)
{ //判断转换是否完成
if (DS18B20) break;
else continue;
}
DS18B20_INIT();
WRITE_DS18B20_CMD(SKIPROM);
WRITE_DS18B20_CMD(READSCRACHPAD);
temperature=READ_DS18B20();
itoa10(atemperature, (int) (temperature * 10));
// so use temperature * 10 to enlarge the temperature len=strlen(atemperature);
atemperature[len]=atemperature[len-1];
atemperature[len-1]='.';
atemperature[len+1]=0;
LCD_Display_location (0,0);
LCD_Display (DA T_BUFF1); //LCD第一行显示Tempereture: 字符LCD_Display_location (1,0);
LCD_Display (DA T_BUFF2);
LCD_Display_location (1,2);
LCD_Display (atemperature); //LCD第二行显示当前温度值
LCD_Display (DA T_BUFF2);
US_delay(5000); //每隔0.5秒读取一次温度值
}
}
int strlen(const char * s)
{
const char *cp;
cp = s;
while(*cp++)
continue;
return cp-s-1;
}
void LCD_Display(char *s)
{
int len;
int atmp;
len=strlen(s);
for (atmp=0; atmp WRITE_LCD_DA TA(s[atmp]); } void LCD1602_BUSY() { // char tmpbusy; TRISB &= 0xF8; TRISD=0XFF; LCDRS=0; LCDRW=1; LCDE=1; while(LCDDA TA & 0X80); } void LCD_Display_location (char line, char col) { char pos; LCD1602_BUSY(); pos = line * 0X40 + 0X80 + col; WRITE_LCD_CMD(pos); } void WRITE_LCD_DA TA(char data) { LCD1602_BUSY(); TRISB & =0XF8; TRISD=0; LCDDA TA=data; LCDRS=1; LCDRW=0; LCDE=0; asm("NOP"); asm("NOP"); LCDE=1; } void WRITE_LCD_CMD(char cmd) { LCD1602_BUSY(); TRISB & =0XF8; TRISD=0; LCDDA TA=cmd; LCDRS=0; LCDRW=0; LCDE=0; asm("NOP"); asm("NOP"); LCDE=1; } void LCD1602_INIT(void) { LCD1602_BUSY(); TRISB &= 0XF8; TRISD=0; WRITE_LCD_CMD(CLRLCD); WRITE_LCD_CMD(LCDMOD); WRITE_LCD_CMD(TURNON); WRITE_LCD_CMD(CURMODE); LCD_Display_location (0,0); } void DS18B20_INIT() { TRIS_B20=0; DS18B20=0; US_delay(20); TRIS_B20=1; US_delay(10); } void WRITE_DS18B20_CMD(char cmd) { char tmp; char i; TRIS_B20=0; for(tmp=8;tmp>0;tmp--) { TRIS_B20=0; DS18B20= 0; asm ("NOP"); asm ("NOP"); asm ("NOP"); asm ("NOP"); asm ("NOP"); if (cmd & 0x01) { TRIS_B20=1; US_delay(1); for (i=5;i>0;i--); } else { DS18B20=0 ; US_delay(1); for (i=5;i>0;i--); TRIS_B20=1; } cmd=cmd/2; } } float READ_DS18B20 () { char tmp=0x01; float t; union { char c[2]; int x; }temp; temp.x=0; while (tmp) { // read first 8 bits TRIS_B20=0; DS18B20=0; asm("NOP"); TRIS_B20=1; if (DS18B20) temp.c[0] |= tmp; tmp=tmp<<1; US_delay(2); } tmp=1; while (tmp) { // read first 8 bits TRIS_B20=0; DS18B20=0; asm("NOP"); TRIS_B20=1; // release the bus asm("NOP"); if (DS18B20) // "1" presented temp.c[1] |= tmp; tmp=tmp<<1; US_delay(2); } t=((float) temp.x)/16.0 ; return t; } void itoa10(unsigned char *buf, int i) { unsigned int rem; unsigned char *s,length=0; s = buf; if (i == 0) *s++ = '0'; else { if (i < 0) { *buf++ = '-'; s = buf; i = -i; } while (i) { ++length; rem = i % 10; *s++ = rem + '0'; i /= 10; } for(rem=0; ((unsigned char)rem) { *(buf+length) = *(buf+((unsigned char)rem)); *(buf+((unsigned char)rem)) = *(buf+(length-((unsigned char)rem)-1)); *(buf+(length-((unsigned char)rem)-1)) = *(buf+length); } } *s=0; } void US_delay( int i) { unsigned char j; while(i--) { j=3; while(j--); } } (1)先将数据线置高电平“1”。 (2)延时(该时间要求的不是很严格,但是尽可能的短一点) (3)数据线拉到低电平“0”。 (4)延时750微秒(该时间的时间范围可以从480到960微秒)。 (5)数据线拉到高电平“1”。 (6)延时等待(如果初始化成功则在15到60毫秒时间之内产生一个由DS18B20所返回的低电平“0”。据该状态可以来确定它的存在,但是应注意不能无限的进行等待,不然会使程序进入死循环,所以要进行超时控制)。 (7)若CPU读到了数据线上的低电平“0”后,还要做延时,其延时的时间从发出的高电平算起(第(5)步的时间算起)最少要480微秒。 (8)将数据线再次拉高到高电平“1”后结束。 (1)数据线先置低电平“0”。 (2)延时确定的时间为15微秒。 (3)按从低位到高位的顺序发送字节(一次只发送一位)。 (4)延时时间为45微秒。 (5)将数据线拉到高电平。 (6)重复上(1)到(6)的操作直到所有的字节全部发送完为止。(7)最后将数据线拉高。 DS18B20的写操作时序图如图 DS18B20的读操作 (1)将数据线拉高“1”。 (2)延时2微秒。 (3)将数据线拉低“0”。 (4)延时15微秒。 (5)将数据线拉高“1”。 (6)延时15微秒。 (7)读数据线的状态得到1个状态位,并进行数据处理。 (8)延时30微秒。DS18B20的读操作时序图如图所示。 DS18B20的Protues仿真图 源程序代码: #include "reg51.h" #include "intrins.h" // 此头文件中有空操作语句NOP 几个微秒的延时可以用NOP 语句,但本人没用NOP,直接用了I++来延时 #define uchar unsigned char #define uint unsigned int uchar code table[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37, 0x38,0x39}; sbit ds18b20_io=P2^0; //单片机与DS18B20的连接口 sbit lcdrs=P2^6; //1602与单片机的接口 sbit lcden=P2^7; PIC16F877A与PC机串行通信C语言源程 序 //*******串口通信程序********* //*******定义变量************* #include ; #define unchar unsigned char #define uint unsigned int unchar RC_label;//标志位起始位为1结束位为0 unchar caiji_label;//采集帧格式标志位正确为1错误为0 unchar data RC[100];//存储接收到的数据 unchar data TX1[100];//存储自身参数 unchar data TX2[100];//存储出错指示ERROR int RC_buff;// int i=0,j=0,k=0;// //*****变量定义完毕************ //*****子程序区**************** //*****串口初始化程序开始********** void initRS232() { //设置TXSTA CSRC=0;// TX9=0;//8位数据发送 TXEN=1;//发送使能 SYNC=0;//选择异步模式 BRGH=1;//高速 TRMT=1;//发送寄存器空 TX9D=0;// //设置RCSTA SPEN=1;//允许串口工作 RX9=0;//接收8位数据 SREN=1;// CREN=1;//使能连续接收 ADDEN=0;// FERR=0;// OERR=0;//无超速错误 RX9D=0;// TRISC=0X80;//设置C口 SPBRG=0X19;//设置波特率为9600 #include 最近都在学习和写单片机的程序, 今天有空又模仿DS18B20温度测量显示实验写了一个与DS18B20基于单总线通信的程序. DS18B20 数字温度传感器(参考:智能温度传感器DS18B20的原理与应用)是DALLAS 公司生产的1-Wire,即单总线器件,具有线路简单,体积小的特点。因此用它来组成一个测温系统,具有线路简单,在一根通信线,可以挂很多这样的数字温度计。DS18B20 产品的特点: (1)、只要求一个I/O 口即可实现通信。 (2)、在DS18B20 中的每个器件上都有独一无二的序列号。 (3)、实际应用中不需要外部任何元器件即可实现测温。 (4)、测量温度范围在-55 到+125℃之间; 在-10 ~ +85℃范围内误差为±5℃; (5)、数字温度计的分辨率用户可以从9 位到12 位选择。将12位的温度值转换为数字量所需时间不超过750ms; (6)、内部有温度上、下限告警设置。 DS18B20引脚分布图 DS18B20 详细引脚功能描述: 1、GND 地信号; 2、DQ数据输入出引脚。开漏单总线接口引脚。当被用在寄生电源下,此引脚可以向器件提供电源;漏极开路, 常太下高电平. 通常要求外接一个约5kΩ的上拉电阻. 3、VDD可选择的VDD 引脚。电压范围:3~5.5V; 当工作于寄生电源时,此引脚必须接地。 DS18B20存储器结构图 暂存储器的头两个字节为测得温度信息的低位和高位字节; 第3, 4字节是TH和TL的易失性拷贝, 在每次电复位时都会被刷新; 第5字节是配置寄存器的易失性拷贝, 同样在电复位时被刷新; 第9字节是前面8个字节的CRC检验值. 配置寄存器的命令内容如下: MSB LSB R0和R1是温度值分辨率位, 按下表进行配置.默认出厂设置是R1R0 = 11, 即12位. 温度值分辨率配置表 4种分辨率对应的温度分辨率为0.5℃, 0.25℃, 0.125℃, 0.0625℃(即最低一位代表的温度值) 12位分辨率时的两个温度字节的具体格式如下: 其中高字节前5位都是符号位S, 若分辨率低于12位时, 相应地使最低为0, 如: 当分辨 , 高字节不变.... 一些温度与转换后输出的数字参照如下: 最近天气热了,想要是做个能显示温度的小设备就好了, 于是想到DIY 个电子温度计, 网上找了很多资料,结合自己的材料,设计了这个用单片机控制的实时电子温度计。 作为单 片机小虾的我做这个用了 2天时间,当然是下班后,做工不行见谅了。 主要元件用到了单片机 STC89C54RD+ , DB18B20温度传感器,4为共阳数码管, PNPS8550三极管等。 先上原理图: 洞洞板布局图: 然后就是实物图了: 函8D P3 iW 、 E E FJ T I RF D51*BZ0渥度澈码管显示 F7 Dl'AI>D li'A£> I 2、心 PDRM, 杖心P0WAD7 Pl I^TO 洋心EI^AJ D FLSAH 附上源程序:程序是别人写的,我只是自己 修改了下,先谢谢原程序者的无私奉献。 #include"reg52.h” #define uchar unsigned char #define uint unsigned int sbit DQ=P3A 4; 〃温度数据口 sbit wx1=P2A0; sbit wx2=P2A1; sbit wx3=P2A2; sbit wx4=P2A3; unsigned int temp, temp1,temp2, xs; //位选1 //位选2 //位选3 //位选4 uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99, 0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6}; /****** 延时程序 *******/ void delay1(unsigned int m) { unsigned int i,j; for(i=m;i>0;i--) for(j=110;j>0;j--); } void delay(unsigned int m) { while(m--); } /***********ds18b20 uchar ReadOneChar() { unsigned char i=0; unsigned char dat = 0; for (i=8;i>0;i--) { 读一个字节 **************/ void Init_DS18B20() { unsigned char x=0; DQ = 1; //DQ 复位 delay(8); 〃稍做延时 DQ = 0; 〃单片机将 ds18b20通信端口 DQ 拉低 delay(80); //精确延时大于480us DQ = 1; delay(4); x=DQ; delay(20); } 〃拉高总线 //稍做延时后如果x=0则初始化成功 x=1 则初始化失败 〃共阳数码管 〃温度延时程序 PIC16F877A的特殊功能配置CPU的特殊功能 BIT13CP:闪存程序存储器代码保护位 0:所有程序存储器代码保护 1:关闭代码保护 BIT12Unimplemented:读时为结果为1 BIT11DEBUG:在电路调试模式位 0:在电路调试功能有效,RB6和RB7专用于调试器 1:在电路调试功能失效,RB6和RB7用于本身的IO或其它功能BIT10-9WRT1-0:闪存程序存储器写使能位 WRT1WRT0说明 11写保护关闭,所有程序存储器由EECON控制写 100000h到00ffh写保护;0100h到1fffh由EECON控制写010000h到07ffh写保护;0800h到1fffh由EECON控制写000000h到0fffh写保护;1000h到1fffh由EECON控制写BIT8CPD:数据EEPROM存储器代码保护位 0:数据EEPROM存储器代码保护开启 1:数据EEPROM存储器代码保护关闭 BIT7LVP:低电压(单电源)的在线串行编程使能位 0:RB3/PGM是普通IO口功能,编程时MCLR管脚必须是高电压1:RB3/PGM是PGM功能,低电压编程使能 BIT6BOREN:欠压复位使能位 0:欠压复位失效 1:欠压复位使能 BIT5-4Unimplemented:读时结果为1 BIT3PWRTEN:上电延时定时器使能位 0:上电延时定时器使能 1:上电延时定时器失效 BIT2WDTEN:看门狗定时器使能位 0:看门狗失效 1:看门狗使能 BIT1-0:Fosc1:Fosc0:时钟源选择位 Fosc1Fosc0时钟源11RC振荡器 10外部石英高频晶振HS【频率范围见下表】01外部石英晶振XT【频率范围见下表】 00外部低频石英晶振LP【频率范围见下表】 //PIC16F877A.H头文件详细注释 /* Header file for the Microchip * PIC 16F873A chip * PIC 16F874A chip * PIC 16F876A chip * PIC 16F877A chip * Midrange Microcontroller */ #if defined(_16F874A) || defined(_16F877A) #define __PINS_40 #endif static volatile unsigned char INDF @ 0x00; //间接寻址寄存器 static volatile unsigned char TMR0 @ 0x01; //定时器0 static volatile unsigned char PCL @ 0x02; //低8位程序计数器 static volatile unsigned char STA TUS @ 0x03; //程序状态寄存器 static unsigned char FSR @ 0x04; //特殊功能寄存器 static volatile unsigned char PORTA @ 0x05; //端口A寄存器 static volatile unsigned char PORTB @ 0x06; //端口B寄存器 static volatile unsigned char PORTC @ 0x07; //端口C寄存器 #ifdef __PINS_40 static volatile unsigned char PORTD @ 0x08; //端口D寄存器 static volatile unsigned char PORTE @ 0x09; //端口E寄存器 #endif static unsigned char PCLA TH @ 0x0A; //高5位程序计数器 static volatile unsigned char INTCON @ 0x0B; //中断控制寄存器 static volatile unsigned char PIR1 @ 0x0C; //中断标志寄存器PIR1 static volatile unsigned char PIR2 @ 0x0D; //中断标志寄存器PIR2 static volatile unsigned char TMR1L @ 0x0E; //低字节计数寄存器 static volatile unsigned char TMR1H @ 0x0F; //高字节计数寄存器 static volatile unsigned char T1CON @ 0x10; //TMR1控制寄存器 static volatile unsigned char TMR2 @ 0x11; //定时/计数器TMR2 static volatile unsigned char T2CON @ 0x12; //TMR2控制寄存器 static volatile unsigned char SSPBUF @ 0x13; //收/发数据缓冲器 static volatile unsigned char SSPCON @ 0x14; //同步串口控制寄存器,对MSSP模块的功能和指标进行设置和定义。 static volatile unsigned char CCPR1L @ 0x15; //捕获/比较/PWM寄存器低字节 static volatile unsigned char CCPR1H @ 0x16; //捕获/比较/PWM寄存器低字节 static volatile unsigned char CCP1CON @ 0x17; //CCP1CON寄存器 static volatile unsigned char RCSTA @ 0x18; //USART接收控制兼状态寄存器 static volatile unsigned char TXREG @ 0x19; //USART发生缓冲器 static volatile unsigned char RCREG @ 0x1A; //USART接收缓冲器 static volatile unsigned char CCPR2L @ 0x1B; //捕获/比较/PWM寄存器低字节 static volatile unsigned char CCPR2H @ 0x1C; //捕获/比较/PWM寄存器低字节 static volatile unsigned char CCP2CON @ 0x1D; //CCP2CON寄存器 static volatile unsigned char ADRESH @ 0x1E; //ADC转换结果寄存器高字节 static volatile unsigned char ADCON0 @ 0x1F; //A/D转换器开关位。 温度值精确到0.1度,lcd1602显示 仿真电路图如下: c程序如下: #include uchar data disdata[5]; uint tvalue;//温度值 uchar tflag;//温度正负标志 /*************************lcd1602程序**************************/ void delay1ms(unsigned int ms)//延时1毫秒(不够精确的){unsigned int i,j; for(i=0;i 51单片机操作DS18B20汇编源程序 推荐 ; FLAG1:标志位,为"1"时表示检测到DS18B20 ; DQ:DS18B20的数据总线接脚 ; TEMPER_NUM:保存读出的温度数据 ; 本程序仅适合单个DS18B20和51单片机的连接,晶振为12MHZ左右TEMPER_LEQU36H TEMPER_HEQU35H DQBITP1.7 ; DS18B20初始化程序 ;//*****************************************// INIT_1820: SETBDQ NOP CLRDQ MOVR0,#06BH TSR1: DJNZR0,TSR1; 延时 SETBDQ MOVR0,#25H TSR2: JNBDQ,TSR3 DJNZR0,TSR2 LJMPTSR4; 延时 TSR3: SETBFLAG1; 置标志位,表示DS1820存在 LJMPTSR5 TSR4: CLRFLAG1; 清标志位,表示DS1820不存在 LJMPTSR7 TSR5: MOVR0,#06BH TSR6: DJNZR0,TSR6; 延时 TSR7: SETBDQ RET ;//*****************************************// ; 重新写DS18B20暂存存储器设定值 ;//*****************************************// RE_CONFIG: JBFLAG1,RE_CONFIG1; 若DS18B20存在,转RE_CONFIG1 RET RE_CONFIG1: MOVA,#0CCH; 发SKIP ROM命令 LCALLWRITE_1820 MOVA,#4EH; 发写暂存存储器命令 LCALLWRITE_1820 MOVA,#00H; TH(报警上限)中写入00H LCALLWRITE_1820 MOVA,#00H; TL(报警下限)中写入00H LCALLWRITE_1820 MOVA,#1FH; 选择9位温度分辨率 LCALLWRITE_1820 RET ;//*****************************************// ; 读出转换后的温度值 ;//*****************************************// GET_TEMPER: SETBDQ; 定时入口 LCALLINIT_1820 JBFLAG1,TSS2 RET; 若DS18B20不存在则返回 TSS2: MOVA,#0CCH; 跳过ROM匹配 LCALLWRITE_1820 MOVA,#44H; 发出温度转换命令 LCALLWRITE_1820 LCALLINIT_1820 MOVA,#0CCH; 跳过ROM匹配 LCALLWRITE_1820 MOVA,#0BEH; 发出读温度命令 LCALLWRITE_1820 LCALLREAD_1820 MOVTEMPER_NUM,A; 将读出的温度数据保存 RET ;//*****************************************// ; 读DS18B20的程序,从DS18B20中读出一个字节的数据 温度传感器DS18B20资料 2008-08-28 16:06 美国Dallas半导体公司的数字化温度传感器DS1820是世界上第一片支持 "一线总线"接口的温度传感器,在其内部使用了在板(ON-B0ARD)专利技术。全部传感元件及转换电路集成在形如一只三极管的集成电路内。一线总线独特而且经济的特点,使用户可轻松地组建传感器网络,为测量系统的构建引入全新概念。现在,新一代的DS18B20体积更小、更经济、更灵活。使你可以充分发挥“一线总线”的优点。目前DS18B20批量采购价格仅10元左右。 在传统的模拟信号远距离温度测量系统中,需要很好的解决引线误差补偿问题、多点测量切换误差问题和放大电路零点漂移误差问题等技术问题,才能够达到较高的测量精度。另外一般监控现场的电磁环境都非常恶劣,各种干扰信号较强,模拟温度信号容易受到干扰而产生测量误差,影响测量精度。因此,在温度测量系统中,采用抗干扰能力强的新型数字温度传感器是解决这些问题的最有效方案,新型数字温度传感器DS18B20具有体积更小、精度更高、适用电压更宽、采用一线总线、可组网等优点,在实际应用中取得了良好的测温效果。 新的"一线器件"DS18B20体积更小、适用电压更宽、更经济。 DS18B20、DS1822的特性 DS18B20可以程序设定9~12位的分辨率,精度为±0.5°C。可选更小的封装方式,更宽的电压适用范围。分辨率设定,及用户设定的报警温度存储在EEPROM中,掉电后依然保存。DS18B20的性能是新一代产品中最好的!性能价格比也非常出色!DS1822与DS18B20软件兼容,是DS18B20的简化版本。省略了存储用户定义报警温度、分辨率参数的EEPROM,精度降低为±2°C,适用于对性能要求不高,成本控制严格的应用,是经济型产品。 继"一线总线"的早期产品后,DS1820开辟了温度传感器技术的新概念。DS18B20和DS1822使电压、特性及封装有更多的选择,让我们可以构建适合自己的经济的测温系统。 DS18B20、DS1822 "一线总线"数字化温度传感器 同DS1820一样,DS18B20也支持"一线总线"接口,测量温度范围为-55°C~+125°C,在-10~+85°C 范围内,精度为±0.5°C。DS1822的精度较差为±2°C。现场温度直接以"一线总线"的数字方式传输,大大提高了系统的抗干扰性。适合于恶劣环境的现场温度测量,如:环境控制、设备或过程控制、测温类消费电子产品等。与前一代产品不同,新的产品支持3V~5.5V的电压范围,使系统设计更灵活、方便。而且新一代产品更便宜,体积更小。 一、DS18B20的主要特性 (1)适应电压范围更宽,电压范围:3.0~5.5V,在寄生电源方式下可由数据线供电 (2)独特的单线接口方式,DS18B20在与微处理器连接时仅需要一条口线即可实现微处理器与DS18B20的双向通讯 (3)DS18B20支持多点组网功能,多个DS18B20可以并联在唯一的三线上,实现组网多点测温 (4)DS18B20在使用中不需要任何外围元件,全部传感元件及转换电路集成在形如一只三极管的集成电路内 (5)温范围-55℃~+125℃,在-10~+85℃时精度为±0.5℃ (6)可编程的分辨率为9~12位,对应的可分辨温度分别为0.5℃、0.25℃、0.125℃和0.0625℃, 最近天气热了,想要是做个能显示温度的小设备就好了,于是想到DIY个电子温度计,网上找了很多资料,结合自己的材料,设计了这个用单片机控制的实时电子温度计。作为单片机小虾的我做这个用了2天时间,当然是下班后,做工不行见谅了。 主要元件用到了单片机STC89C54RD+,DB18B20温度传感器,4为共阳数码管,PNPS8550三极管等。 先上原理图: 洞洞板布局图: 然后就是实物图了: 附上源程序:程序是别人写的,我只是自己修改了下,先谢谢原程序者的无私奉献。#include"reg52.h" #define uchar unsigned char #define uint unsigned int sbit DQ=P3^4; //温度数据口 sbit wx1=P2^0; //位选1 sbit wx2=P2^1; //位选2 sbit wx3=P2^2; //位选3 sbit wx4=P2^3; //位选4 unsigned int temp, temp1,temp2, xs; uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99, //共阳数码管0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6}; /******延时程序*******/ void delay1(unsigned int m) { unsigned int i,j; for(i=m;i>0;i--) for(j=110;j>0;j--); } void delay(unsigned int m) //温度延时程序 { while(m--); } void Init_DS18B20() { unsigned char x=0; DQ = 1; //DQ复位ds18b20通信端口 delay(8); //稍做延时 DQ = 0; //单片机将DQ拉低 delay(80); //精确延时大于480us DQ = 1; //拉高总线 delay(4); x=DQ; //稍做延时后如果x=0则初始化成功x=1则初始化失败delay(20); } /***********ds18b20读一个字节**************/ uchar ReadOneChar() { unsigned char i=0; unsigned char dat = 0; for (i=8;i>0;i--) { 18B20温度传感器应用解析 温度传感器的种类众多,在应用与高精度、高可靠性的场合时DALLAS(达拉斯)公司生产的DS18B20温度传感器当仁不让。超小的体积,超低的硬件开消,抗干扰能力强,精度高,附加功能强,使得DS18B 20更受欢迎。对于我们普通的电子爱好者来说,DS18B20的优势更是我们学习单片机技术和开发温度相关的小产品的不二选择。了解其工作原理和应用可以拓宽您对单片机开发的思路。 DS18B20的主要特征: ?? 全数字温度转换及输出。 ?? 先进的单总线数据通信。 ?? 最高12位分辨率,精度可达土0.5摄氏度。 ?? 12位分辨率时的最大工作周期为750毫秒。 ?? 可选择寄生工作方式。 ?? 检测温度范围为–55°C ~+125°C (–67°F ~+257°F) ?? 内置EEPROM,限温报警功能。 ?? 64位光刻ROM,内置产品序列号,方便多机挂接。 ?? 多样封装形式,适应不同硬件系统。 DS18B20芯片封装结构: DS18B20引脚功能: ·GND 电压地·DQ 单数据总线·VDD 电源电压·NC 空引脚 DS18B20工作原理及应用: DS18B20的温度检测与数字数据输出全集成于一个芯片之上,从而抗干扰力更强。其一个工作周期可分为两个部分,即温度检测和数据处理。在讲解其工作流程之前我们有必要了解18B20的内部存储器资源。18B20共有三种形态的存储器资源,它们分别是: ROM 只读存储器,用于存放DS18B20ID编码,其前8位是单线系列编码(DS18B20的编码是19H),后面48位是芯片唯一的序列号,最后8位是以上56的位的CRC码(冗余校验)。数据在出产时设置不由用户更改。DS18B20共64位ROM。 RAM 数据暂存器,用于内部计算和数据存取,数据在掉电后丢失,DS18B20共9个字节RAM,每个字节为8位。第1、2个字节是温度转换后的数据值信息,第3、4个字节是用户EEPROM(常用于温度报警值储存)的镜像。在上电复位时其值将被刷新。第5个字节则是用户第3个EEPROM的镜像。第6、7、8个字节为计数寄存器,是为了让用户得到更高的温度分辨率而设计的,同样也是内部温度转换、计算的暂存单元。第9个字节为前8个字节的CRC码。EEPROM 非易失性记忆体,用于存放长期需要保存的数据,上下限温度报警值和校验数据,DS18B20共3位EEPROM,并在RAM都存在镜像,以方便用户操作。RAM及EEPROM结构图: 图2 我们在每一次读温度之前都必须进行复杂的且精准时序的处理,因为DS18B20的硬件简单结果就会导致软件的巨大开消,也是尽力减少有形资产转化为无形资产的投入,是一种较好的节约之道。 控制器对18B20操作流程: 1,复位:首先我们必须对DS18B20芯片进行复位,复位就是由控制器(单片机)给DS18B20单总线至少480uS的低电平信号。当18B20接到此复位信号后则会在15~60uS后回发一个芯片的存在脉冲。 2,存在脉冲:在复位电平结束之后,控制器应该将数据单总线拉高,以便于在15~60uS后接收存在脉冲,存在脉冲为一个60~240uS的低电平信号。至此,通信双方已经达成了基本的协议,接下来将会是控制器与18B20间的数据通信。如果复位低电平的时间不足或是单总线的电路断路都不会接到存在脉冲,在设计时要注意意外情况的处理。 3,控制器发送ROM指令:双方打完了招呼之后最要将进行交流了,ROM指令共有5条,每一个工作周期只能发一条,ROM指令分别是读ROM数据、指定匹配芯片、跳跃ROM、芯片搜索、报警芯片搜索。ROM指令为8位长度,功能是对片内的64位光刻ROM进行操作。其主要目的是为了分辨一条总线上挂接的多个器件并作处理。诚然,单总线上可以同时挂接多个器件,并通过每个器件上所独有的ID号来区别,一般只挂接单个18B20芯片时可以跳过ROM指令(注意:此处指的跳过ROM指令并非不发送ROM指令,而是用特有的一条“跳过指令”)。ROM指令在下文有详细的介绍。 4,控制器发送存储器操作指令:在ROM指令发送给18B20之后,紧接着(不间断)就是发送存储器操作指令了。操作指令同样为8位,共6条,存储器操作指令分别是写RAM数据、读RAM数据、将R AM数据复制到EEPROM、温度转换、将EEPROM中的报警值复制到RAM、工作方式切换。存储器操作指令的功能是命令18B20作什么样的工作,是芯片控制的关键。 5,执行或数据读写:一个存储器操作指令结束后则将进行指令执行或数据的读写,这个操作要视存储器操作指令而定。如执行温度转换指令则控制器(单片机)必须等待18B20执行其指令,一般转换时间为500uS。如执行数据读写指令则需要严格遵循18B20的读写时序来操作。数据的读写方法将有下文有详细介绍。 若要读出当前的温度数据我们需要执行两次工作周期,第一个周期为复位、跳过ROM指令、执行温度转换存储器操作指令、等待500uS温度转换时间。紧接着执行第二个周期为复位、跳过ROM指令、执行读 PIC16F877A定时器的学习 由于实时数据的仿真需要用到定时器产生数据,今天晚上完成 PIC16F877A 产生正弦波形,并将波形数据发送到上位机!这是一个三角波的 仿真程序,并通过串口发送到上位机 #include #include #include #include “main.h”#include“t232.h”#include“lcd.h”#include“timer.h” //define global variable bank1 uchar flag =0 ;//利用flag 判断中断时间是否到了!bank1 char dat[6] ; bank2 char str[]=“shan dong qing gong ye xue yuan”;bank2 char str1[]=“Starting........”;bank2 char str2[]=“Capturing.......”;bank2 char str3[]=“Stop..........” ;//bank2 float test = 0;//bank2 float t1 ;bank2 uchar t1 =0 ;bank2 uchar t2=0 ;bank1 uchar state = READY ;//当前状态bank1 uchar frame[3] ;//帧缓冲bank1 uchar temp ;//ms 级延时程序void DelayMS(uint ms){ uint i; while(ms--){ for(i=0;i//10us 级延时程序void Delay10US(uint us){ uchar i; for(i=0;iwhile(1) {while((t1>=-20)&&(state==CAPTURE)){t1++ ;sprintf(dat,”(%d)”,t1) ;send_str(dat) ;if(t1==20)break ;}while((t1} tips:感谢大家的阅读,本文由我司收集整编。仅供参阅! DS18B20单线数字温度传感器 DALLAS半导体公司的数字化温度传感器DS1820是世界上第一片支持“一线总线”接口的温度传感器,体积更小、适用电压更宽、更经济。一线总线独特而且经济的特点,使用户可轻松地组建温度传感器网络,为测量系统的构建引入全新概念。DS18B20、DS1822 “一线总线”数字化温度传感器同DS1820一样,支持“一线总线”接口,测量温度范围为-55°C~+125°C,在-10~+85°C范围内,精度为±0.5°C,而DS1822的精度较差为± 2°C 。现场温度直接以“一线总线”的数字方式传输,大大提高了系统的抗干扰性,适合于恶劣环境的现场温度测量,如:环境控制、设备或过程控制、测温类消费电子产品等。 DS18B20可以程序设定9~12位的分辨率,精度为±0.5°C,分辨率设定,以及用户设定的报警温度存储在EEPROM中,掉电后依然保存。DS1822与DS18B20软件兼容,是DS18B20的简化版本。省略了存储用户定义报警温度、分辨率参数的EEPROM,精度降低为±2°C,适用于对性能要求不高,成本控制严格的应用,是经济型产品。继“一线总线”的早期产品后,DS1820开辟了温度传感器技术的新概念。DS18B20和DS1822使电压、特性及封装有更多的选择,让我们可以构建适合自己的经济的测温系统。 1、 DS18B20性能特点 DS18B20的性能特点:①采用单总线专用技术,既可通过串行口线,也可通过其它I/O口线与微机接口,无须经过其它变换电路,直接输出被测温度值(9位二进制数,含符号位),②测温范围为-55℃-+125℃,测量分辨率为0.0625℃,③内含64位经过激光修正的只读存储器ROM,④适配各种单片机或系统机,⑤用户可分别设定各路温度的上、下限,⑥内含 寄生电源。 2、 DS18B20内部结构 DS18B20内部结构主要由四部分组成:64位光刻 ROM,温度传感器,非挥发的温度报警触发器TH和 TL,高速暂存器。DS18B20的管脚排列如图1所示。64 位光刻ROM是出厂前被光刻好的,它可以看作是该 DS18B20的地址序列号,不同的器件地址序列号不同。 8位产品系列号48位产品序号8位CRC编码DS18B20高速暂存器共9个存储单元,如表所示: 序号寄存器名称作用序号寄存器名称作用 0 温度低字节 以16位补码形式存放4、5 保留字节1、2 1 温度高字节 6 计数器余值 2 TH/用户字节1 存放温度上限7 计数器/℃ 3 HL/用户字节2 存放温度下限8 CRC CRC校验 图1 DS18B20引脚分布图 //////////////////////////////ds18b20模块//////////////////////////////////////////////////// DS18B20是美国DALLAS半导体公司生产的可组网的一线式数字温度传感器,由于DS18B20是在一根I/O线上读写数据,因此,对读写的数据位有着严格的时序要求。 DS18B20有严格的通信协议来保证各位数据传输的正确性和完整性。该协议定义了几种信号的时序:初始化时序、读时序、写时序。所有时序都是将主机作为主设备,单总线器件作为从设备。而每一次命令和数据的传输都是从主机主动启动写时序开始,如果要求单总线器件回送数据,在进行写命令后,主机需启动读时序完成数据接收。数据和命令的传输都是低位在先。以下是常见的DS18B20的测温程序,其正确性笔者已经通过仿真实验和实际电路验证过。 在程序设计时,只要将ds18b20.c和主程序放在同一个工程中,且在主程序中包含头文件ds18b20.h即可。 DS18B20头文件:ds18b20.h #ifndef __DS18B20_H__ #define __DS18B20_H__ void delay_18B20(unsigned int i); Init_DS18B20(void) ; ReadOneChar(void); WriteOneChar(unsigned char dat); ReadTemperature(void); #endif 测温C程序:ds18b20.c #include ;Digit clock ;----------------------------------------------- ;DA TE :20101205 ;Author:Tang HS ;M C U :PIC16F877A ;FileName : ClockPIC.ASM ;----------------------------------------------------------- ;Date: {2010/12/07.14:35}-V er01--CS-ICD:0xAFCE---ISP:0xb7ce---- ;功能: 1.LED显示:时分秒;格式:[ hh mm ss ] 备注:按键未定义 ;------------------------------------------------------------ ;----------------------------------------------------------- ;Date: {2010/12/07.22:15}-V er01--CS-ICD:0xAFCE---ISP:0xb7ce---- ;功能: 1.LED显示:时分秒;格式:[ hh mm ss ] 备注:按键未定义 ; 2.RB0-SET_KEY;RB1-ADD_KEY;RB2-SUB_KEY;RB3-EXIT_KEY ;------------------------------------------------------------ ;Date: {2010/12/09.18:06}-V er02--CS-ICD:0xAFCE---ISP:0xef0e---- ;************************************************************ ;Date: {2010/12/10.00:47}-V er03--CS-ICD:0xb08d---ISP:0xfaa7---- ;功能: 1.LED显示:时分秒;格式:[ hh mm ss ] 备注:按键未定义 ; 2.RB0-SET_KEY;RB1-ADD_KEY;RB2-SUB_KEY;RB3-EXIT_KEY 都OK ; 3.MOVLW 纠正MOVV REG,1 引起的SUB_不良; ;-------------------------------------------------------------- ;Date: {2010/12/10.13:10}-V er03.1--CS-ICD:0xb08b---ISP:0xfaa4---- ; 4.时差。50ms原来计数20次改为19次;250us原来计数200次改为197次;--------------------------------------------------------------- ;Date: {2010/12/10.17:30}-V er03.2--CS-ICD:0x296B---ISP:0x7387---- ; 5.在Set_ini中--增加CALL SET_Flag;指定Flag,1=1;标志位- ---解决Ver03.1-第一次按SET键时不能调HourL&HourH的问题 ;------------------------------------------------------------ ;************************************************ ;程序清单 ;************************************************** __CONFIG 3F39H;设置配置位中振荡方式为XT,其它全部禁止或关闭 ;************************************************ ;----------------------------------------------- include P16F877A.INC ;----------------------------------------------- ;-----------------ram varable------------------------------ HourH equ 20H ; HourL equ 21H ; MinH equ 22H ; MinL equ 23H ; SecH equ 24h ;DS18B20温度检测程序
PIC16F877A与PC机串行通信C语言源程序
PIC16F877A与EEPROM进行SPI通信C程序
ds18b20详解及程序
DS18B20单片机数码管显示原理图和程序
PIC16F877A的特殊功能配置
PIC16F877A.H头文件详细注释
DS18B20温度计C程序
51单片机操作DS18B20汇编源程序
DS18B20中文全套资料
DS18B20 单片机数码管显示原理图和程序
DS18B20中文资料+C程序
PIC16F877A定时器的学习
DS18B20介绍、流程图和程序源代码
ds18b20模块C程序
PIC16F877A数字时钟时钟程序