当前位置:首页 > 电子图书 > 电子电路 > 正文内容

C语言中实现边沿函数算法及应用,这是抛弃PLC留下的痛!

admin1年前 (2023-07-25)电子电路58

本原创文章基于实践经验,提供严谨可靠的设计原理及思路。

后续准备穿插一些有关单片机应用C语言编程技巧的文章,那么本期讲解边沿信号的应用。很多从事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只加1
 i++; //以下为SW2按键长按计数间隔50ms
 if(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只减1
 i++; //以下为SW2按键长按计数间隔50ms
 if(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)返回值为1,if条件语句判断为真,在1ms周期内Cnt_Code加1;

if(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) 中判断语句的假值→真值也可以作为上升沿来使用,是不是很妙

以上的两种用法只是上升沿函数和下降沿函数最为普遍的用法,运用熟练后,可以自由发挥,另外,以上变量的数据类型我都定义为u8(unsigned char),因为我的STM32的标准库里没有布尔类型(bool)的定义,我也一直没使用过布尔类型。变量定义如下:

u8 i; //按钮长按间隔计数
u8 Cnt_Code;//参数码
u8 Flag_OVP;//过压标志
u8 Flag_1ms;//1ms标志

❤要点:

①上升沿函数和下降沿函数的返回值都为1,且在当前扫描周期内有效,下一个周期就变为0了,所以可以理解为其输出了一个脉冲;

按键消抖的常用方法是延时判断,其实用边沿函数处理开关信号完全不用消抖,直接调用即可;如果主函数有实时性要求较高的扫描程序存在,延时函数的弊病就出来了,ta会严重影响扫描周期。

③用于只需要执行一次的指令(非保持),如加一减一、移位、交换、存储,以及一个变量受制于多个条件等,如果不用上升沿或者下降沿,那么代码在每个周期都会被执行一次,于是就不能达到理想效果;


扫描二维码推送至手机访问。

版权声明:本文由梦魁网络资源站发布,如需转载请注明出处。

本文链接:https://family.monkui.com:39/?id=1161

标签: 电子电路
分享给朋友:

相关文章

看爽了!50张电工接线图,够你琢磨一天了

看爽了!50张电工接线图,够你琢磨一天了

   众所周知,所谓电工也就是成天跟“电”打交道的存在,那么下面这么多电工接线图,各位老师傅熟悉哪些呢?一起来看看吧!1、启、停延时不断循环2、桥式全波整流滤波电路3、起保停控制4、电源线的接电方式5、时间继电器延时控制...

非常全的地线基础知识整理

非常全的地线基础知识整理

线的作用地线的主要作用就是当电器出现故障时,电源可能击穿(或:破坏)某些元件,使电器的外壳带电。将电器的外壳接地,可以使漏电保护装置1. 信号“地”;信号“地”又称参考“地”,就是零电位的参考点,也是构成电路信号回路的公共段,图形符号“⊥”...

电工最实用的8大经验公式,快快收藏~

电工最实用的8大经验公式,快快收藏~

一、照明电路电流计算及熔丝刀闸的选择口诀:白炽灯算电流,可用功率除压求;日光灯算电流,功率除压及功率因数求(节能日光灯除外);刀闸保险也好求,一点五倍额定流。说明:照明电路中的白炽灯为电阻性负荷,功率因数cosΦ=1,用功率P单位瓦除以电压...

200个电气知识,值得收藏

01电荷的性质答:电荷之间存在着相互作用力,同性电荷相互排斥,异性电荷相互吸引。02电场答:在带电体周围的空间存在着一种特殊物质,它对放在其中的任何电荷表现为力的作用,这一特殊物质叫做电场。03电阻,影响电阻的因素答:电流在导体内流动过程中...

44种实用电路图,掌握了,也就一通百通了!

44种实用电路图,掌握了,也就一通百通了!

通过以下各种各样的实用电路,大家可以了解元器件的结构、特性、动作原理及电路的基本控制方式,掌握一些控制规律,这样的话,在日后的电路识图中就能融会贯通,一通百通。文章中的电路图有难有易,有些图现在可能看不懂,说不定以后就能看懂了,建议大家收藏...

看懂这75张电路图,老板都管不了你!

看懂这75张电路图,老板都管不了你!

今天为大家整理了一些各类电气控制接线图、电子元件工作原理图,还有可控硅整流电路及负反馈调速装置原理等等,希望对大家的工作有所帮助,一起来了解一下吧。01可控硅调速电路02电磁调速电机控制图03三相四线电度表互感器接线04能耗制动05顺序起动...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。