51单片机以定时中断的方法实现DS18B20时序

发布者:boczsy2018最新更新时间:2022-04-21 来源: eefocus关键字:51单片机  定时中断  DS18B20  时序 手机看文章 扫描二维码
随时随地手机看文章

由于DS18B20是单线操作,所以必须严格遵守它的时序要求才能正常与之建立联系并实现读写操作。


网上见到的程序多是在主程序中以延时的方式实现,而且要求关中断,以实现18B20对时序的要求。但是实际应用中,测温操作一般是作为辅助功能,主要任务是通信及数据处理等其他操作,这样一来,如果将DS18B20的程序代码放在主程序中,势必影响其他需要实时处理的中断。


前些天用到DS18B20,就尝试以51定时中断的方法实现DS18B20时序,在面包板上成功跑了起来。


用的单片机是STC11F16XE,使用外部晶振24MHz。下面的程序中不仅有DS18B20的操作,还包含了数码管显示、按键检测、EEPROM的操作。定时器T1专门用于DS18B20时序产生,定时器T0用于按键检测、数码管显示,主函数中做EEPROM及其他的操作。程序中有些注释是调试过程中加的,并且有些代码部分在调试中修改过,先前的注释并没有同时删去,所以看下面的代码的时候,不要被注释误导了。


代码如下:


#include "REG51.H"

#include "INTRINS.H"



typedef unsigned char BYTE;

typedef unsigned int WORD;



sfr P1M0 = 0x92; //                                                                      

sfr P1M1 = 0x91; // 



sfr P3M0 = 0xB2;

sfr P3M1 = 0xB1;



sfr P2M0 = 0x96;

sfr P2M1 = 0x95;



/*sfr associated with the IAP*/

sfr IAP_DATA = 0xc2;

sfr IAP_ADDRH = 0xc3;

sfr IAP_ADDRL = 0xc4;

sfr IAP_CMD = 0xc5;

sfr IAP_TRIG = 0xc6;

sfr IAP_CONTR = 0xc7;

/*ISP/IAP/EEPROM command*/

#define CMD_IDLE 0

#define CMD_READ 1

#define CMD_PROGRAM 2

#define CMD_ERASE 3



#define ENABLE_IAP 0x80 //if SYSCLK<30MHz

//#define ENABLE_IAP 0x81//if SYSCLK<24MHz



//start address for STC11/10xx series EEPROM

#define IAP_ADDRESS0x0000



void Delay(BYTE N);

void IapIdle();

BYTE IapReadByte(WORD addr);

void IapProgramByte(WORD addr, BYTE val);

void IapEraseSector(WORD addr);



#define MINUTE 8400  //60*140=8400 interrupts per minute

#define DAY3S 4320  //there are 72*60*8400=4320*8400 interrupts in 72 hours

//

sbit shi = P3^7;

sbit ge = P3^2;

//sbit led = P1^5;



sbit key1 = P3^3;

sbit key2 = P3^4;

sbit key3 = P3^5;



sbit heat = P2^7;

sbit water = P2^5;

sbit beep = P2^0;



unsigned char code digit[11] ={

0xbf,//0

0x83,//1

0xed,//2

0xeb,//3

0xd3,//4

0xfa,//5

0xfe,//6

0xa3,//7

0xff,//8

0xfb,//9

0xc0//nfinished

}; 



unsigned char code cmd[4] = {0xcc,0x44,0xcc,0xbe};

unsigned int cmd_n;

bit nodevice,cunz;

unsigned char saom;

unsigned int num,t1_num;

unsigned char temp,led;

unsigned int jiaoshui,jiaoshui_t,jiaoshui_tt;



unsigned char wendu,cishu;

unsigned int ds18b20;

unsigned char menu,inc,dec;

BYTE kflag;  //

bit adjust;

bit updateEEP;



unsigned int heat_t;



sbit DQ = P3^1;                     //DS18B20?????P3.3

BYTE TPH;                           //?????????

BYTE TPL;                           //?????????

BYTE dat;



void main()

