標(biāo)題: STC單片機(jī)程序問(wèn)題請(qǐng)教 功能類(lèi)似電蚊香加熱器 [打印本頁(yè)]

作者: mcuhui    時(shí)間: 2023-8-28 13:39
標(biāo)題: STC單片機(jī)程序問(wèn)題請(qǐng)教 功能類(lèi)似電蚊香加熱器
各位大神,現(xiàn)在從某開(kāi)源平臺(tái)找了一個(gè)開(kāi)源案例DIY,功能類(lèi)似電蚊香加熱器。
現(xiàn)在問(wèn)題是:這個(gè)產(chǎn)品一上電就會(huì)自動(dòng)開(kāi)啟加熱,我想改成手動(dòng)開(kāi)啟加熱,目前沒(méi)有找到從程序哪個(gè)地方更改。
懇請(qǐng)大神幫忙看看。以下是源碼
單片機(jī)源程序如下:
#include <STC8G.H>
#include <eeprom.h>
#include <ntc.h>

#define uint8_t unsigned char
#define uint16_t unsigned int
#define uint32_t unsigned long
#define int8_t char
#define int16_t int
#define int32_t int long

sbit KEY=P3^2;
sbit NTC=P3^3;
sbit LED=P5^4;
sbit PWM=P5^5;

uint8_t idata run_mode = 0;

void Timer0_Init(void)                //1毫秒@12.000MHz
{
        AUXR &= 0x7F;                        //定時(shí)器時(shí)鐘12T模式
        TMOD &= 0xF0;                        //設(shè)置定時(shí)器模式
        TL0 = 0x18;                                //設(shè)置定時(shí)初始值
        TH0 = 0xFC;                                //設(shè)置定時(shí)初始值
        TF0 = 0;                                //清除TF0標(biāo)志
        TR0 = 1;                                //定時(shí)器0開(kāi)始計(jì)時(shí)
        ET0 = 1;                                //使能定時(shí)器0中斷
}

void Timer1_Init(void)        //僅記錄時(shí)間用于測(cè)溫
{
        AUXR &= 0xBF;                //定時(shí)器時(shí)鐘12T模式
        TMOD &= 0x0F;                //設(shè)置定時(shí)器模式
        TMOD |= 0x10;                //設(shè)置定時(shí)器模式
        TL1 = 0;                        //設(shè)置定時(shí)初始值
        TH1 = 0;                        //設(shè)置定時(shí)初始值
        TF1 = 0;                        //清除TF1標(biāo)志
        ET1 = 1;                        //使能定時(shí)器0中斷
}

void Int1_Init()
{
    IT1 = 1;                        //使能INT1下降沿中斷
    EX1 = 1;                        //使能INT1中斷
}

void GPIO_init()
{
        P3M1 = 0xFB;        //按鍵準(zhǔn)雙向
        
        P5M1 = 0xDF;        //LED開(kāi)漏
        P5M0 = 0x30;        //PWM推挽
}

static uint16_t save_tick = 0;        //安全計(jì)時(shí)
void pwm_scan()
{
        static uint8_t i = 0;
        static uint8_t duty_cycle = 10;
        uint8_t ntc_temp;
        
        i++;
        if(i >= 200)//200分頻,當(dāng)100分頻時(shí)部分充電寶因負(fù)載脈寬過(guò)小而休眠
                i = 0;
        
        if(run_mode != 1)//非運(yùn)行狀態(tài)
        {
                if(PWM == 0)
                {
                        PWM = 1;        //關(guān)機(jī)
                        TR1 = 1;        //定時(shí)器1開(kāi)始計(jì)時(shí)
                }
                NTC_reset();
                return;
        }
        
        if(duty_cycle < 10)                        //最小占空比為5%
                duty_cycle = 10;
        if(duty_cycle > 190)                //最大占空比為95%
                duty_cycle = 190;
        
        if(i == 0)//啟動(dòng)
        {
                PWM = 0;
        }
        else if(i == 1)//開(kāi)始1ms開(kāi)始分段運(yùn)行
        {
                ntc_temp = NTC_get_temp();
                if(ntc_temp < 10)
                        run_mode = 2;
                else if(ntc_temp < 85)
                        duty_cycle = 190;
                else if(ntc_temp < 95)
                        duty_cycle = 160;
                else if(ntc_temp < 105)
                        duty_cycle = 130;
                else if(ntc_temp < 120)
                {
                        duty_cycle = 50;
                        save_tick = 0;
                }
                else                                //大于120度,異常狀況
                {
                        save_tick = 0;
                        run_mode = 2;
                }
                save_tick++;
                if(save_tick > 900)//持續(xù)3分鐘達(dá)不到目標(biāo)溫度,異常狀況
                {
                        save_tick = 0;
                        run_mode = 2;
                }
        }
        else if(i == duty_cycle)
        {
                if(PWM == 0)
                {
                        PWM = 1;        //關(guān)機(jī)
                        TR1 = 1;        //定時(shí)器1開(kāi)始計(jì)時(shí)
                }
        }
}

