欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 192|回復: 0
打印 上一主題 下一主題
收起左側

基于51單片機的溫度設計 顯示錯誤

[復制鏈接]
跳轉到指定樓層
樓主
基于 51 單片機的簡易溫度控制系統:電路 + 功能全解析
最近搗鼓了個基于 51 單片機的溫度控制小項目,電路不復雜但功能挺實用,分享給大家~
一、電路核心組成
整個系統圍繞 51 單片機最小系統展開,搭配了這些模塊:
單片機最小系統:51 芯片 + 12MHz 晶振(X1)+ 復位電路(R3、C1),是系統的 “大腦”。
溫度檢測模塊:DS18B20 傳感器(U2),負責采集環境溫度。
顯示模塊:LCD1602 液晶屏幕,用來實時顯示溫度數值。
按鍵模塊:“遞增 / 遞減” 按鍵,可設置溫度閾值。
執行 & 指示模塊:
升溫裝置(比如加熱元件)+ 升溫指示燈(D2);
雙色指示燈(D1 紅 / 綠):用來提示溫度狀態(比如超閾值亮紅、正常亮綠)。
二、實際功能是啥?
這個小系統能實現 **“溫度采集 + 顯示 + 閾值控制”** 的閉環邏輯:
溫度采集:DS18B20 實時測溫度,把數據傳給單片機;
顯示:LCD1602 同步顯示當前溫度、設定的閾值;
閾值控制:通過 “遞增 / 遞減” 鍵設定目標溫度范圍;
狀態反饋:
當實際溫度低于閾值→觸發 “升溫” 裝置工作,同時 D2 亮燈提示;
溫度達到閾值→升溫裝置停止,雙色燈根據溫度狀態亮紅 / 綠燈。
比如你把它當簡易溫控器:設定 25℃為閾值,溫度低于 25℃時自動加熱,到 25℃就停,還能直觀看到溫度變化~
三、為啥說它實用?
電路成本低(都是常用元件)、邏輯清晰,適合單片機新手練手 —— 既練了傳感器通信(DS18B20 的單總線協議),又練了 LCD 顯示、按鍵交互、IO 口控制外設的基礎用法,稍微改改還能拓展成 “魚缸溫控”“小空間保溫” 這類實際場景的裝置~
要不要我幫你整理一份這個系統的核心代碼框架(包含溫度讀取、LCD 顯示、按鍵控制的基礎邏輯)?


需要
以下是基于 51 單片機的簡易溫度控制系統核心代碼框架,包含 DS18B20 溫度讀取、LCD1602 顯示、按鍵閾值設置、加熱邏輯控制 四大核心功能,代碼注釋詳細,新手可直接參考移植:
核心代碼框架(Keil C51 編寫)
c
運行
#include <reg52.h>
#include <intrins.h>

// ********** 引腳定義 **********
// LCD1602引腳
sbit LCD_RS = P2^0;  // 寄存器選擇引腳
sbit LCD_RW = P2^1;  // 讀寫控制引腳
sbit LCD_EN = P2^2;  // 使能引腳
#define LCD_DATA P0  // 數據端口

// DS18B20引腳(可自定義,此處用P3^7)
sbit DQ = P3^7;

// 按鍵引腳(遞增/遞減,此處用P3^2/P3^3,下拉電阻)
sbit KEY_ADD = P3^2;
sbit KEY_SUB = P3^3;

// 執行器引腳(加熱裝置+指示燈)
sbit HEATER = P1^0;  // 加熱元件控制(高電平工作)
sbit LED_HEAT = P1^1; // 加熱指示燈(高電平亮)
sbit LED_RED = P1^2;  // 溫度超閾值紅燈
sbit LED_GREEN = P1^3;// 溫度正常綠燈

// 全局變量
unsigned char temp_val;  // 實際溫度值(整數部分,單位℃)
unsigned char set_val = 25;  // 溫度閾值(默認25℃)
bit flag_temp_updata = 0;  // 溫度更新標志位

// ********** 延時函數(通用)**********
// 微秒級延時(參數:us,12MHz晶振)
void delay_us(unsigned int us) {
    while(us--) _nop_();
}

// 毫秒級延時(參數:ms,12MHz晶振)
void delay_ms(unsigned int ms) {
    unsigned int i, j;
    for(i = ms; i > 0; i--)
        for(j = 110; j > 0; j--);
}

// ********** LCD1602驅動函數 **********
// LCD寫命令函數
void LCD_WriteCmd(unsigned char cmd) {
    LCD_RS = 0;  // 命令模式
    LCD_RW = 0;  // 寫模式
    LCD_DATA = cmd;
    LCD_EN = 1;  // 高電平鎖存
    delay_us(10);
    LCD_EN = 0;  // 低電平完成
    delay_ms(2); // 命令執行延時
}