{

  updateEEP = 0;

num = 0;

temp = 0;

saom = 0;

led = 0x00;

nodevice = 0;


menu = 0;

inc = 0;

dec = 0;

kflag = 0x00;

adjust = 0;


wendu = 50;

cishu = 72;

heat = 1;

water = 1;

jiaoshui = 0;

jiaoshui_t = 1;

jiaoshui_tt = 0;


P2M0 = 0x01;

P2M1 = 0x00;

beep = 0;


P1M0 = 0xff; //                                                                      

  P1M1 = 0x00; // 

// P1 = digit[0];


P3M0 = 0x84; //                                                                         

  P3M1 = 0x84;

P3 = 0X0;


TMOD = 0x11; //TMOD = 0x1;

TH0 = 0x00;

TL0 = 0xff;

TR0 = 1;

ET0 = 1;


TH1 = 0xff;

TL1 = 0x88;//256-120=136=0x88

TR1 = 0;

ET1 = 1; // enable T1 interrupt

PT0 = 0;

PT1 = 1; // T1优先级高


EA = 1;



//read wendu and cishu value from EEPROM

Delay(10);

wendu = IapReadByte(0x0002);

cishu = IapReadByte(0x0003);



jiaoshui = 8400/cishu;



//

  while (1)

{

if(updateEEP == 1)

{

updateEEP = 0;


IapEraseSector(0x0000);

IapProgramByte(0x0002,wendu);

IapProgramByte(0x0003,cishu);


jiaoshui = 8400/cishu;

}



beep= (ds18b20>30)? 1:0;

heat= (ds18b20>30)? 0:1;

water=(jiaoshui_t<420)? 0:1;

// beep= (jiaoshui_t<420)? 1:0;

}

}





/

void it_timer0(void) interrupt 1

{

TH0 = 0xc8;  //定时时间是1/140s

TL0 = 0x32;

num++;

/*

if(jiaoshui_t

   

    0) wendu--; 

else wendu=0; 

kflag = 0x00; break;}

else if(menu==2)

{if(cishu>0) cishu--;

else cishu=0; 

kflag = 0x00; break;}

else break;

default ://??????????????

break;

}

// P1M0 = 0xff;

// P1M1 = 0x00;


//显示

saom++;

saom = saom%3;


switch(menu)

{

case 0 : temp = ds18b20; led = 0x00; break;

case 1 : temp = wendu; led = 0x02; break;

case 2 : temp = cishu; led = 0x01; break;

default : temp = ds18b20; break;

}


if(nodevice)

{

shi = 0;

ge = 0;

P1 = digit[10];

}

else

switch(saom)

{

case 0 :

shi = 0;

ge = 1;

P1 = digit[temp/10];

break;

case 1 :

shi = 1;

ge = 0;

P1 = digit[temp%10];

break;

case 2 :

shi = 1;

ge = 1;

if(num < 80) P1 = led;

else P1 = 0x80;

break;

default : break;

}

/*

//加热定时

if(ds18b20>30) {heat = 1; heat_t++;}

if((heat_t > 0) && (heat_t < 1400))

{heat_t++;}

else {heat_t = 0; heat = 0;}

*/



//采集18B20

if(num>=140)

{

num = 0;

t1_num = 0; cmd_n = 0; nodevice = 0;

TR1 = 1; 

}



}





void it_timer1(void) interrupt 3

