跪求 单片机进行温度检测的C语言程序

跪求 单片机进行温度检测的C语言程序,第1张

//DS18B20的读写程序,数据脚P2.7 //

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

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

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

//P0口为段码输入,P34~P37为位选 //

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

#include "reg51.h"

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

#define Disdata P0 //段码输出口

#define discan P3 //扫描口

#define uchar unsigned char

#define uint unsigned int

sbit DQ=P2^7 //温度输入口

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

uint h

uint temp

//

//

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

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个数据和一个运算暂用

//

//

//

/*****************11us延时函数*************************/

//

void delay(uint t)

{

for (t>0t--)

}

//

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

scan()

{

char k

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

{

Disdata=dis_7[display[k]] //数据显示

if (k==1){DIN=0} //小数点显示

discan=scan_con[k]//位选

delay(300)

}

}

//

//

/****************DS18B20复位函数************************/

ow_reset(void)

{

char presence=1

while(presence)

{

while(presence)

{

DQ=1_nop_()_nop_()//从高拉倒低

DQ=0

delay(50) //550 us

DQ=1

delay(6) //66 us

presence=DQ//presence=0 复位成功,继续下一步

}

delay(45) //延时500 us

presence=~DQ

}

DQ=1 //拉高电平

}

//

//

/****************DS18B20写命令函数************************/

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

void write_byte(uchar val)

{

uchar i

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

{

DQ=1_nop_()_nop_() //从高拉倒低

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

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

delay(6) //66 us

val=val/2//右移1位

}

DQ=1

delay(1)

}

//

/****************DS18B20读1字节函数************************/

//从总线上取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_()//4 us

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

if(DQ)value|=0x80

delay(6)//66 us

}

DQ=1

return(value)

}

//

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

//

read_temp()

{

ow_reset() //总线复位

delay(200)

write_byte(0xcc) //发命令

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

ow_reset()

delay(1)

write_byte(0xcc) //发命令

write_byte(0xbe)

temp_data[0]=read_byte() //读温度值的第字节

temp_data[1]=read_byte() //读温度值的高字节

temp=temp_data[1]

temp<<=8

temp=temp|temp_data[0] // 两字节合成一个整型变量。

return temp//返回温度值

}

//

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

//二进制高字节的低半字节和低字节的高半字节组成一字节,这个

//字节的二进制转换为十进制后,就是温度值的百、十、个位值,而剩

//下的低字节的低半字节转化成十进制后,就是温度值的小数部分

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

work_temp(uint tem)

{

uchar n=0

if(tem>6348)// 温度值正负判断

{tem=65536-temn=1}// 负温度求补码,标志位置1

display[4]=tem&0x0f // 取小数部分的值

display[0]=ditab[display[4]] // 存入小数部分显示值

display[4]=tem>>4// 取中间八位,即整数部分的值

display[3]=display[4]/100// 取百位数据暂存

display[1]=display[4]%100// 取后两位数据暂存

display[2]=display[1]/10 // 取十位数据暂存

display[1]=display[1]%10

/******************符号位显示判断**************************/

if(!display[3])

{

display[3]=0x0a //最高位为0时不显示

if(!display[2])

{

display[2]=0x0a //次高位为0时不显示

}

}

if(n){display[3]=0x0b} //负温度时最高位显示"-"

}

//

//

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

main()

{

Disdata=0xff//初始化端口

discan=0xff

for(h=0h<4h++) //开机显示"0000"

{display[h]=0}

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

write_byte(0xcc)//Skip ROM

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

for(h=0h<100h++)//开机显示"0000"

{scan()}

while(1)

{

work_temp(read_temp())//处理温度数据

scan()//显示温度值

}

}

//

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

用c很简单 ,

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

FILE NAME:DS18B20.c

CHIP TYPE:ATMEGA16

CLOCK FREQUENCY: 8MHZ

IDE: VSMStudio

COMPILER: AVR-GCC

TIME: September 2010

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

#include <avr/io.h>

#include <util/delay.h>

#define uchar unsigned char

#define uint unsigned int

#define BUS PORTC

// Low level port/pin definitions