uint8_t get_key_state()
{
        static uint16_t idata event_tick=0;
        static uint16_t idata sw_num=0;
        uint8_t out_temp=0;
        
        if(KEY==0)        //如果IO被拉低
        {
                sw_num++;
                if(sw_num==5)
                {
                        event_tick/=1000;
                        event_tick++;
                        event_tick*=1000;//保留千位
                        return 0xFE;        //按下事件
                }
        }
        else
        {
                if(sw_num>=5)
                {
                        sw_num=0;
                        return 0xFF;        //松開(kāi)事件
                }
                sw_num=0;
        }
        
        if(event_tick)                        //連擊事件處理
        {
                event_tick++;
                if(event_tick%1000==500)
                {
                        if(sw_num==0)        //松開(kāi)時(shí)才會(huì)觸發(fā)連擊事件
                                out_temp=event_tick/1000;
                        event_tick=0;
                }
        }
        return out_temp;
}


uint8_t idata ms_tick=0;
void whit_ms()
{
        static uint8_t idata tick=0;
        
        while(tick == ms_tick)
                PCON |= 1;        //sleep
        tick++;
        
        pwm_scan();
}

void main()
{
        uint16_t idata sec_div1000 = 0;
        uint16_t idata sec_countdown = 0;
        uint8_t key_temp;
        
        GPIO_init();
        Timer0_Init();
        Timer1_Init();
        Int1_Init();
        
        EA=1;
        while(1)
        {
                whit_ms();
                key_temp = get_key_state();
                switch(key_temp)
                {
                        case 1:
                                if(run_mode)        //正在運(yùn)行,則關(guān)機(jī)
                                {
                                        sec_countdown = 0;
                                        run_mode = 0;
                                }
                                else                        //讀取歷史記錄
                                {
                                        sec_countdown = (get_new_data() + 2) * (2 * 60 *60);//對(duì)應(yīng)4~12小時(shí),還有一直運(yùn)行
                                        run_mode = 1;
                                        save_tick = 0;
                                }
                                break;
                        case 2:
                        case 3:
                        case 4:
                        case 5:
                        case 6:
                        case 7:
                                save_new_data(key_temp - 2);        //保存數(shù)據(jù)
                        
                                sec_countdown = key_temp * (2 * 60 *60);//對(duì)應(yīng)4~12小時(shí),還有一直運(yùn)行
                                run_mode = 1;
                                break;
                }
               
                sec_div1000++;
                if(sec_div1000>=1000)//每秒執(zhí)行一次
                {
                        sec_div1000=0;
                        if(sec_countdown > 0 && sec_countdown < 50000)//0~13小時(shí)內(nèi)則倒計(jì)時(shí)
                        {
                                sec_countdown--;
                                if(sec_countdown == 0)//倒計(jì)時(shí)結(jié)束
                                {
                                        run_mode = 0;
                                }
                        }
                }
                switch(run_mode)
                {
                        case 0:        //停止關(guān)燈
                                LED = 1;
                                break;
                        case 1:        //運(yùn)行常亮
                                LED = 0;
                                break;
                        case 2:        //錯(cuò)誤閃爍
                                LED = sec_div1000 > 500 ? 1: 0;
                                break;
                }
        }
}

void Timer0_Isr() interrupt 1
{
        ms_tick++;
}