{


switch(t1_num)

{

case 0 :

case 33 :

cunz = 1; DQ = 0; break;

case 8 :

case 41 :

DQ = 1; break;

case 9 :

case 42 :

cunz = DQ; break;

case 16 :  //写字节  第一位

case 49 :

if(cunz) {/*ET1 = 0;*/TR1 = 0; nodevice = 1; break;}

else

{

dat = cmd[cmd_n++]; DQ = 0; _nop_(); _nop_(); 

dat >>= 1; DQ = CY; break;

}

case 17 : //cmd[0]

case 18 :

case 19 :

case 20 :

case 21 :

case 22 :

case 23 :


case 25 : //cmd[1]

case 26 :

case 27 :

case 28 :

case 29 :

case 30 :

case 31 :


case 50 : //cmd[2]

case 51 :

case 52 :

case 53 :

case 54 :

case 55 :

case 56 :


case 58 : //cmd[3]

case 59 :

case 60 :

case 61 :

case 62 :

case 63 :

case 64 :


DQ = 1; _nop_(); _nop_(); //恢复数据线,恢复时间

 DQ = 0; _nop_(); _nop_(); //开始下一位

 dat >>= 1; DQ = CY; break;

case 24 :

case 57 :

DQ = 1; _nop_(); _nop_(); //写第一个字节结束

dat = cmd[cmd_n++];       //填充dat

DQ = 0; _nop_(); _nop_();  //写第二个字节

dat >>= 1; DQ = CY; break;

case 32 :

DQ = 1; _nop_(); _nop_();  //写第二个字节结束 0x44

_nop_(); _nop_();

case 65 :

DQ = 1; _nop_(); _nop_();   //0xbe 命令发完

dat = 0; //读TPL

dat >>= 1;

DQ = 0; _nop_(); _nop_();

DQ = 1; _nop_(); _nop_();

if(DQ) dat |= 0x80;

break;

case 66 :

case 67 :

case 68 :

case 69 :

case 70 :

case 71 :

case 72 :


case 74 :

case 75 :

case 76 :

case 77 :

case 78 :

case 79 :

case 80 :

dat >>= 1;

DQ = 0; _nop_(); _nop_();

DQ = 1; _nop_(); _nop_();

if(DQ) dat |= 0x80;

break;

case 73 :

TPL = dat;

 dat = 0; //读TPH

dat >>= 1;

DQ = 0; _nop_(); _nop_();

DQ = 1; _nop_(); _nop_();

if(DQ) dat |= 0x80;

break;

case 81 :

TPH = dat;

TPL = (TPL>>4) & 0x0f;

TPH = (TPH<<4) & 0xf0;

ds18b20 = TPL | TPH;

if(ds18b20>99 | ds18b20 <=0)

nodevice = 1;


TR1 = 0;

break;

default : break;

}


t1_num++;


TH1 = 0xff;

TL1 = 0x88;//256-120=136=0x88

}



//

void Delay(BYTE n)

{

WORD x;

while(n--)

{

x = 0;

while(++x);

}

}



void IapIdle()

{

IAP_CONTR = 0;

IAP_CMD = 0;

IAP_TRIG = 0;

IAP_ADDRH = 0xff;

IAP_ADDRL = 0xff;

}



BYTE IapReadByte(WORD addr)

{

BYTE rdval;


IAP_CONTR = ENABLE_IAP;

IAP_CMD = CMD_READ;

IAP_ADDRL = addr;

IAP_ADDRH = addr >> 8;

IAP_TRIG = 0x5a;

IAP_TRIG = 0xa5;

_nop_();


rdval = IAP_DATA;

IapIdle();


return rdval;

}



void IapProgramByte(WORD addr, BYTE val)

{

IAP_CONTR = ENABLE_IAP;

IAP_CMD = CMD_PROGRAM;

IAP_ADDRL = addr;

IAP_ADDRH = addr >> 8;

IAP_DATA = val;

IAP_TRIG = 0x5a;

IAP_TRIG = 0xa5;

_nop_();


IapIdle();

}



void IapEraseSector(WORD addr)

{

IAP_CONTR = ENABLE_IAP;

IAP_CMD = CMD_ERASE;

IAP_ADDRL = addr;

IAP_ADDRH = addr >> 8;

IAP_TRIG = 0x5a;

IAP_TRIG = 0xa5;

_nop_();


IapIdle();

}

关键字:51单片机  定时中断  DS18B20  时序 引用地址:51单片机以定时中断的方法实现DS18B20时序

上一篇:单片机_LCD12864显示自己制作的图片(时钟为例)
下一篇:基于单片机的电梯(四层)控制系统设计

推荐阅读最新更新时间:2024-11-12 10:48

单片机关于时钟和不同字节不同指令时序(ALE)
首先贴上时钟的结构和电路: 了解下什么是机器周期和指令周期: 各种不同字节不同周期指令的时序(important):
[单片机]
单片机关于时钟和不同字节不同指令<font color='red'>时序</font>(ALE)
MCS-51单片机主要应用特性
  MCS-51单片机是美国INTE公司于1980年推出的产品,与MCS-48单片机相比,它的结构更先进,功能更强,在原来的基础上增加了更多的电路单元和指令,指令数达111条,MCS-51单片机可以算是相当成功的产品,一直到现在,MCS-51系列或其兼容的单片机仍是应用的主流产品,各高校及专业学校的培训教材仍与MCS-51单片机作为代表进行理论基础学习。我们也以这一代表性的机型进行系统的讲解。   MCS-51系列单片机主要包括8031、8051和8751等通用产品,其主要功能如下:   ·8位CPU   ·4kbytes 程序存储器(ROM)   ·128bytes的数据存储器(RAM)   ·32条I/O口线   
