求一个51单片机控制的温度计显示程序

求一个51单片机控制的温度计显示程序,第1张

这个程序完全没问题的,我做过实验。希望对你有帮助,,,,

//DS18B20的读写程序,数据脚P3.3 //

//温度传感器18B20汇编程序,采用器件默认的12位转化 //

//最大转化时间750微秒,显示温度-55到+125度,显示精度 //

//为0.1度,显示采用4位LED共阳显示测温值//

//P0口为段码输入,P24~P27为位选 //

/***************************************************/

#include "reg51.h"

#include "intrins.h"//_nop_()延时函数

#define Disdata P0 //段码输出口

#define discan P2 //扫描口

#define uchar unsigned char

#define uint unsigned int

sbit DQ=P3^3 //温度输入口

sbit DIN=P0^7 //LED小数点控制

uint h

uchar flag

//**************温度小数部分用查表法***********//

uchar code ditab[16]=

{0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09}

//

uchar code dis_7[12]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf}

//共阳LED段码表"0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "不亮" "-"

uchar code scan_con[4]={0x7f,0xbf,0xdf,0xef} //列扫描控制字

uchar data temp_data[2]={0x00,0x00}//读出温度暂放

uchar data display[5]={0x00,0x00,0x00,0x00,0x00}//显示单元数据,共4个数据和一个运算暂用

//

//

//

/***********11微秒延时函数**********/

//

void delay(uint t)

{

for(t>0t--)

}

//

/***********显示扫描函数**********/

scan()

{

char k

for(k=0k<4k++) //四位LED扫描控制

{

Disdata=0xff

Disdata=dis_7[display[k]]

if(k==1){DIN=0}

discan=scan_con[k]delay(90)

discan=0xff

}

}

//

//

/***********18B20复位函数**********/

ow_reset(void)

{

char presence=1

while(presence)

{

while(presence)

{

DQ=1_nop_()_nop_()

DQ=0 //

delay(50)// 550us

DQ=1 //

delay(6)// 66us

presence=DQ// presence=0继续下一步

}

delay(45) //延时500us

presence = ~DQ

}

DQ=1

}

//

//

/**********18B20写命令函数*********/

//向 1-WIRE 总线上写一个字节

void write_byte(uchar val)

{

uchar i

for (i=8i>0i--) //

{

DQ=1_nop_()_nop_()

DQ = 0_nop_()_nop_()_nop_()_nop_()_nop_()//5us

DQ = val&0x01 //最低位移出

delay(6) //66us

val=val/2 //右移一位

}

DQ = 1

delay(1)

}

//

/*********18B20读1个字节函数********/

//从总线上读取一个字节

uchar read_byte(void)

{

uchar i

uchar value = 0

for (i=8i>0i--)

{

DQ=1_nop_()_nop_()

value>>=1

DQ = 0//

_nop_()_nop_()_nop_()_nop_() //4us

DQ = 1_nop_()_nop_()_nop_()_nop_() //4us

if(DQ)value|=0x80

delay(6) //66us

}

DQ=1

return(value)

}

//

/***********读出温度函数**********/

//

read_temp()

{

ow_reset() //总线复位

write_byte(0xCC)// 发Skip ROM命令

write_byte(0xBE)// 发读命令

temp_data[0]=read_byte()//温度低8位

temp_data[1]=read_byte()//温度高8位

ow_reset()

write_byte(0xCC)// Skip ROM

write_byte(0x44)// 发转换命令

}

//

/***********温度数据处理函数**********/

void work_temp()

{

uchar n=0

uchar doth,dotl

uchar flag3=1,flag2=1 //数字显示修正标记

if((temp_data[1]&0xf8)!=0x00)

{

temp_data[1]=~(temp_data[1])

temp_data[0]=~(temp_data[0])+1

n=1

flag=1

}//负温度求补码

if(temp_data[0]>255)

{

temp_data[1]++

}

display[4]=temp_data[0]&0x0f

display[0]=ditab[display[4]]

doth=display[0]/10

dotl=display[0]%10

display[4]=((temp_data[0]&0xf0)>>4)|((temp_data[1]&0x07)<<4)

display[3]=display[4]/100

display[2]=display[4]/10%10

display[1]=display[4]%10

if(!display[3])

{

display[3]=0x0a

flag3=0

if(!display[2])

{

display[2]=0x0a

flag2=0

}

}//最高位为0时都不显示

if(n)

{

display[3]=0x0b//负温度时最高位显示"-"

flag3=0

}

}