// LCD寫數據函數
void LCD_WriteData(unsigned char dat) {
    LCD_RS = 1;  // 數據模式
    LCD_RW = 0;  // 寫模式
    LCD_DATA = dat;
    LCD_EN = 1;
    delay_us(10);
    LCD_EN = 0;
    delay_ms(1);
}

// LCD初始化函數(1602標準初始化流程)
void LCD_Init() {
    delay_ms(15);  // 上電等待穩定
    LCD_WriteCmd(0x38);  // 8位數據接口,2行顯示,5*8點陣
    LCD_WriteCmd(0x0c);  // 開顯示,關光標
    LCD_WriteCmd(0x06);  // 光標自動右移,不滾屏
    LCD_WriteCmd(0x01);  // 清屏
}

// LCD顯示字符串(x:列0-15,y:行0-1,str:字符串指針)
void LCD_ShowStr(unsigned char x, unsigned char y, unsigned char *str) {
    if(y == 0) LCD_WriteCmd(0x80 + x);  // 第1行起始地址
    else LCD_WriteCmd(0xc0 + x);        // 第2行起始地址
    while(*str != '\0') {
        LCD_WriteData(*str);
        str++;
    }
}

// LCD顯示單個數字(x:列,y:行,num:0-9)
void LCD_ShowNum(unsigned char x, unsigned char y, unsigned char num) {
    if(y == 0) LCD_WriteCmd(0x80 + x);
    else LCD_WriteCmd(0xc0 + x);
    LCD_WriteData(num + '0');  // 數字轉ASCII碼
}

// ********** DS18B20溫度讀取函數 **********
// DS18B20復位(返回1:存在傳感器,0:不存在)
bit DS18B20_Reset() {
    bit ack;
    DQ = 0;  // 拉低總線480-960us
    delay_us(600);
    DQ = 1;  // 釋放總線
    delay_us(80);  // 等待傳感器響應
    ack = DQ;  // 傳感器拉低總線表示響應
    while(!DQ);  // 等待傳感器釋放總線
    return ~ack;  // 存在返回1,不存在返回0
}

// 寫1位數據到DS18B20
void DS18B20_WriteBit(bit bit_val) {
    DQ = 0;
    delay_us(2);  // 拉低至少1us
    DQ = bit_val; // 寫1保持高,寫0保持低
    delay_us(60); // 保持60us
    DQ = 1;       // 釋放總線
}

// 寫1字節數據到DS18B20
void DS18B20_WriteByte(unsigned char byte_val) {
    unsigned char i;
    for(i = 0; i < 8; i++) {
        DS18B20_WriteBit(byte_val & 0x01);  // 從最低位開始寫
        byte_val >>= 1;
    }
}

// 從DS18B20讀1位數據
bit DS18B20_ReadBit() {
    bit bit_val;
    DQ = 0;
    delay_us(2);  // 拉低1us
    DQ = 1;       // 釋放總線
    delay_us(1);  // 等待數據穩定
    bit_val = DQ; // 讀取數據
    delay_us(60); // 保持60us
    return bit_val;
}

// 從DS18B20讀1字節數據
unsigned char DS18B20_ReadByte() {
    unsigned char i, byte_val = 0;
    for(i = 0; i < 8; i++) {
        byte_val >>= 1;
        if(DS18B20_ReadBit()) byte_val |= 0x80;  // 從最低位開始讀
    }
    return byte_val;
}

// 讀取DS18B20溫度值(返回整數部分,精度0.5℃簡化)
void DS18B20_ReadTemp() {
    unsigned char temp_low, temp_high;
    if(DS18B20_Reset()) {  // 傳感器存在
        DS18B20_WriteByte(0xcc);  // 跳過ROM指令(單傳感器無需尋址)
        DS18B20_WriteByte(0x44);  // 啟動溫度轉換
        delay_ms(100);  // 等待轉換完成(DS18B20轉換時間約100ms)
        DS18B20_Reset();
        DS18B20_WriteByte(0xcc);
        DS18B20_WriteByte(0xbe);  // 讀取溫度寄存器
        temp_low = DS18B20_ReadByte();  // 溫度低8位
        temp_high = DS18B20_ReadByte(); // 溫度高8位

        // 計算整數溫度(忽略小數部分,簡化處理)
        temp_val = (temp_high << 4) | (temp_low >> 4);
        // 處理負溫度(此處簡化,若需支持負溫可補充邏輯)
        if(temp_high & 0x80) temp_val = -temp_val;

        flag_temp_updata = 1;  // 標記溫度已更新
    }
}