[单片机]
MCS-<font color='red'>51单片机</font>主要应用特性
51单片机小白零基础教程——数码管的动态显示
数码管的动态显示 数码管的动态显示:数码管的动态显示又叫做数码管的动态扫描。动态显示的特点是:将所有位数码管段选线并联在一起,,由位选控制是哪一位数码管有效。所谓动态扫描显示即轮流向各位数码管送出字型码和相应的位选,利用发光管的余晖和人眼视觉暂留作用,使人感觉好像各位数码管同时都在显示,而实际上多位数码管是一位一位轮流显示的,只是轮流的速度比较快,人眼已经无法分辨出来。 关于数码管以及74HC573锁存器的分析放在这,有详细的分析过程,请自行查看https://blog.csdn.net/chrisbum/article/details/115583779?spm=1001.2014.3001.5502 设计要求:在实验板
[单片机]
<font color='red'>51单片机</font>小白零基础教程——数码管的动态显示
51单片机C语言学习笔记5:include的区别
#include iostream.h #include myfile_h #include 是预处理器标识符。 表示是标准的工程、标准的头文件。查找过程检查预定义的目录。可通过设置搜索路径环境变量或命令行修改这些目录 则表明是用户提供的头文件。查找该文件从当前文件所在的目录开始。 关于C51的库函数可以参考下面文档 参考资料: 1)资料共享,KEIL C51库函数 http://blog.ednchina.com/IET/101947/message.aspx 2)第五章 Keil C51库函数参考(转帖) -- HotPower的文潭 http://blog.ednchina.
[单片机]
如何以AT89C51单片机为核心设计一个剪板机的控制电路?
本文介绍了一种用精密是采用交流接触器、中间继电器、行程开关及脚踏开关等电器来控制剪板机剪切。在生产使用过程中由于剪切频率高(1分钟约30刀),剪板机长期在这种频繁的工作状态下运行,难免经常会出现故障,影响生产效率,加重了维修工作量。 故障主要表现如下几方面;行程开关、脚踏开关、交流接触器及中间继电器等。 针对上述的问题,采用单片机作为控制的核心,用三相交流固态继电器JG-27F/40A380取代交流接触器为电机供电。三相交流固态继电器的特点:光电隔离,单硅反并联输出,具有缺相保护功能,特别适用于频繁起动的工作方式。将限位的行程开关和脚踏开关内的触点开关改为接近开关。接近开关没有任何机械性能,具有寿命长、响应速度快等优点。同
[单片机]
如何以AT89C<font color='red'>51单片机</font>为核心设计一个剪板机的控制电路?
51单片机---串口通讯
一、简介 MCS-51单片机内部有一个可编程的双向全双工串行通信接口,简称串口;该串口有4种工作方式,以适用于不同场合;其波特率由单片机内部的定时器/计数器产生,可由软件设置;接收和发送均可工作在查询模式和中断模式,比较灵活; 二、串口结构与控制 MCS-51单片机内部的串口拥有两个物理上相互独立的接收、发送缓冲器SBUF,可以同时接收和发送数据;发送缓冲器只能写入而不能读出,接收缓冲器只能读出而不能写入;两个缓冲器占用同一个地址(99H);控制MCS-51单片机串口的寄存器有两个SCON和PCON; 1、串口工作方式控制寄存器SCON(99H) 如下图: (1)、SM0和SM1:控制单片机的工作方式; (2)、SM2:允许方式
[单片机]
<font color='red'>51单片机</font>---串口通讯
基于HX711+51单片机电子秤
仿真原理图如下 原理图 单片机源程序如下: #include reg52.h #include intrins.h #include string.h #include main.h #include LCD1602.h #include HX711.h #include eeprom52.h #define uchar unsigned char #define uint unsigned int unsigned long HX711_Buffer = 0; unsigned long Weight_Maopi = 0; unsigned long Weight_Maopi_0 = 0; long
[单片机]
基于HX711+<font color='red'>51单片机</font>电子秤
STC89C52之中断系统 ---- 51单片机的核心 自学笔记
一、中断系统 1.1、概念 cpu在处理某一事件A时,发生了另外一事件B请求cpu迅速去处理(中断发生); cup暂时中断当前的工作,转去处理事件B(中断响应和中断服务); 待cup将事件B处理完毕后,再回到原来事件A被中断的地方继续处理事件A(中断返回); 这一过程称为中断。 引起CPU中断的根源,称为中断源。中断源向CPU提出的中断请求。cup暂时中断原来的事务A,转去处理事件B。对事件B 处理完毕后,再回到原来被中断的地方(即:断点)称为中断返回,实现上述中断功能的部件称为中断系统。 1.2、中断系统的功能与优点 解决了快速主机与慢速i/o设备的数据传送问题。 分时操作:cpu可以为多个io设备服务,
[单片机]
STC89C52之<font color='red'>中断</font>系统 ---- <font color='red'>51单片机</font>的核心 自学笔记