#define sbit(x,PORT) (PORT) |= (1<<x)

#define cbit(x,PORT) (PORT) &= ~(1<<x)

#define pin(x,PIN) (PIN) &(1<<x)

// Pins definition

#define s_digit1 sbit(5,PORTC)

#define c_digit1 cbit(5,PORTC)

#define s_digit2 sbit(4,PORTC)

#define c_digit2 cbit(4,PORTC)

#define outPORTC

#define DQ_IN DDRA&=~(1<<7)

#define DQ_OUT DDRA|=(1<<7)

#define S_DQ sbit(7,PORTA)

#define C_DQ cbit(7,PORTA)

#define DQ pin(7,PINA)

// Function Prototypes

void init_ds18b20(void)

uchar readbyte(void)

void writecommand(uchar)

uchar readtemp(void)

uchar a, b, tt

// Main program

int main(void)

{ uchar i=0, temp

// Initialize Stack Pointer

SPL=0x54

SPH=0x04

// Configure port pins

DDRC = 0xff

DDRA = 0xff

while(1)

{ temp = readtemp()

for(i=0i<10i++) // 10 measures

{ // output the units

out = (temp/10) &0x0f

s_digit1

c_digit2

_delay_ms(5)

// output the tens

out = (temp%10) &0x0f

c_digit1

s_digit2

_delay_ms(5)

}

}

}

// Start transaction with 1-wire line.

void init_ds18b20(void)

{ DQ_OUT

C_DQ

_delay_us(600)

S_DQ

_delay_us(50)

DQ_IN

while(DQ)

_delay_us(240)

DQ_OUT

S_DQ

_delay_us(300)

}

// Read a byte from the sensor

uchar readbyte(void)

{ uchar i = 0,data = 0

DQ_OUT

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

{ C_DQ

data >>= 1

_delay_us(3)

S_DQ

DQ_IN

_delay_us(12)

if(DQ)

data |= 0x80

DQ_OUT

S_DQ

_delay_us(45)

_delay_us(5)

}

return(data)

}

// Write a command to the sensor

void writecommand(uchar data)

{ uchar i

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

{ C_DQ

_delay_us(15)

if(data &0x01)

S_DQ

else

C_DQ

_delay_us(45)

data >>= 1

S_DQ

_delay_us(2)

}

}

// Read value from the sensor

uchar readtemp(void)

{ uint t

init_ds18b20()

// Convert

writecommand(0xCC)

writecommand(0x44)

init_ds18b20()

// Read Scratch memory area

writecommand(0xCC)

writecommand(0xBE)

a = readbyte()

b = readbyte()

t = b

t <<= 8

t = t|a

tt = t*0.0625

return(tt)

}

这是关于DS18B20的读写程序,数据脚P2.2,晶振12MHZ

温度传感器18B20汇编程序,采用器件默认的12位转化,最大转化时间750微秒

可以将检测到的温度直接显示到AT89C51开发实验板的两个数码管上

显示温度00到99度,很准确哦~~无需校正!

ORG 0000H 单片机内存分配申明!

TEMPER_L EQU 29H用于保存读出温度的低8位

TEMPER_H EQU 28H用于保存读出温度的高8位

FLAG1 EQU 38H是否检测到DS18B20标志位

a_bit equ 20h 数码管个位数存放内存位置

b_bit equ 21h 数码管十位数存放内存位置

TEMP_TH EQU

MAIN:

LCALL GET_TEMPER调用读温度子程序 ,显示范围00到99度,显示精度为1度

因为12位转化时每一位的精度为0.0625度,我们不要求显示小数所以可以抛弃29H的低4位

将28H中的低4位移入29H中的高4位,这样获得一个新字节,这个字节就是实际测量获得的温度

MOV A,29H

MOV C,40H将28H中的最低位移入C

RRC A

MOV C,41H

RRC A

MOV C,42H

RRC A

MOV C,43H

RRC A

MOV 29H,A

LCALL DISPLAY 调用数码管显示子程序

CPL P1.0

AJMP MAIN

这是DS18B20复位初始化子程序

INIT_1820:

SETB P3.5

NOP