// ********** 按鍵處理函數(消抖+閾值調整)**********
void Key_Handle() {
    // 遞增按鍵(消抖處理)
    if(KEY_ADD == 0) {
        delay_ms(20);  // 消抖延時
        if(KEY_ADD == 0) {
            if(set_val < 50) set_val++;  // 閾值上限50℃(可自定義)
            while(!KEY_ADD);  // 等待按鍵松開
        }
    }

    // 遞減按鍵(消抖處理)
    if(KEY_SUB == 0) {
        delay_ms(20);
        if(KEY_SUB == 0) {
            if(set_val > 10) set_val--;  // 閾值下限10℃(可自定義)
            while(!KEY_SUB);
        }
    }
}

// ********** 溫控邏輯處理函數 **********
void Temp_Control() {
    if(flag_temp_updata) {  // 溫度已更新才執行邏輯
        flag_temp_updata = 0;

        // 溫度 < 閾值:啟動加熱
        if(temp_val < set_val) {
            HEATER = 1;    // 加熱元件工作
            LED_HEAT = 1;  // 加熱指示燈亮
            LED_RED = 0;   // 紅燈滅
            LED_GREEN = 0; // 綠燈滅
        }
        // 溫度 >= 閾值:停止加熱
        else {
            HEATER = 0;    // 加熱元件停止
            LED_HEAT = 0;  // 加熱指示燈滅
            // 溫度在閾值±1℃:綠燈(正常)
            if(temp_val <= set_val + 1) {
                LED_GREEN = 1;
                LED_RED = 0;
            }
            // 溫度超閾值+1℃:紅燈(過熱提示)
            else {
                LED_RED = 1;
                LED_GREEN = 0;
            }
        }
    }
}

// ********** LCD顯示更新函數 **********
void LCD_Updata() {
    // 第1行:顯示當前溫度 "Temp: XX ℃"
    LCD_ShowStr(0, 0, "Temp: ");
    LCD_ShowNum(6, 0, temp_val / 10);  // 十位
    LCD_ShowNum(7, 0, temp_val % 10);  // 個位
    LCD_ShowStr(9, 0, " ℃");

    // 第2行:顯示設定閾值 "Set: XX ℃"
    LCD_ShowStr(0, 1, "Set:  ");
    LCD_ShowNum(6, 1, set_val / 10);   // 十位
    LCD_ShowNum(7, 1, set_val % 10);   // 個位
    LCD_ShowStr(9, 1, " ℃");
}

// ********** 主函數(程序入口)**********
void main() {
    LCD_Init();  // 初始化LCD1602
    HEATER = 0;  // 初始關閉加熱
    LED_HEAT = 0;
    LED_RED = 0;
    LED_GREEN = 0;

    LCD_ShowStr(0, 0, "System Init...");
    delay_ms(1000);
    LCD_WriteCmd(0x01);  // 清屏

    while(1) {  // 死循環,持續運行
        DS18B20_ReadTemp();  // 讀取溫度(約100ms一次)
        Key_Handle();        // 按鍵檢測(閾值調整)
        Temp_Control();      // 溫控邏輯(加熱控制)
        LCD_Updata();        // 更新LCD顯示
        delay_ms(50);        // 循環延時,穩定系統
    }
}
代碼說明 & 使用注意事項
引腳適配:代碼中引腳定義(如 DS18B20、按鍵、執行器)需與你的硬件電路完全對應,否則功能異常(比如把DQ改到 P3^6,就需要同步修改sbit DQ = P3^6)。
精度擴展:當前代碼只取溫度整數部分,若需 0.5℃精度,可讀取temp_low的低 4 位(temp_low & 0x0f),判斷是否為 8(即 0.5℃),在 LCD 顯示時補充 “XX.5℃” 邏輯。
閾值范圍:代碼中閾值限制在 10-50℃,可通過修改Key_Handle()中的if(set_val < 50)和if(set_val > 10)調整。
硬件配合:
加熱元件建議用繼電器驅動(51 單片機 IO 口電流小,直接接大功率元件會燒芯片);
按鍵需接下拉電阻(10kΩ),避免電平抖動;
DS18B20 需外接 4.7kΩ 上拉電阻到 VCC,否則無法通信。
拓展方向
增加蜂鳴器報警:溫度超閾值(如 > 50℃)時觸發蜂鳴器;
增加掉電保存:用 EEPROM(如 AT24C02)存儲設定閾值,下次上電自動加載;
提升精度:支持小數溫度顯示(如 18.5℃);
遠程監控:通過串口將溫度數據上傳到電腦(需添加串口通信代碼)。
如果需要針對你的硬件電路調整引腳、補充某部分功能(如負溫處理、蜂鳴器報警),可以告訴我具體需求,我會進一步優化代碼~

{}QKDEG){C2XYN2O~P744HK.png (51.26 KB, 下載次數: 0)

{}QKDEG){C2XYN2O~P744HK.png

單片機水溫控制系統(全套設計資料).7z

577.95 KB, 下載次數: 0

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表