久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2150|回復: 13
收起左側

STC單片機程序問題請教 功能類似電蚊香加熱器

[復制鏈接]
ID:1001745 發表于 2023-8-28 13:39 | 顯示全部樓層 |閱讀模式
各位大神,現在從某開源平臺找了一個開源案例DIY,功能類似電蚊香加熱器。
現在問題是:這個產品一上電就會自動開啟加熱,我想改成手動開啟加熱,目前沒有找到從程序哪個地方更改。
懇請大神幫忙看看。以下是源碼
單片機源程序如下:
#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;                        //定時器時鐘12T模式
        TMOD &= 0xF0;                        //設置定時器模式
        TL0 = 0x18;                                //設置定時初始值
        TH0 = 0xFC;                                //設置定時初始值
        TF0 = 0;                                //清除TF0標志
        TR0 = 1;                                //定時器0開始計時
        ET0 = 1;                                //使能定時器0中斷
}

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

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

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

static uint16_t save_tick = 0;        //安全計時
void pwm_scan()
{
        static uint8_t i = 0;
        static uint8_t duty_cycle = 10;
        uint8_t ntc_temp;
        
        i++;
        if(i >= 200)//200分頻,當100分頻時部分充電寶因負載脈寬過小而休眠
                i = 0;
        
        if(run_mode != 1)//非運行狀態
        {
                if(PWM == 0)
                {
                        PWM = 1;        //關機
                        TR1 = 1;        //定時器1開始計時
                }
                NTC_reset();
                return;
        }
        
        if(duty_cycle < 10)                        //最小占空比為5%
                duty_cycle = 10;
        if(duty_cycle > 190)                //最大占空比為95%
                duty_cycle = 190;
        
        if(i == 0)//啟動
        {
                PWM = 0;
        }
        else if(i == 1)//開始1ms開始分段運行
        {
                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)//持續3分鐘達不到目標溫度,異常狀況
                {
                        save_tick = 0;
                        run_mode = 2;
                }
        }
        else if(i == duty_cycle)
        {
                if(PWM == 0)
                {
                        PWM = 1;        //關機
                        TR1 = 1;        //定時器1開始計時
                }
        }
}

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;        //松開事件
                }
                sw_num=0;
        }
        
        if(event_tick)                        //連擊事件處理
        {
                event_tick++;
                if(event_tick%1000==500)
                {
                        if(sw_num==0)        //松開時才會觸發連擊事件
                                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)        //正在運行,則關機
                                {
                                        sec_countdown = 0;
                                        run_mode = 0;
                                }
                                else                        //讀取歷史記錄
                                {
                                        sec_countdown = (get_new_data() + 2) * (2 * 60 *60);//對應4~12小時,還有一直運行
                                        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);        //保存數據
                        
                                sec_countdown = key_temp * (2 * 60 *60);//對應4~12小時,還有一直運行
                                run_mode = 1;
                                break;
                }
               
                sec_div1000++;
                if(sec_div1000>=1000)//每秒執行一次
                {
                        sec_div1000=0;
                        if(sec_countdown > 0 && sec_countdown < 50000)//0~13小時內則倒計時
                        {
                                sec_countdown--;
                                if(sec_countdown == 0)//倒計時結束
                                {
                                        run_mode = 0;
                                }
                        }
                }
                switch(run_mode)
                {
                        case 0:        //停止關燈
                                LED = 1;
                                break;
                        case 1:        //運行常亮
                                LED = 0;
                                break;
                        case 2:        //錯誤閃爍
                                LED = sec_div1000 > 500 ? 1: 0;
                                break;
                }
        }
}

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

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

void Timer1_Isr() interrupt 3
{
        TF1 = 0;                //清除TF1標志
        TR1 = 0;                //定時器1停止計時
        run_mode = 2;        //正常測溫不會進入T1中斷
}

回復

使用道具 舉報

ID:1040201 發表于 2023-8-28 16:02 | 顯示全部樓層
有原理圖才好分析,我看PWM=1時 是關機,你在GPIO初始化的時候 賦值一下。
回復

使用道具 舉報

ID:1006814 發表于 2023-8-28 16:35 | 顯示全部樓層

是立創開源廣場里的STC電熱蚊香加熱器嗎?
回復

使用道具 舉報

ID:1006814 發表于 2023-8-28 16:38 | 顯示全部樓層
貌似按了一次開關后,才能工作。
回復