//

//

/**************主函数****************/

main()

{

Disdata=0xff //初始化端口

discan=0xff

for(h=0h<4h++){display[h]=8}//开机显示8888

ow_reset() // 开机先转换一次

write_byte(0xCC)// Skip ROM

write_byte(0x44)// 发转换命令

for(h=0h<500h++)

{scan()} //开机显示"8888"2秒

while(1)

{

read_temp()//读出18B20温度数据

work_temp()//处理温度数据

scan() //显示温度值2秒

}

}

//

//*********************结束**************************//

/****************************************************************

程序名称: 读取DS18B20温度,通过数码管显示出来

说明:使用本程序你必须把 SE6设置为ON(2-3)短接

SE5设置为ON(2-3)短接

*****************************************************************/

/*头文件*/

#include <reg52.h>

#include <intrins.h>

#define uint unsigned int

#define uchar unsigned char

#define nop() _nop_()

#define _Nop() _nop_()

sbit DQ =P3^6 //定义DS18B20通信端口

#define sled_dm_port P0 /*定义数码管段码的控制脚*/

#define sled_wm_port P2/*定义数码管位码的控制脚*/

/*定义数码管显示字符跟数字的对应数组关系*/

uchar code sled_mun_to_char[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e}

/* 0123456789abcdef *//*定义需要点亮的数码管*/

uchar code sled_bit_table[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe}uchar data sled_data[8]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}/*0-7号SLED缓冲值*/

uchar data led_lighten_bit=0 /*LED灯点亮标志位0-7*/

//延时函数

void delay(unsigned int i)

{

while(i--)

}//初始化函数

Init_DS18B20(void)

{

unsigned char x=0

DQ = 1//DQ复位

delay(8)//稍做延时

DQ = 0//单片机将DQ拉低

delay(80)//精确延时 大于 480us

DQ = 1//拉高总线

delay(14)

x=DQ//稍做延时后 如果x=0则初始化成功 x=1则初始化失败

delay(20)

}//读一个字节

ReadOneChar(void)

{

unsigned char i=0

unsigned char dat = 0

for (i=8i>0i--){

DQ = 0// 给脉冲信号

dat>>=1

DQ = 1// 给脉冲信号

if(DQ) dat|=0x80

delay(4)

}

return(dat)

}//写一个字节

WriteOneChar(unsigned char dat)

{

unsigned char i=0

for (i=8i>0i--){

DQ = 0

DQ = dat&0x01

delay(5)

DQ = 1

dat>>=1

}

}//读取温度

ReadTemperature(void)

{

unsigned char a=0

unsigned char b=0

unsigned int t=0

float tt=0

Init_DS18B20()

WriteOneChar(0xCC)// 跳过读序号列号的 *** 作

WriteOneChar(0x44)// 启动温度转换

Init_DS18B20()

WriteOneChar(0xCC)//跳过读序号列号的 *** 作

WriteOneChar(0xBE)//读取温度寄存器等(共可读9个寄存器) 前两个就是温度

a=ReadOneChar()

b=ReadOneChar()

t=b

t<<=8

t=t|a

tt=t*0.0625//将温度的高位与低位合并

t= tt*10+0.5//对结果进行4舍5入

return(t)

}

/*1MS为单位的延时程序*/

void delay_1ms(uchar x)

{

uchar j

while(x--){

for(j=0j<125j++)

{}

}

}main()

{

uint temp_buff

uchar i

while(1){

temp_buff=ReadTemperature()/*读取当前温度*/

sled_data[5] = sled_mun_to_char[temp_buff/100]

sled_data[6] = sled_mun_to_char[temp_buff%100/10]

sled_data[7] = sled_mun_to_char[temp_buff%10]

for(i=0i<8i++){

sled_wm_port = 0xff/*关闭显示*/

_Nop()

_Nop()

_Nop()

sled_dm_port = sled_data[i]/*输出段码数据到数码管*/

if(i==6) sled_dm_port = sled_dm_port&0x7f/*显示小数点*/

sled_wm_port = sled_bit_table[i]/*输出位码数据到数码管*/

delay_1ms(1)

}

}

}


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

原文地址: http://outofmemory.cn/yw/11258053.html

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

发表评论

登录后才能评论

评论列表(0条)

保存