推荐帖子

【MPS商城钜惠体验季】开箱+资料
上月通过朋友介绍参加了MPS商城的购物体验活动,感谢给与机会。首先MPS的箱子搞的还真是大,一点点元件都搞的好大个箱子,还以为买了好多元件。下面是大箱子,上面是小纸箱子收到的芯片是长这个样子下面的封装框图:原理图:【MPS商城钜惠体验季】开箱+资料开发板呢?就弄了两个芯片吗?
king86 LED专区
电力电子装置控制系统的DSP设计方案
作者:武汉大学王奇陈柏超来源:单片机及嵌入式系统应用摘要以TI公司的电机控制专用芯片TMS320LF2407aDSP为例,介绍电力电子装置中控制系统的硬件设计方案。包括DSP的电平转换、时钟、复位、译码、片外存储、键盘、液晶显示和E2PROM电路与必要的外围电路。关键词DSP硬件设计电力电子装置PCB引言在现代高性能电力电子和交流电机控制系统中,DSP已经取代了微控制器成为控制器的核心。其快速强大的运算和处理能力以及并行运行的能力,满足了电力电子装置控制
hellodsp DSP 与 ARM 处理器
【藏书阁】几何绕射理论
目录:第一章几何光学和几何绕射理论的基本概念1.1几何光学1.1.1各向同性不均匀媒质中的电磁场1.1.2高频的几何光学近似1.1.3几何光学的基本方程1.1.4几何光学的强度定律1.2均匀媒质中射线场的基本表示式1.3费马原理1.4几何绕射理论的基本概念1.5几何光学入射场和反射场1.5.l几何光学入射场1.5.2几何光学反射场1.6绕射射线场1.6.1边缘绕射射线场1.6.2表面统射射线场1.6.3尖顶绕射射线场l.7
wzt RF/无线
为DIY大赛加把油:LaunchPad超多代码分享
同事分享的:TITEMBOOTemboo支持7种编程语言,其平台相当于为程序员提供了一个基于云系统的图书馆,拥有超过2000个的代码和代码编排,供程序员直接取用。当你的App希望支持将文件同步到Dropbox,或支持用PayPal支付时,Temboo上都有相应的工具包,让曾经烦琐的写代码过程缩减到五行代码就能搞定,结果是程序员手边就能拿到各种软件包。如果某个在线服务商的API发生变动,Temboo也会相应在后台调整代码——这给程序员省了大把时间,而且解决了他们最头疼的API频繁更新问题
soso 微控制器 MCU
BLE4.0之CC2541串口应用从基础实验到协议栈
为什么要发个这个帖子呢?学习BLE4.0有一个月了吧,发这个帖子也是为了记录自己的学习过程相信大家都是学过其他系列的单片机,CC2541集51内核,肯定少不了51的影子,肯定要知道串口,在学习中,串口调试是必不可少的,它能打印出很多有用的信息出来。CC2541的串口引脚是:P0.2--------UART_RXP0.3--------UART_TX先说基础实验吧,上代码: voidInitUart(void) { P0SEL|=BV(2)|BV(3)
ywlzh 无线连接
为什么FREERTOS里好多例程编译通不过
请问高手,为什么为什么FREERTOS里好多例程编译通不过?谢谢为什么FREERTOS里好多例程编译通不过对开发环境有要求呗,甚至是版本,有的支持文件不同
chenbingjy 实时操作系统RTOS
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved