使用 8051 的高温警报

问题描述 投票:0回答:1

This is a screenshot from proteus 8

//Code for HIGH TEMPERATURE ALERT SYSTEM using 8051

#include<reg51.h> // Includes 8051 microcontroller definitions

// Function declarations
void delay(unsigned int i); // Generates a delay for LCD enable pulse
void lcd_cmd(unsigned char a); // Sends a command to the LCD
void lcd_data(unsigned char b); // Sends data (characters) to the LCD
void lcd_init(void); // Initializes the LCD
void lcd_str(unsigned char *str); // Displays a string on the LCD
void hex2ascii(unsigned char value); // Converts hex value to ASCII for display

// Pin and port definitions
sbit rs = P2^0; // Register select pin for LCD
sbit en = P2^1; // Enable pin for LCD
sfr ldata = 0xb0; // Data port for LCD (Port 3)
sbit rd = P2^2; // Read pin for ADC
sbit wr = P2^3; // Write pin for ADC
sbit intr = P2^4; // Interrupt pin from ADC
sfr adc = 0x90; // ADC data from Port 1
sbit buz = P2^5; // Buzzer control pin

// Main function
void main ()
{
    // LCD welcome message
    lcd_init(); // Initialize LCD
    buz = 0; // Ensure the buzzer is off at the start
    lcd_str("    WELCOME    "); // Display first line of welcome message
    lcd_cmd(0xc0); // Move to the second line
    lcd_str("   TO PROJECT   "); // Display second line of welcome message
    delay(65000); // Delay for display
    lcd_cmd(0x01); // Clear the display
    
    // Display project title
    lcd_cmd(0x81); // Position the cursor
    lcd_str("  TEMPERATURE  "); // Display project title
    lcd_cmd(0xc2); // Move to the second line
    lcd_str("   ALERT   "); // Display 'ALERT' text
    delay(65000); // Delay for display
    lcd_cmd(0x01); // Clear display
    
    // Display temperature label
    lcd_cmd(0x80); // Move cursor to first line, start position
    lcd_str("  Temp ="); // Display 'Temp =' text
    lcd_cmd(0x8b); // Move cursor to show temperature in degrees
    lcd_data((char)223); // Display degree symbol
    lcd_str("C"); // Display 'C' for Celsius

    // Infinite loop to continuously monitor temperature
    while(1)
    {   
        // ADC conversion process
        rd = 1; // Set read high
        wr = 0; // Start conversion by setting write low
        delay(100); // Wait for conversion
        wr = 1; // Set write high
        while(intr == 1); // Wait until conversion finishes (interrupt flag low)
        delay(100); // Small delay
        rd = 0; // Set read low to fetch ADC result

        // Display temperature value
        lcd_cmd(0x89); // Set cursor position to display temperature value
        hex2ascii(adc*2); // Convert ADC value to ASCII and display
        
        // High-temperature alert condition
        if(adc*2 > 0x1d) // Check if temperature exceeds threshold (29°C)
        {
            // Display alert message and activate buzzer
            lcd_cmd(0xC0); // Move cursor to second line
            lcd_str("HIGH TEMP ALERT!"); // Display high temp alert message
            buz = 1; // Turn buzzer on
        }
        else
        {
            // Clear alert message and turn off buzzer
            lcd_cmd(0xC0); // Move cursor to second line
            lcd_str("                "); // Clear the alert message
            buz = 0; // Turn buzzer off
        }
        intr = 1; // Ready for next ADC conversion
    }
}

// Function to convert hex value to ASCII and display on LCD
void hex2ascii(unsigned char value) 
{
    unsigned char x, d1, d2, d3;
    x = value / 10; // Extract tens digit
    d3 = value % 10; // Extract ones digit
    d2 = x % 10; // Extract tens digit
    d1 = x / 10; // Extract hundreds digit
    //lcd_data(d1 + 0x30); // Display hundreds digit (ASCII)
    lcd_data(d2 + 0x30); // Display tens digit (ASCII)
    lcd_data(d3 + 0x30); // Display ones digit (ASCII)
}

