单片机编程问题

DS18B20测温C程序怎么写?... DS18B20测温C程序怎么写? 展开
 我来答
天天向上555abc
推荐于2018-03-13 · TA获得超过407个赞
知道小有建树答主
回答量:275
采纳率:0%
帮助的人:127万
展开全部
/*-----------------------------------------------
名称:18B20温度传感器
内容:18B20单线温度检测的应用样例程序,请将18b20插紧,
然后在数码管可以显示XX.XC,C表示摄氏度,如显示25.3C表示当前温度25.3度
------------------------------------------------*/
#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include<math.h>
#include<INTRINS.H>
#define uchar unsigned char
#define uint unsigned int;
/******************************************************************/
/* 定义端口 */
/******************************************************************/
sbit seg1=P2^0;
sbit seg2=P2^1;
sbit seg3=P2^2;
sbit DQ=P1^3;//ds18b20 端口
sfr dataled=0x80;//显示数据端口
/******************************************************************/
/* 全局变量 */
/******************************************************************/
uint temp;
uchar flag_get,count,num,minute,second;
uchar code tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
//7段数码管段码表共阳
uchar str[6];
/******************************************************************/
/* 函数声明 */
/******************************************************************/
void delay1(uchar MS);
unsigned int ReadTemperature(void);
void Init_DS18B20(void);
unsigned char ReadOneChar(void);
void WriteOneChar(unsigned char dat);
void delay(unsigned int i);
/******************************************************************/
/* 主函数 */
/******************************************************************/
main()
{
unsigned char TempH,TempL;
TMOD|=0x01;//定时器设置
TH0=0xef;
TL0=0xf0;
IE=0x82;
TR0=1;
P2=0x00;
count=0;
while(1)
{
str[5]=0x39; //显示C符号
str[1]=tab[TempH/100]; //百位温度
str[2]=tab[(TempH%100)/10]; //十位温度
str[3]=tab[(TempH%100)%10]|0x80; //个位温度,带小数点
str[4]=tab[TempL];
if(flag_get==1) //定时读取当前温度
{
temp=ReadTemperature();
if(temp&0x8000)
{
str[0]=0x40;//负号标志
temp=~temp; // 取反加1
temp +=1;
}
else
str[0]=0;
TempH=temp>>4;
TempL=temp&0x0F;
TempL=TempL*6/10;//小数近似处理
flag_get=0;
}
}
}

/******************************************************************/
/* 定时器中断 */
/******************************************************************/
void tim(void) interrupt 1 using 1//中断,用于数码管扫描和温度检测间隔
{
TH0=0xef;//定时器重装值
TL0=0xf0;
num++;
if (num==50)
{num=0;
flag_get=1;//标志位有效
second++;
if(second>=60)
{second=0;
minute++;
}
}
count++;
if(count==1)
{P2=0;
dataled=str[0];}//数码管扫描
if(count==2)
{P2=1;
dataled=str[1];}
if(count==3)
{ P2=2;
dataled=str[2];
}
if(count==4)
{ P2=3;
dataled=str[3];
}
if(count==5)
{ P2=4;
dataled=str[4];
}
if(count==6)
{ P2=5;
dataled=str[5];
count=0;}
}
/******************************************************************/
/* 延时函数 */
/******************************************************************/
void delay(unsigned int i)//延时函数
{
while(i--);
}
/******************************************************************/
/* 初始化 */
/******************************************************************/
void Init_DS18B20(void)
{
unsigned char x=0;
DQ = 1; //DQ复位
delay(8); //稍做延时
DQ = 0; //单片机将DQ拉低
delay(80); //精确延时 大于 480us
DQ = 1; //拉高总线
delay(10);
x=DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
delay(5);
}
/******************************************************************/
/* 读一个字节 */
/******************************************************************/
unsigned char ReadOneChar(void)
{
unsigned char i=0;
unsigned char dat = 0;
for (i=8;i>0;i--)
{
DQ = 0; // 给脉冲信号
dat>>=1;
DQ = 1; // 给脉冲信号
if(DQ)
dat|=0x80;
delay(5);
}
return(dat);
}
/******************************************************************/
/* 写一个字节 */
/******************************************************************/
void WriteOneChar(unsigned char dat)
{
unsigned char i=0;
for (i=8; i>0; i--)
{
DQ = 0;
DQ = dat&0x01;
delay(5);
DQ = 1;
dat>>=1;
}
delay(5);
}
/******************************************************************/
/* 读取温度 */
/******************************************************************/
unsigned int ReadTemperature(void)
{
unsigned char a=0;
unsigned int b=0;
unsigned int t=0;
Init_DS18B20();
WriteOneChar(0xCC); // 跳过读序号列号的操作
WriteOneChar(0x44); // 启动温度转换
delay(200);
Init_DS18B20();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
a=ReadOneChar(); //低位
b=ReadOneChar(); //高位
b<<=8;
t=a+b;
return(t);
}
更多追问追答
追问
我要加一个报警电路,是设置一个子函数,然后再main函数里面调用。还是直接在main函数里面写呢?
追答
写在main函数上面,用的时候写函数名就行了
mf31415
2014-04-02 · TA获得超过274个赞
知道小有建树答主
回答量:126
采纳率:100%
帮助的人:109万
展开全部
/**************************************
;www.STCMCU.COM
;Mobile:13922805190
;0755-82948412
温度传感器DS18B20测试程序
主芯片 : STC90C52RC (12T)
工作频率: 12.000MHz
**************************************/

