|
各位大神,現(xiàn)在從某開源平臺找了一個開源案例DIY,功能類似電蚊香加熱器。
現(xiàn)在問題是:這個產(chǎn)品一上電就會自動開啟加熱,我想改成手動開啟加熱,目前沒有找到從程序哪個地方更改。
懇請大神幫忙看看。以下是源碼
單片機(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; //定時器時鐘12T模式
TMOD &= 0xF0; //設(shè)置定時器模式
TL0 = 0x18; //設(shè)置定時初始值
TH0 = 0xFC; //設(shè)置定時初始值
TF0 = 0; //清除TF0標(biāo)志
TR0 = 1; //定時器0開始計時
ET0 = 1; //使能定時器0中斷
}
void Timer1_Init(void) //僅記錄時間用于測溫
{
AUXR &= 0xBF; //定時器時鐘12T模式
TMOD &= 0x0F; //設(shè)置定時器模式
TMOD |= 0x10; //設(shè)置定時器模式
TL1 = 0; //設(shè)置定時初始值
TH1 = 0; //設(shè)置定時初始值
TF1 = 0; //清除TF1標(biāo)志
ET1 = 1; //使能定時器0中斷
}
void Int1_Init()
{
IT1 = 1; //使能INT1下降沿中斷
EX1 = 1; //使能INT1中斷
}
void GPIO_init()
{
P3M1 = 0xFB; //按鍵準(zhǔn)雙向
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分頻,當(dāng)100分頻時部分充電寶因負(fù)載脈寬過小而休眠
i = 0;
if(run_mode != 1)//非運(yùn)行狀態(tài)
{
if(PWM == 0)
{
PWM = 1; //關(guān)機(jī)
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開始分段運(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; //定時器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) //松開時才會觸發(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);//對應(yīng)4~12小時,還有一直運(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);//對應(yīng)4~12小時,還有一直運(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小時內(nèi)則倒計時
{
sec_countdown--;
if(sec_countdown == 0)//倒計時結(jié)束
{
run_mode = 0;
}
}
}
switch(run_mode)
{
case 0: //停止關(guān)燈
LED = 1;
break;
case 1: //運(yùn)行常亮
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; //清零時間計數(shù)
}
void Timer1_Isr() interrupt 3
{
TF1 = 0; //清除TF1標(biāo)志
TR1 = 0; //定時器1停止計時
run_mode = 2; //正常測溫不會進(jìn)入T1中斷
}
|
|