导语:切入正题,在程序中,这个蜂鸣器的驱动是一个高低电平驱动。高电平时三极管导通,蜂鸣器发声;低电平时三极管关断,蜂鸣器不发声。这确实很简单。最初,我在项目中是这样写的:
如果不能保证I/O输出性能,可以根据情况增加上拉或下拉电阻。
切入正题,在程序中,这个蜂鸣器的驱动是一个高低电平驱动。高电平时三极管导通,蜂鸣器发声;低电平时三极管关断,蜂鸼器不发声。这确实很简单。最初,我在程序中是这样写的:
当然,如果单片机没有很好的I/O跳变功能,也可以这样修改:
这里稍作解释:
函数功能:控制蜂鸣器发声。
传入参数:需要让蜂鸣器连续响起cnt次声音。但由于每次响应后都需要关闭一次,所以实际响起的声音数量会比输入次数少一倍。
在while循环结束后,还需要添加一个关闭操作,以确保函数调用完成后,蜂鸼器处于关闭状态。
假设传入参数为2,即希望让蜂音发生两次响应。在执行过程中:
第一次while(4) 开启,然后 cnt减至3
第二次while(3) 关闭,然后 cnt减至2
第三次while(2) 开启,然后 cnt减至1
第四次while(1) 关闭,然后 cnt减至0
第五次while(0) 跳出循环
此时虽然已经到达了 while 结束后的状态,但为了保险起见,我们还要确认函数调用完毕后,蜗音是否已关闭。如果之前使用的是I/O跳变,那么我们无法确定其最终状态,因此加以确认尤为重要。
现在,让我们来探讨如何提高效率。在原有的延迟(Delay)方式下,每一次开关操作都会带来效率损失,但这也是必须的,因为没有延迟则无法实现开关效果。此外,我们也尝试通过更改驱动策略来提升效率。
新的代码如下:
这个新方法较为简洁,它基于定时器和中断处理来实现开关操作,而不是直接依赖延迟时间。具体步骤如下:
确定与引脚相关联的一些必要配置。
配置用于产生定期中断的计数溢出事件。
实现用于管理各类事件和状态变化的心智模型,其中包括了一种名为 Bell_Tog 的函数用以改变引脚状态,以及一个名为 Systick_ms 的全局变量,用以跟踪系统运行时间,并且定义了一个50ms周期间隔,以便模拟软件中的等待行为。
接下来,我们将分析这些新加入代码段落中的关键部分:
首先,为Systic_ms赋予正确值,并使NOW保持与之相差50ms,以便计算即将到来的50ms时间片开始点。
检查当前Bell_Tog()是否被激活,如果未激活,则立即对其进行重置,从而停止任何可能正在进行但尚未完成的事务(如持续信号)。
如果Bell_Tog()已被激活,则执行以下操作:
a). 调用Bell_Tog()函数,将引脚打开或关闭(具体取决于当前状态)。
b). 将BELL_CNT递减,使其朝着零方向移动,同时检查它是否已经达到零。如果到了零,则意味着所有预定的信号发出之后,现在应该重新设置该标志位,以防止进一步信号发送而导致无意图地重复触发同样的序列。
c). 最后,不论何种情况,都强制执行Bell_Tog()作为保护措施,一旦收到请求,就保证整个过程结束后至少有一遍清理工作完成,无论之前是否有信号发出或者何种形式存在的问题,都能得到妥善解决。
最后,这两个核心变量 BELL_CNT 和 FLAG_BELL 是全局性的结构体成员,它们允许不同模块之间共享数据,而不会影响彼此独立性和可维护性。此外,由于它们通常属于不同的C文件内部,因此被封装成结构体形式呈现,使得它们能够跨越多个源文件使用,从而提供更多灵活性并促进模块化设计。