#include "REG51.H"
#include "INTRINS.H"

typedef unsigned char BYTE;

sbit DQ = P3^3; //DS18B20的数据口位P3.3
BYTE TPH; //存放温度值的高字节
BYTE TPL; //存放温度值的低字节

void DelayXus(BYTE n);
void DS18B20_Reset();
void DS18B20_WriteByte(BYTE dat);
BYTE DS18B20_ReadByte();

void main()
{
DS18B20_Reset(); //设备复位
DS18B20_WriteByte(0xCC); //跳过ROM命令
DS18B20_WriteByte(0x44); //开始转换命令
while (!DQ); //等待转换完成

DS18B20_Reset(); //设备复位
DS18B20_WriteByte(0xCC); //跳过ROM命令
DS18B20_WriteByte(0xBE); //读暂存存储器命令
TPL = DS18B20_ReadByte(); //读温度低字节
TPH = DS18B20_ReadByte(); //读温度高字节

while (1);
}

/**************************************
延时X*10微秒(STC90C52RC@12M)
不同的工作环境,需要调整此函数
当改用1T的MCU时,请调整此延时函数
**************************************/
void DelayX0us(BYTE n)
{
while (n--)
{
_nop_();
_nop_();
}
}

/**************************************
复位DS18B20,并检测设备是否存在
**************************************/
void DS18B20_Reset()
{
CY = 1;
while (CY)
{
DQ = 0; //送出低电平复位信号
DelayX0us(48); //延时至少480us
DQ = 1; //释放数据线
DelayX0us(6); //等待60us
CY = DQ; //检测存在脉冲
DelayX0us(42); //等待设备释放数据线
}
}

/**************************************
从DS18B20读1字节数据
**************************************/
BYTE DS18B20_ReadByte()
{
BYTE i;
BYTE dat = 0;

for (i=0; i<8; i++) //8位计数器
{
dat >>= 1;
DQ = 0; //开始时间片
_nop_(); //延时等待
_nop_();
DQ = 1; //准备接收
_nop_(); //接收延时
_nop_();
if (DQ) dat |= 0x80; //读取数据
DelayX0us(6); //等待时间片结束
}

return dat;
}

/**************************************
向DS18B20写1字节数据
**************************************/
void DS18B20_WriteByte(BYTE dat)
{
char i;

for (i=0; i<8; i++) //8位计数器
{
DQ = 0; //开始时间片
_nop_(); //延时等待
_nop_();
dat >>= 1; //送出数据
DQ = CY;
DelayX0us(6); //等待时间片结束
DQ = 1; //恢复数据线
}
}
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
5922771321
2014-04-02 · TA获得超过1438个赞
知道小有建树答主
回答量:1410
采纳率:100%
帮助的人:358万
展开全部