使用道具 舉報

ID:123289 發表于 2023-8-28 16:48 | 顯示全部樓層
1、找到加熱的接口(IO)。
2、做一個控制輸出的標記KZ。
3、當KZ=1時,讓IO口恒定輸出為關邏輯。當KZ=0時,讓IO口為原定的輸出,即加熱。
4、做一個選擇鍵,根據健入狀態,決定KZ值。

回復

使用道具 舉報

ID:276663 發表于 2023-8-28 17:48 | 顯示全部樓層
程序如果上電是運行,按一下按鍵是關閉的話,你可以把輸出腳做個電平取反電路。
回復

使用道具 舉報

ID:1001745 發表于 2023-8-29 08:40 | 顯示全部樓層
liucan2020 發表于 2023-8-28 16:02
有原理圖才好分析,我看PWM=1時 是關機,你在GPIO初始化的時候 賦值一下。

是的,用的是PMOS,PWM=1才是關機。
回復

使用道具 舉報

ID:1001745 發表于 2023-8-29 08:41 | 顯示全部樓層
hb_lhw 發表于 2023-8-28 16:35
是立創開源廣場里的STC電熱蚊香加熱器嗎?

是的,就是這個。V1.0版本應該是需要開關開啟才工作的。可是我寫進去之后一上電就開啟加熱了
回復

使用道具 舉報

ID:1001745 發表于 2023-8-29 08:41 | 顯示全部樓層
hb_lhw 發表于 2023-8-28 16:38
貌似按了一次開關后,才能工作。

實際卻是一上電就開啟加熱了
回復

使用道具 舉報

ID:1001745 發表于 2023-8-29 08:42 | 顯示全部樓層
yzwzfyz 發表于 2023-8-28 16:48
1、找到加熱的接口(IO)。
2、做一個控制輸出的標記KZ。
3、當KZ=1時,讓IO口恒定輸出為關邏輯。當KZ=0 ...

好的,我來試試
回復

使用道具 舉報

ID:1001745 發表于 2023-8-29 08:45 | 顯示全部樓層
IdeaMing 發表于 2023-8-28 17:48
程序如果上電是運行,按一下按鍵是關閉的話,你可以把輸出腳做個電平取反電路。

if(PWM == 0)
                {
                        PWM = ~1;        //關機
                        TR1 = 1;        //定時器1開始計時
                }
是這樣嗎?
回復

使用道具 舉報

ID:276663 發表于 2023-8-30 10:43 | 顯示全部樓層
mcuhui 發表于 2023-8-29 08:45
if(PWM == 0)
                {
                        PWM = ~1;        //關機

硬件非門電路
回復

使用道具 舉報

ID:1092275 發表于 2023-8-30 13:47 | 顯示全部樓層
hb_lhw 發表于 2023-8-28 16:38
貌似按了一次開關后,才能工作。

實際卻是一上電就開啟加熱了
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 91福利在线导航 | 国产色婷婷久久99精品91 | 中文字幕不卡 | 国产91亚洲精品一区二区三区 | 中文字幕欧美一区二区 | 欧美一区二区三区在线视频 | 日韩在线欧美 | 亚洲视频在线看 | 免费一区二区三区在线视频 | 欧美激情视频一区二区三区在线播放 | 国产精品毛片一区二区在线看 | 久久精品国产一区二区电影 | 国产偷录叫床高潮录音 | 亚洲一区国产 | 免费精品国产 | 最新国产精品精品视频 | 久久日韩精品一区二区三区 | 国产一区在线视频 | 欧美在线观看免费观看视频 | 亚洲一区二区三区在线播放 | 亚洲 中文 欧美 日韩 在线观看 | 91精品国产91久久久久久最新 | 精品视频一区二区三区 | 中文字幕一区二区三区在线视频 | 亚洲精品视频在线 | 久久久久久电影 | 亚洲精品久久久久久一区二区 | 午夜免费视频 | 黄色三级在线播放 | 五月综合激情婷婷 | 免费成人高清 | 超碰97av | 美女毛片| 久久久91精品国产一区二区三区 | 免费高潮视频95在线观看网站 | 亚洲欧美一区二区三区1000 | 亚洲一区欧美一区 | 一级无毛片 | 欧美一区二区三区在线观看视频 | 蜜桃色网| 成人三级在线播放 |