51 MCU uses timer interrupt method to realize DS18B20 timing

Publisher:boczsy2018Latest update time:2022-04-21 Source: eefocus Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

Since DS18B20 is a single-line operation, its timing requirements must be strictly followed in order to establish normal communication with it and implement read and write operations.


Most of the programs found on the Internet are implemented in a delayed manner in the main program, and require interrupts to be turned off to meet the timing requirements of 18B20. However, in actual applications, temperature measurement operations are generally used as auxiliary functions, and the main tasks are other operations such as communication and data processing. In this way, if the DS18B20 program code is placed in the main program, it will inevitably affect other interrupts that need to be processed in real time.


A few days ago, I used DS18B20, and tried to implement the DS18B20 timing with the 51 timer interrupt method, and it ran successfully on the breadboard.


The microcontroller used is STC11F16XE, and an external crystal oscillator of 24MHz is used. The following program not only includes the operation of DS18B20, but also includes the operation of digital tube display, key detection, and EEPROM. Timer T1 is specifically used for DS18B20 timing generation, timer T0 is used for key detection and digital tube display, and EEPROM and other operations are performed in the main function. Some comments in the program are added during debugging, and some code parts have been modified during debugging. The previous comments were not deleted at the same time, so when looking at the following code, don't be misled by the comments.


code show as below:


#include "REG51.H"

#include "INTRINS.H"



typedef unsigned char BYTE;

typedef unsigned int WORD;



sfr P1M0 = 0x92; //                                                                      

sfrP1M1 = 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;

SWITCH kflag; //

bit adjust;

bit updateEEP;



unsigned int heat_t;



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

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

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

BITE that;



void main()

{

  updateEEP = 0;

num = 0;

temp = 0;

words = 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 has high priority


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; //The timing time is 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;


//show

word++;

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)

{

it = 0;

ge = 0;

P1 = digit[10];

}

else

switch(saom)

{

case 0 :

it = 0;

ge = 1;

P1 = digit[temp/10];

break;

case 1 :

it = 1;

ge = 0;

P1 = digit[temp%10];

break;

case 2 :

it = 1;

ge = 1;

if(num < 80) P1 = led;

else P1 = 0x80;

break;

default : break;

}

/*

//Heating timing

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

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

{heat_t++;}

else {heat_t = 0; heat = 0;}

*/



//Collect 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: //Write byte first bit

case 49 :

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

else

{

that = 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_(); //Restore data line, restore time

 DQ = 0; _nop_(); _nop_(); //Start the next bit

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

case 24 :

case 57 :

DQ = 1; _nop_(); _nop_(); //Write the first byte to end

dat = cmd[cmd_n++]; //fill dat

DQ = 0; _nop_(); _nop_(); //Write the second byte

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

case 32 :

DQ = 1; _nop_(); _nop_(); //Write the second byte and end 0x44

_nop_(); _nop_();

case 65 :

DQ = 1; _nop_(); _nop_(); //0xbe command sent

dat = 0; //Read TPL

that >>= 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 :

that >>= 1;

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

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

if(DQ) dat |= 0x80;

break;

case 73 :

TPL = that;

 dat = 0; //Read TPH

that >>= 1;

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

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

if(DQ) dat |= 0x80;

break;

case 81 :

TPH = that;

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();

}

Reference address:51 MCU uses timer interrupt method to realize DS18B20 timing

Previous article:MCU_LCD12864 displays self-made pictures (clock as an example)
Next article:Design of elevator (four-story) control system based on single chip microcomputer

Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号