![]() |
發布時間: 2024-1-6 14:46
正文摘要:/*一、上電后故障燈和加水燈點亮,加熱燈熄滅; 二、開關低電平后,延時5s加熱燈亮,加水燈滅 ,故障燈熄滅。 三、開關高電平后 ,加水燈點亮,故障燈和加熱燈熄滅。 四、保護功能兩個:1、開機后六分鐘如果開關 ... |
wulin 發表于 2024-1-8 10:22 /*一、上電后故障燈和加水燈點亮,加熱燈熄滅; 二、第一次開關低電平后,延時5s加熱燈亮,加水燈滅 ,故障燈熄滅。第二次之后一直延時3s加熱燈亮,加水燈滅 ,故障燈熄滅。 三、開關高電平后 ,加水燈點亮,故障燈和加熱燈熄滅。 四、保護功能兩個:1、開機后六分鐘如果開關一直處于高電平,則:故障燈1秒閃爍,加熱燈加水燈熄滅。 2、在開關由低電平轉為高電平后,加水燈加熱燈都點亮,延時30秒,開關電平沒有轉換,則:故障燈閃爍,加水燈加熱燈熄滅 */ 第二條修改了一下延時動作,分第一次延時動作5s,第二次后面的延時動作3s,應該怎樣修改程序? |
問題第三點與保護的第二點邏輯矛盾 |
wulin 發表于 2024-1-8 10:22 //一、上電后故障燈和加水燈點亮,加熱燈熄滅;這段代碼如果修改為://一、上電后故障燈和加水燈點亮,延時1秒后,加熱燈熄滅;這樣應該怎么修改? |
hjx5548 發表于 2024-1-7 20:49 寫一個死循環報警函數替換閃爍代碼 void Alarm() { unsigned long i; while(1) { LED3=~LED3;//故障燈閃爍 i=50000L; while(i--); } } if(count2>=600)//超過30秒沒有再次低電平 { LED1=0;//加熱燈滅 LED2=0;//加水燈滅 Alarm();//故障燈閃爍 } |
wulin 發表于 2024-1-7 09:52 保護后,不需要恢復現場,一定重啟電源,才能工作,否則一直保護。應該怎樣修改? |
wulin 發表于 2024-1-7 09:52 只要LED3閃爍 LED1和LED2始終為低電平。不管KEY電平怎么變化,LED1和LED2始終為低電平,保護閃爍了,只有重新上電才能恢復,應該怎樣修改? |
hjx5548 發表于 2024-1-7 00:20 你的硬件電路和軟件設計都有嚴重問題,延時功能也不是你這么個玩法。給你徹底改寫,有詳細注釋,看不明白就反復測試反復看,理清邏輯關系。
|
hjx5548 發表于 2024-1-7 09:01 閃爍太暗是因為閃爍間隔時間太短,或者減少串聯電阻 |
csmyldl 發表于 2024-1-6 19:21 把這個取消了,程序在貼上了,但是故障指示燈閃爍太暗了,幾乎看不到,而且時間到了LD2也不能進入低電平。 |
csmyldl 發表于 2024-1-6 19:21 #include <STC8H.h> #define uchar unsigned char #define uint unsigned int sbit LD3 = P3^3; sbit LD2 = P5^5; sbit KEY1 = P3^2; sbit ERR_LED = P5^4; bit t0zd0b=0; bit t1zd0b=0; uchar count; char sec,min; uint i=0,j=0; uchar t0IntCnt = 0; //T0中斷計數變量 uint ledFlashCnt = 0; //ERR_LED指示燈閃爍周期計數 uchar Flag2ms = 0; //2MS到標志 uchar u8Flag6min = 0; //6分鐘到標志 void Timer0_Init(void); void Timer1_Init(void); void delay_1ms(void); void delay_ms(uint var); void IO_init(); /* 必須開啟T0中斷,延時函數才起作用 */ void delay_1ms(void) { uchar i = 4; //每次250us,1ms中斷4次 while (i) { if (t1zd0b) { t1zd0b = 0; //清除時間中斷標志 --i; } } } void delay_ms(uint var)//延時單位為毫秒,最多延時65.535秒(65535mS) { while (var--) { delay_1ms(); } } #define d_s(s) delay_ms((s)*1000ul)//延時單位為秒 void IO_init() { P3M0 = 0x08; P3M1 = 0x00; P5M0 = 0x30; P5M1 = 0x00; ERR_LED = 0; LD2 = 1; LD3 = 0; } void Timer0_Init(void) //250微秒@11.0592MHz { AUXR &= 0x7F; //定時器時鐘12T模式 TMOD &= 0xF0; //設置定時器模式 TL0 = 0x1A; //設置定時初始值 TH0 = 0xFF; //設置定時初始值 TF0 = 0; //清除TF0標志 TR0 = 1; //定時器0開始計時 ET0 = 1; //使能定時器0中斷 } void Timer1_Init(void) //250微秒@11.0592MHz { AUXR |= 0x40; //定時器時鐘1T模式 TMOD &= 0x0F; //設置定時器模式 TL1 = 0x33; //設置定時初始值 TH1 = 0xF5; //設置定時初始值 TF1 = 0; //清除TF1標志 TR1 = 1; //定時器1開始計時 ET1 = 1; //開T0中斷 } void TM0_Isr() interrupt 1 //250微秒 { // ERR_LED ^= 1; //測試是否進入中斷 t0zd0b = 1; t0IntCnt++; if(t0IntCnt>=8) //8*250 = 2ms { t0IntCnt = 0; Flag2ms=1; ledFlashCnt ++; } } void TM1_Isr() interrupt 3 //250微秒 { // ERR_LED ^= 1; //測試是否進入中斷 t1zd0b=1; } void main() { Timer0_Init(); Timer1_Init(); EA = 1; //開總中斷 IO_init(); delay_ms(80); while (1) { if(KEY1 == 1 ) //缺水時 { ERR_LED = 0; LD2 = 1; LD3 = 0; if(!u8Flag6min) //6分鐘沒到 { if(Flag2ms) //2ms { Flag2ms=0; if(i<0xFFFF) i++; if(i>=30000) //60000ms,1分鐘 { i=0; j++; } if(j>=1) //方便調試改為1分鐘 { u8Flag6min = 1; LD2 = 0; LD3 = 0; } } } else //6分鐘到,執行LED閃爍 3、如果第一個動作水位開關一直高電平, //也就是開關一直斷開高電平,則故障燈閃爍, //加水加熱電磁閥燈全部熄滅。 { if (ledFlashCnt>=500) //500*2=1000ms { ledFlashCnt = 0; ERR_LED ^= 1; } } } else if(KEY1==0) //b、第二步只要水位到了,也就是開關接通低電平,延時一秒 //加熱燈點亮,延時五秒后,電磁閥燈熄滅,又過一秒,加水燈熄滅。 { u8Flag6min = 0; ERR_LED = 0; LD3 = 1; LD2 = 0; } } } //這樣修改對嗎? |
csmyldl 發表于 2024-1-6 19:21 if(TF1) TF1=0進入中斷,硬件自動清零,這局不要嗎? |
開啟了定時中斷,在進入中斷程序后硬件自動清除標志TF0,而進入中斷后又來判斷該標志,條件永遠不成立 if(TF0) //定時器 0 上溢中斷 |