/***************   writer:shopping.w   ******************/
#include <reg52.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
#define delayNOP() {_nop_();_nop_();_nop_();_nop_();}
sbit DQ = P3^3;
sbit LCD_RS = P2^0;
sbit LCD_RW = P2^1;
sbit LCD_EN = P2^2;
uchar code Temp_Disp_Title[]={"Current Temp : "};
uchar Current_Temp_Display_Buffer[]={" TEMP:   "};
uchar code Temperature_Char[8] =
{
  0x0c,0x12,0x12,0x0c,0x00,0x00,0x00,0x00
};
uchar code df_Table[]=
{
  0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9
};
uchar CurrentT = 0;
uchar Temp_Value[]={0x00,0x00};
uchar Display_Digit[]={0,0,0,0};
bit DS18B20_IS_OK = 1;
void DelayXus(uint x)
{
  uchar i;
while(x--)
{
   for(i=0;i<200;i++);
}
}
bit LCD_Busy_Check()
{
  bit result;
LCD_RS = 0;
LCD_RW = 1;
LCD_EN = 1;
delayNOP();
result = (bit)(P0&0x80);
LCD_EN=0;
return result;
}
void Write_LCD_Command(uchar cmd)
{
while(LCD_Busy_Check());
LCD_RS = 0;
LCD_RW = 0;
LCD_EN = 0;
_nop_();
_nop_();
P0 = cmd;
delayNOP();
LCD_EN = 1;
delayNOP();
LCD_EN = 0;
}
void Write_LCD_Data(uchar dat)
{
while(LCD_Busy_Check());
LCD_RS = 1;
LCD_RW = 0;
LCD_EN = 0;
P0 = dat;
delayNOP();
LCD_EN = 1;
delayNOP();
LCD_EN = 0;
}
void LCD_Initialise()
{
  Write_LCD_Command(0x01);
DelayXus(5);
Write_LCD_Command(0x38);
DelayXus(5);
Write_LCD_Command(0x0c);
DelayXus(5);
Write_LCD_Command(0x06);
DelayXus(5);
}
void Set_LCD_POS(uchar pos)
{
  Write_LCD_Command(pos|0x80);
}
void Delay(uint x)
{
  while(--x);
}
uchar Init_DS18B20()
{
  uchar status;
DQ = 1;
Delay(8);
DQ = 0;
Delay(90);
DQ = 1;
Delay(8);
DQ = 1;
return status;
}
uchar ReadOneByte()
{
  uchar i,dat=0;
DQ = 1;
_nop_();
for(i=0;i<8;i++)
{
   DQ = 0;
  dat >>= 1;
  DQ = 1;
  _nop_();
  _nop_();
  if(DQ)
   dat |= 0X80;
  Delay(30);
  DQ = 1;
}
return dat;
}
void WriteOneByte(uchar dat)
{
  uchar i;
for(i=0;i<8;i++)
{
   DQ = 0;
  DQ = dat& 0x01;
  Delay(5);
  DQ = 1;
  dat >>= 1;
}
}
void Read_Temperature()
{
  if(Init_DS18B20()==1)
  DS18B20_IS_OK=0;
else
{
  WriteOneByte(0xcc);
  WriteOneByte(0x44);
  Init_DS18B20();
  WriteOneByte(0xcc);
  WriteOneByte(0xbe);
  Temp_Value[0] = ReadOneByte();
  Temp_Value[1] = ReadOneByte();
  DS18B20_IS_OK=1;
}
}
void Display_Temperature()
{
  uchar i;
uchar t = 150, ng = 0;
if((Temp_Value[1]&0xf8)==0xf8)
{
   Temp_Value[1] = ~Temp_Value[1];
  Temp_Value[0] = ~Temp_Value[0]+1;
  if(Temp_Value[0]==0x00)
   Temp_Value[1]++;
  ng = 1;
}
Display_Digit[0] = df_Table[Temp_Value[0]&0x0f];
CurrentT = ((Temp_Value[0]&0xf0)>>4) | ((Temp_Value[1]&0x07)<<4);
Display_Digit[3] = CurrentT/100;
Display_Digit[2] = CurrentT%100/10;
Display_Digit[1] = CurrentT%10;
Current_Temp_Display_Buffer[11] = Display_Digit[0] + '0';
Current_Temp_Display_Buffer[10] = '.';
Current_Temp_Display_Buffer[9]  = Display_Digit[1] + '0';
Current_Temp_Display_Buffer[8]  = Display_Digit[2] + '0';
Current_Temp_Display_Buffer[7]  = Display_Digit[3] + '0';
if(Display_Digit[3] == 0)
  Current_Temp_Display_Buffer[7]  = ' ';
if(Display_Digit[2] == 0&&Display_Digit[3]==0)
  Current_Temp_Display_Buffer[8]  = ' ';
if(ng)
{
   if(Current_Temp_Display_Buffer[8]  == ' ')
   Current_Temp_Display_Buffer[8]  = '-';
  else if(Current_Temp_Display_Buffer[7]  == ' ')
   Current_Temp_Display_Buffer[7]  = '-';
  else
   Current_Temp_Display_Buffer[6]  = '-';
}
Set_LCD_POS(0x00);
for(i=0;i<16;i++)
{
  Write_LCD_Data(Temp_Disp_Title[i]); 
}
Set_LCD_POS(0x40);
for(i=0;i<16;i++)
{
  Write_LCD_Data(Current_Temp_Display_Buffer[i]); 

Set_LCD_POS(0x4d);
Write_LCD_Data(0x00);
Set_LCD_POS(0x4e);
Write_LCD_Data('C');
}
void main()
{
  LCD_Initialise();
Read_Temperature();
Delay(50000);
Delay(50000);
while(1)
{
   Read_Temperature();
  if(DS18B20_IS_OK)
   Display_Temperature();
  DelayXus(100); 
}
}

以上程序来自《单片机C语言程序设计实训100例基于8051+Proteus仿真》

电路和程序!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

追问
我要加一个报警电路,是设置一个子函数,然后再main函数里面调用。还是直接在main函数里面写呢?
追答
写一个子函数比较好!!
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
zhxiufan
2018-07-31 · 知道合伙人软件行家
zhxiufan
知道合伙人软件行家
采纳数:14923 获赞数:38379
国家科技进步奖

向TA提问 私信TA
展开全部
这是用C51编写的单片机源代码,这里只是函数的申明部分和宏定义部分。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(2)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式