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

 找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 192|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

基于51單片機(jī)的溫度設(shè)計(jì) 顯示錯(cuò)誤

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:578150 發(fā)表于 2025-11-25 10:18 | 只看該作者 |只看大圖 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
基于 51 單片機(jī)的簡(jiǎn)易溫度控制系統(tǒng):電路 + 功能全解析
最近搗鼓了個(gè)基于 51 單片機(jī)的溫度控制小項(xiàng)目,電路不復(fù)雜但功能挺實(shí)用,分享給大家~
一、電路核心組成
整個(gè)系統(tǒng)圍繞 51 單片機(jī)最小系統(tǒng)展開(kāi),搭配了這些模塊:
單片機(jī)最小系統(tǒng):51 芯片 + 12MHz 晶振(X1)+ 復(fù)位電路(R3、C1),是系統(tǒng)的 “大腦”。
溫度檢測(cè)模塊:DS18B20 傳感器(U2),負(fù)責(zé)采集環(huán)境溫度。
顯示模塊:LCD1602 液晶屏幕,用來(lái)實(shí)時(shí)顯示溫度數(shù)值。
按鍵模塊:“遞增 / 遞減” 按鍵,可設(shè)置溫度閾值。
執(zhí)行 & 指示模塊:
升溫裝置(比如加熱元件)+ 升溫指示燈(D2);
雙色指示燈(D1 紅 / 綠):用來(lái)提示溫度狀態(tài)(比如超閾值亮紅、正常亮綠)。
二、實(shí)際功能是啥?
這個(gè)小系統(tǒng)能實(shí)現(xiàn) **“溫度采集 + 顯示 + 閾值控制”** 的閉環(huán)邏輯:
溫度采集:DS18B20 實(shí)時(shí)測(cè)溫度,把數(shù)據(jù)傳給單片機(jī);
顯示:LCD1602 同步顯示當(dāng)前溫度、設(shè)定的閾值;
閾值控制:通過(guò) “遞增 / 遞減” 鍵設(shè)定目標(biāo)溫度范圍;
狀態(tài)反饋:
當(dāng)實(shí)際溫度低于閾值→觸發(fā) “升溫” 裝置工作,同時(shí) D2 亮燈提示;
溫度達(dá)到閾值→升溫裝置停止,雙色燈根據(jù)溫度狀態(tài)亮紅 / 綠燈。
比如你把它當(dāng)簡(jiǎn)易溫控器:設(shè)定 25℃為閾值,溫度低于 25℃時(shí)自動(dòng)加熱,到 25℃就停,還能直觀看到溫度變化~
三、為啥說(shuō)它實(shí)用?
電路成本低(都是常用元件)、邏輯清晰,適合單片機(jī)新手練手 —— 既練了傳感器通信(DS18B20 的單總線協(xié)議),又練了 LCD 顯示、按鍵交互、IO 口控制外設(shè)的基礎(chǔ)用法,稍微改改還能拓展成 “魚(yú)缸溫控”“小空間保溫” 這類實(shí)際場(chǎng)景的裝置~
要不要我?guī)湍阏硪环葸@個(gè)系統(tǒng)的核心代碼框架(包含溫度讀取、LCD 顯示、按鍵控制的基礎(chǔ)邏輯)?


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

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

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

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

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

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

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

// 毫秒級(jí)延時(shí)(參數(shù):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驅(qū)動(dòng)函數(shù) **********
// LCD寫(xiě)命令函數(shù)
void LCD_WriteCmd(unsigned char cmd) {
    LCD_RS = 0;  // 命令模式
    LCD_RW = 0;  // 寫(xiě)模式
    LCD_DATA = cmd;
    LCD_EN = 1;  // 高電平鎖存
    delay_us(10);
    LCD_EN = 0;  // 低電平完成
    delay_ms(2); // 命令執(zhí)行延時(shí)
}

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

// LCD初始化函數(shù)(1602標(biāo)準(zhǔn)初始化流程)
void LCD_Init() {
    delay_ms(15);  // 上電等待穩(wěn)定
    LCD_WriteCmd(0x38);  // 8位數(shù)據(jù)接口,2行顯示,5*8點(diǎn)陣
    LCD_WriteCmd(0x0c);  // 開(kāi)顯示,關(guān)光標(biāo)
    LCD_WriteCmd(0x06);  // 光標(biāo)自動(dòng)右移,不滾屏
    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顯示單個(gè)數(shù)字(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');  // 數(shù)字轉(zhuǎn)ASCII碼
}

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

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

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

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

// 從DS18B20讀1字節(jié)數(shù)據(jù)
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;  // 從最低位開(kāi)始讀
    }
    return byte_val;
}

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

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

        flag_temp_updata = 1;  // 標(biāo)記溫度已更新
    }
}

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

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

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

        // 溫度 < 閾值:?jiǎn)?dòng)加熱
        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℃:紅燈(過(guò)熱提示)
            else {
                LED_RED = 1;
                LED_GREEN = 0;
            }
        }
    }
}

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

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

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

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

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

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

{}QKDEG){C2XYN2O~P744HK.png

單片機(jī)水溫控制系統(tǒng)(全套設(shè)計(jì)資料).7z

577.95 KB, 下載次數(shù): 0

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

使用道具 舉報(bào)

本版積分規(guī)則

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

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表