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 上溢中断 |