void INT1_Isr() interrupt 2
{
        TR1 = 0;        //定時(shí)器1停止計(jì)時(shí)
        
    NTC_updata((TH1 << 8) | TL1);
        
        TL1 = 0;
        TH1 = 0;        //清零時(shí)間計(jì)數(shù)
}

void Timer1_Isr() interrupt 3
{
        TF1 = 0;                //清除TF1標(biāo)志
        TR1 = 0;                //定時(shí)器1停止計(jì)時(shí)
        run_mode = 2;        //正常測(cè)溫不會(huì)進(jìn)入T1中斷
}


作者: liucan2020    時(shí)間: 2023-8-28 16:02
有原理圖才好分析,我看PWM=1時(shí) 是關(guān)機(jī),你在GPIO初始化的時(shí)候 賦值一下。
作者: hb_lhw    時(shí)間: 2023-8-28 16:35

是立創(chuàng)開(kāi)源廣場(chǎng)里的STC電熱蚊香加熱器嗎?

作者: hb_lhw    時(shí)間: 2023-8-28 16:38
貌似按了一次開(kāi)關(guān)后,才能工作。
作者: yzwzfyz    時(shí)間: 2023-8-28 16:48
1、找到加熱的接口(IO)。
2、做一個(gè)控制輸出的標(biāo)記KZ。
3、當(dāng)KZ=1時(shí),讓IO口恒定輸出為關(guān)邏輯。當(dāng)KZ=0時(shí),讓IO口為原定的輸出,即加熱。
4、做一個(gè)選擇鍵,根據(jù)健入狀態(tài),決定KZ值。


作者: IdeaMing    時(shí)間: 2023-8-28 17:48
程序如果上電是運(yùn)行,按一下按鍵是關(guān)閉的話(huà),你可以把輸出腳做個(gè)電平取反電路。
作者: mcuhui    時(shí)間: 2023-8-29 08:40
liucan2020 發(fā)表于 2023-8-28 16:02
有原理圖才好分析,我看PWM=1時(shí) 是關(guān)機(jī),你在GPIO初始化的時(shí)候 賦值一下。

是的,用的是PMOS,PWM=1才是關(guān)機(jī)。
作者: mcuhui    時(shí)間: 2023-8-29 08:41
hb_lhw 發(fā)表于 2023-8-28 16:35
是立創(chuàng)開(kāi)源廣場(chǎng)里的STC電熱蚊香加熱器嗎?

是的,就是這個(gè)。V1.0版本應(yīng)該是需要開(kāi)關(guān)開(kāi)啟才工作的�?墒俏覍�(xiě)進(jìn)去之后一上電就開(kāi)啟加熱了
作者: mcuhui    時(shí)間: 2023-8-29 08:41
hb_lhw 發(fā)表于 2023-8-28 16:38
貌似按了一次開(kāi)關(guān)后,才能工作。

實(shí)際卻是一上電就開(kāi)啟加熱了
作者: mcuhui    時(shí)間: 2023-8-29 08:42
yzwzfyz 發(fā)表于 2023-8-28 16:48
1、找到加熱的接口(IO)。
2、做一個(gè)控制輸出的標(biāo)記KZ。
3、當(dāng)KZ=1時(shí),讓IO口恒定輸出為關(guān)邏輯。當(dāng)KZ=0 ...

好的,我來(lái)試試
作者: mcuhui    時(shí)間: 2023-8-29 08:45
IdeaMing 發(fā)表于 2023-8-28 17:48
程序如果上電是運(yùn)行,按一下按鍵是關(guān)閉的話(huà),你可以把輸出腳做個(gè)電平取反電路。

if(PWM == 0)
                {
                        PWM = ~1;        //關(guān)機(jī)
                        TR1 = 1;        //定時(shí)器1開(kāi)始計(jì)時(shí)
                }
是這樣嗎?
作者: IdeaMing    時(shí)間: 2023-8-30 10:43
mcuhui 發(fā)表于 2023-8-29 08:45
if(PWM == 0)
                {
                        PWM = ~1;        //關(guān)機(jī)

硬件非門(mén)電路
作者: sj820224    時(shí)間: 2023-8-30 13:47
hb_lhw 發(fā)表于 2023-8-28 16:38
貌似按了一次開(kāi)關(guān)后,才能工作。

實(shí)際卻是一上電就開(kāi)啟加熱了




歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1