Use 51 single chip to measure temperature (DS18B20) and frequency (external interrupt measurement) at the same time

Publisher:橙子1234Latest update time:2020-02-10 Source: 51hei Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

void main()//main function
{           
    delay1ms(1000);     
        lcd_init();//LCD display initialization
        init_play(); 

while(1)
{        
     EA=0; //Since DS18B20 has high timing requirements and is affected by interrupts, turn off the general interrupt first
     read_temp();//Read temperature
     ds1820disp();//Display
     CT_init();//Timer counter initialization     
     EA=1;//Open general interrupt 
         EX0=1;//Allow external interrupt
         IT0=1;//Set external interrupt mode to falling edge trigger
         P3=0xff;                                                        
         t0=(u*65536+x)*(12/22.1);//Calculate pulse time width (unit: ms)
         f=1000000/(2*t0);//Calculate frequency                        
         if(f>8000&&tflag==1)          
          init_play1(); //Display Frozen
   else init_play2(); //Display Not frozen
}
}
This is the main function. I initially suspect that the interruption of measuring frequency affects the reading of data by the temperature sensor. How to solve it?
Method 1: If the real-time requirement of reading frequency is not high, just turn this on and off, take turns, and there is no other trick.
First measure the temperature for 1 second, then measure the frequency for 1 second, and then measure the temperature for 1 second?
Method 2: I will give you a reference program, which is also single-bus data acquisition (clock 11.0592).
Do not turn off interrupts in your main loop. When calling to read temperature, there is a checksum to determine the validity of the data (if there is an interrupt in the middle of the temperature reading program, the data may be invalid).
#include
#include "public.h"

sbit DS2401Bus = P3^5;

//DS2401.c
// First reset the single bus:
// The bus remains low for more than 480us; all devices on the bus will reset
// The master releases the bus and enters receive mode
// The slave waits for 15-60us, then pulls the bus low for 60-240us to generate a response pulse
// Write 0x33H command: Only suitable for single node (read ROM[0x33] command)
// All write (0 or 1) time slots require at least 60us and at least 1us recovery time is required between two independent write time slots
// Both write time slots start with the master pulling the bus low
// Write 1 time slot: After pulling the bus low, the master must release the bus within 15us, and the bus is pulled to a high level by a 5k pull-up resistor
// Write 0 time slot: After pulling the bus low, the master only needs to keep the low level for at least 60us during the entire time slot
// -- During the period of 15-60us after the start of the write time slot, the single-bus device samples the bus level state (0 or 1)
// Read time slot
// The device transmits data to the host only when the host issues a read time slot. So after the host issues a read data command, a read time slot must be generated immediately
. // All read time slots require at least 60us and at least 1us of recovery time is required between two independent read time slots.
// Each read time slot is initiated by the host, which pulls the bus down for at least 1us.
// The single-bus device starts sending 0 or 1 on the bus only
after the host initiates a read time slot. // The data sent by the slave remains valid for 15us after the start time slot.
// Therefore, the host must release the bus during the read time slot and sample the bus status within 15us after the start of the time slot.
//
#pragma ot(4,SPEED)

void delay_500us(void)   
{   
    unsigned char data i;          
    for(i = 0; i < 56; i++);   
}    
void delay_250us(void)   
{   
    unsigned char data i;          
    for(i = 0; i < 28; i++);   
}    
void delay_90us(void)   
{   
    unsigned char data i;          
    for(i = 0; i < 9; i++) ;   
}    
void delay_60us(void)   
{   
    unsigned char data i;          
    for(i = 0; i < 6; i++) ;   
}    

unsigned char InitDS2401(void) //Reset DS2401
{
        unsigned char tmp;
        DS2401Bus = 0; // Output: 0; the bus remains at a low level for more than 480us
        delay_500us(); // 498us
        DS2401Bus = 1; // Release the bus, and the 5k pull-up resistor pulls the bus to a high level
        delay_60us(); // 64us, wait for the device to send a response pulse
        tmp = DS2401Bus; // Check the response pulse
        delay_250us(); // 255us, delay more than 240us
        if(tmp) // Read data
                return 0;
        else
                return 1;
}

void WriteDS2401(unsigned char d)//Write 2401 command
{
        unsigned char i;
        for(i=0;i<8;i++) {
                DS2401Bus = 0; // After pulling the bus low, the host must release the bus within 15us_nop_
                (); _nop_(); _nop_(); // Each nop is estimated to take 1.085us
                if(d & 1) { // Output: data bit
                        DS2401Bus = 1;
                }
                d >>= 1;
                delay_60us(); // At least keep 60us
                DS2401Bus = 1; // Pull the bus to a high level, at least 1us recovery time is required_nop
                _();_nop_();_nop_();                  
        }
}

unsigned char ReadDS2401() //Read 2401 data
{
        unsigned char i,d;
        for(i=0;i<8;i++) {
                d >>= 1;
                DS2401Bus = 0; // At least pull the bus low for 1us
                _nop_();_nop_();_nop_();             
                DS2401Bus = 1; // Release bus_nop
                _();_nop_();_nop_();_nop_();_nop_();
                if(DS2401Bus == 1) d |= 0x80; // Read data
                delay_90us(); // 90us
        }
        return d;
}

unsigned char crctest() //Perform CRC check
{
        unsigned char i1, i2, crc=0;
        for(i1=0; i1<8; i1++) {
                crc ^= DS2401IDBuf[i1];
                for(i2=0; i2<8; i2++) {
                        if (crc & 0x01) 
                                crc = (crc >> 1) ^ 0x8C;
                        else
                                crc >>= 1;
                }
        }
        return (crc);
}

unsigned char ReadRS2401ID() //Read out DS2401's
{
        unsigned char i;
        if (!InitDS2401()) return(0);
        WriteDS2401(0x33);
        for(i=0;i<8;i++) DS2401IDBuf[i]=ReadDS2401();
        if (crctest() != 0) return(0);
        return(1); //CRC check successful
}

Reference address:Use 51 single chip to measure temperature (DS18B20) and frequency (external interrupt measurement) at the same time

Previous article:51 MCU Smart Home Remote Control
Next article:51 MCU + K9F2080U0A to make MP3 circuit diagram and source program

Recommended ReadingLatest update time:2024-11-16 11:51

51 single chip microcomputer controls eight DS18B20 temperature sensors to display
  The microcontroller source program is as follows: #include reg51.h #include Intrins.h #define DATA P1 //1602 driver port //ROM operation command #define READ_ROM 0x33 //Read ROM  #define SKIP_ROM 0xCC //Skip ROM  #define MATCH_ROM 0x55 //Match ROM  #define SEARCH_ROM 0xF0 //Search ROM  #define ALARM_SEARCH 0
[Microcontroller]
51 single chip microcomputer controls eight DS18B20 temperature sensors to display
51 single chip microcomputer - temperature sensor DS18B20
Temperature sensor is the most commonly used one among various sensors. In the early days, analog temperature sensors, such as thermistors, were used. As the ambient temperature changes, its resistance also changes linearly. The voltage across the resistor is collected by the processor, and then the current ambient tem
[Microcontroller]
51 single chip microcomputer - temperature sensor DS18B20
MSP430 and DS18B20 Driver
**File name: ds18b20.c   **Description: Use the single bus DS18B20 temperature measurement program and display it on the LCD, taking three effective decimal places. Two integer parts. A total of 5 digits are displayed    #include  MSP430x44x.h   #define SEGE 0X80  #define SEGH 0X40  #define SEGF 0X20  #define SEGC 0X1
[Microcontroller]
Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
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号