// LCD initialization function
void lcd_init()
{
    lcd_cmd(0x38); // Initialize LCD for 8-bit mode
    lcd_cmd(0x0c); // Display on, cursor off
    lcd_cmd(0x01); // Clear display
    lcd_cmd(0x80); // Set cursor to beginning of first line
}

// Delay function
void delay(unsigned int i)
{
    unsigned int j;
    for(j = 0; j < i; j++); // Simple loop for delay
}

// Function to send command to LCD
void lcd_cmd(unsigned char a)
{
    rs = 0; // Set for command mode
    ldata = a; // Load command to data port
    en = 1; // Enable LCD
    delay(5); // Small delay
    en = 0; // Disable LCD
    delay(5); // Small delay
}

// Function to send data (characters) to LCD
void lcd_data(unsigned char b)
{
    rs = 1; // Set for data mode
    ldata = b; // Load data to data port
    en = 1; // Enable LCD
    delay(5); // Small delay
    en = 0; // Disable LCD
    delay(5); // Small delay
}

// Function to display string on LCD
void lcd_str(unsigned char *str)
{
    while(*str) // Loop until the end of the string
    {
        lcd_data(*str++); // Send each character to the LCD
    }
}

我尝试调整代码中使用的公式来显示连接到 LM35 温度传感器的 ADC 的温度值。最初,我将 ADC 值乘以 2,但这仅显示偶数温度。

我的期望: 当传感器读取温度时,我期望温度显示屏显示偶数和奇数。当传感器检测到变化时,我预计温度值(例如 29°C、30°C、31°C)会平稳变化,不会出现跳过或舍入错误。

embedded microcontroller sensors temperature 8051
1个回答
0
投票

乍一看,您似乎在问“为什么”您只有偶数值。正如我们所评论的,这是因为您将 ADC 的结果乘以二。 不能得到二的倍数的奇数结果。

经过更深入且耗时的调查(您可以通过在问题中预先添加此信息来拯救我们),可以理解为什么您乘以二:

LM35 每 °C 产生 10mV。由于它是模拟设备,因此它(实际上)还输出两者之间的任何值,与温度成比例。
  1. ADC 在其约 5V 的全范围内有 256 个步长,每步仅提供约 20mV。
  2. 因此 ADC 的未修改结果为 1 步 = 20mV = 2°C。
  3. 这导致了两倍的“修正”。
  4. 不幸的是,您的问题的历史记录造成了这种情况,其中剩余的问题在这里,并且在
SE/EE

上的双重发布版本被删除,即使该网站更适合。所以我觉得无论如何你都应该得到一个答案,即使它就在这里。请下次在提问时多加一些努力,以避免出现这种混乱。

您真正的问题是,“
如何以能够区分单个°C的方式测量电压?

解决方案一:降低参考电压

由于您的 ADC 无法扩展其数字范围,因此您可以降低参考电压。请参阅 ADC 数据表以了解更多信息。

要让 ADC 输出类似于温度(°C)的数字值,您需要 2.56V 的参考电压。引脚“V

REF

/2”需要由该值的一半驱动,即1.28V。 为了进行快速实验,您可以使用普通(不是超亮)红色 LED,其正向电压约为 1.2V。结果不会很好,但是你会看到效果的。

对于真正的解决方案,您需要更准确的参考。有专门的组件用于此,您需要进行自己的研究。

解决方案2:放大输入电压

作为替代方案,您可以将 LM35 的电压放大两倍。

使用运算放大器。由于信号实际上是直流信号,因此您不需要昂贵的高速设备。使用任何通用部分。

如何构建电路留作练习,它显然超出了 StackOverflow 的范围。

最后注意事项

不要忘记从代码中删除二乘法。

© www.soinside.com 2019 - 2024. All rights reserved.