CLR P3.5 主机发出延时537微秒的复位低脉冲

MOV R1,#3

TSR1:MOV R0,#107

DJNZ R0,$

DJNZ R1,TSR1

SETB P3.5 然后拉高数据线

NOP

NOP

NOP

MOV R0,#25H

TSR2:

JNB P3.5,TSR3 等待DS18B20回应

DJNZ R0,TSR2

LJMP TSR4 延时

TSR3:

SETB FLAG1 置标志位,表示DS1820存在

CLR P1.7 检查到DS18B20就点亮P1.7LED

LJMP TSR5

TSR4:

CLR FLAG1 清标志位,表示DS1820不存在

CLR P1.1 点亮P1。1脚LED表示温度传感器通信失败

LJMP TSR7

TSR5:

MOV R0,#117

TSR6:

DJNZ R0,TSR6 时序要求延时一段时间

TSR7:

SETB P3.5

RET

读出转换后的温度值

GET_TEMPER:

SETB P3.5

LCALL INIT_1820 先复位DS18B20

JB FLAG1,TSS2

CLR P1.2

RET 判断DS1820是否存在?若DS18B20不存在则返回

TSS2:

CLR P1.3 DS18B20已经被检测到!!!!!!!!!!!!!!!!!!

MOV A,#0CCH

LCALL WRITE_1820

MOV A,#44H 发出温度转换命令

LCALL WRITE_1820

这里通过调用显示子程序实现延时一段时间,等待AD转换结束,12位的话750微秒

LCALL DISPLAY

LCALL INIT_1820 准备读温度前先复位

MOV A,#0CCH 跳过ROM匹配

LCALL WRITE_1820

MOV A,#0BEH 发出读温度命令

LCALL WRITE_1820

LCALL READ_18200将读出的温度数据保存到35H/36H

CLR P1.4

RET

写DS18B20的子程序(有具体的时序要求)

WRITE_1820:

MOV R2,#8一共8位数据

CLR C

WR1:

CLR P3.5

MOV R3,#6

DJNZ R3,$

RRC A

MOV P3.5,C

MOV R3,#23

DJNZ R3,$

SETB P3.5

NOP

DJNZ R2,WR1

SETB P3.5

RET

读DS18B20的程序,从DS18B20中读出两个字节的温度数据

READ_18200:

MOV R4,#2 将温度高位和低位从DS18B20中读出

MOV R1,#29H 低位存入29H(TEMPER_L),高位存入28H(TEMPER_H)

RE00:

MOV R2,#8数据一共有8位

RE01:

CLR C

SETB P3.5

NOP

NOP

CLR P3.5

NOP

NOP

NOP

SETB P3.5

MOV R3,#9

RE10:

DJNZ R3,RE10

MOV C,P3.5

MOV R3,#23

RE20:

DJNZ R3,RE20

RRC A

DJNZ R2,RE01

MOV @R1,A

DEC R1

DJNZ R4,RE00

RET

显示子程序

display: mov a,29H将29H中的十六进制数转换成10进制

mov b,#10 10进制/10=10进制

div ab

mov b_bit,a 十位在a

mov a_bit,b 个位在b

mov dptr,#numtab 指定查表启始地址

mov r0,#4

dpl1: mov r1,#250 显示1000次

dplop: mov a,a_bit 取个位数

MOVC A,@A+DPTR 查个位数的7段代码

mov p1,a 送出个位的7段代码

setb p2.0 开个位显示

acall d1ms 显示1ms

clr p2.0

mov a,b_bit 取十位数

MOVC A,@A+DPTR 查十位数的7段代码

mov p1,a 送出十位的7段代码

setb p2.1 开十位显示

acall d1ms 显示1ms

clr p2.1

djnz r1,dplop 100次没完循环

djnz r0,dpl1 4个100次没完循环

ret

1MS延时(按12MHZ算)

D1MS: MOV R7,#80

DJNZ R7,$

RET

numtab:数码管共阳极0~9代码

DB 0C0H,0F9H,0A4H,0B0H,99H, 92H,82H,0F8H,80H,90H

end


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

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

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

发表评论

登录后才能评论

评论列表(0条)

保存