选择大连网站建设,crm系统营销,网站积分解决方案,wordpress 页面链接很多从事PLC编程的朋友都知道#xff0c;不管是什么品牌的PLC#xff0c;都有上升沿和下降沿指令。❤那么什么情况下我们才会使用或必须使用边沿信号呢#xff1f;边沿信号我们又如何获取呢#xff1f;如图1#xff0c;任何一个开关信号#xff08;或数字信号#xff09… 很多从事PLC编程的朋友都知道不管是什么品牌的PLC都有上升沿和下降沿指令。❤那么什么情况下我们才会使用或必须使用边沿信号呢边沿信号我们又如何获取呢如图1任何一个开关信号或数字信号都可以分解成4个状态①高电平 ②低电平 ③上升沿 ④下降沿。图1开关信号❤在PLC编程里上升沿指令和下降沿指令可以直接调用那么对于单片机的C语言编程又如何实现边沿信号的判断呢因为早期做过PLC编程的缘故受PLC编程思路的影响对C语言编程急需简单而高效的边沿函数于是痛定思痛编写了以下上升沿函数和下降沿函数使用方便、简单暴力。/*************************************************上升沿函数
*************************************************/
u8 Posedge(u8 Old_Value,u8 m)
{static u8 New_Value[100];u8 _PLS[100];_PLS[m] Old_Value (Old_Value ^ New_Value[m]);New_Value[m] Old_Value;return(_PLS[m]);
}❤上升沿函数的逻辑原理是第一次进入函数①Old_Value从0→1此时New_Value[m]初始值为0②_PLS[m] Old_Value (Old_Value ^ New_Value[m])的运算结果为1括号里异或运算为1③New_Value[m]) Old_Value被赋值为1④返回_PLS[m]值为1。第二次及以后进入函数①New_Value[m]保持为1因为被定义了static类型第二次调用不会被清0②_PLS[m] Old_Value (Old_Value ^ New_Value[m])的运算结果为0括号里异或运算为0③New_Value[m]) Old_Value仍然被赋值为1④返回_PLS[m]值为0。⑤Old_Value从1→0运算结果为0返回值也为0❤所以上升沿函数只在变量0→1变化时返回值为1。另外形参m的取值范围是0~99是为了区分不同Old_Value的实参如果不同的实参用相同的m值比如0则该函数返回值会发生混乱具体应用下面会附上实例。/************************************************下降沿函数
************************************************/
u8 Negedge(u8 Old_Value,u8 m)
{static u8 New_Value[100];u8 _PLF[100];_PLF[m] ~Old_Value (~Old_Value ^ New_Value[m]);New_Value[m] ~Old_Value;return(_PLF[m]);
}下降沿函数的原理与上升沿函数完全一样只需把Old_Value值取反即可。❤应用实例讲解①以下为按键短按长按计数为例单片机使用的是STM32F103系列的。if(Flag_1ms) //在1ms扫描周期内
{Flag_1ms 0;if(SW1_IN 0) //SW1按键长按参数码Cnt_Code以50ms间隔递增{if(Negedge(SW1_IN,0) 1) Cnt_Code; //SW1按键短按Cnt_Code只加1i; //以下为SW2按键长按计数间隔50msif(i 50) //取经验值50{i 0;Cnt_Code;if(Cnt_Code 101) Cnt_Code 0; //Cnt_Code值范围1--100}}
if(SW2_IN 0) //SW2按键长按参数码Cnt_Code以50ms间隔递减{if(Negedge(SW2_IN,1) 1) Cnt_Code--; //SW1按键短按Cnt_Code只减1i; //以下为SW2按键长按计数间隔50msif(i 50) //取经验值50{i 0;Cnt_Code--;if(Cnt_Code 0) Cnt_Code 100;}}
}是不是发现了一个bug本人没有做按键的消抖处理别急用边沿函数处理开关信号完全不需要消抖处理是不是很简单省事if(Negedge(SW1_IN,0) 1) Cnt_Code;上面代码表示SW1按键按下时函数Negedge(SW1_IN,0)返回值为1if条件语句判断为真在1ms周期内Cnt_Code加1if(Negedge(SW2_IN,1) 1) Cnt_Code--;逻辑同上但注意括号(SW2_IN,1)内不是0而是1是为了避免与前一个下降沿函数在调用时有冲突。②电池过压保护程序if(Posedge(Battery_Voltage 14 ,0) 1)//电池电压大于14V
{Flag_OVP 1; //过压标志置位
}
if(Posedge(Battery_Voltage 14 ,1) 1)//电池电压小于14V
{Flag_OVP 0; //过压标志复位
}上面代码的上升沿函数Posedge(Battery_Voltage 14 ,0) 中判断语句的假值→真值也可以作为上升沿来使用是不是很妙。以上的两种用法只是上升沿函数和下降沿函数最为普遍的用法运用熟练后可以自由发挥另外以上变量的数据类型我都定义为u8unsigned char因为我的STM32的标准库里没有布尔类型bool的定义我也一直没使用过布尔类型。变量定义如下u8 i; //按钮长按间隔计数
u8 Cnt_Code;//参数码
u8 Flag_OVP;//过压标志
u8 Flag_1ms;//1ms标志❤要点①上升沿函数和下降沿函数的返回值都为1且在当前扫描周期内有效下一个周期就变为0了所以可以理解为其输出了一个脉冲②按键消抖的常用方法是延时判断其实用边沿函数处理开关信号完全不用消抖直接调用即可如果主函数有实时性要求较高的扫描程序存在延时函数的弊病就出来了ta会严重影响扫描周期。③用于只需要执行一次的指令非保持如加一减一、移位、交换、存储以及一个变量受制于多个条件等如果不用上升沿或者下降沿那么代码在每个周期都会被执行一次于是就不能达到理想效果声明本文于网络整理版权归原作者所有如来源信息有误或侵犯权益请联系我们删除或授权事宜。