STM32LED--基于HAL库(LCD与LED冲突?一文看懂如何精准劝架)


前言

相关说明:

开发板:CT117E-M4(STM32G431RB 蓝桥杯嵌入式比赛板)
开发环境: CubeMX+Keil5
在历年真题中,几乎每题都会遇到LED与LCD显示冲突的情况,虽然第十二届省赛没有涉及这一矛盾,但第十三届考的概率仍然很大。


心得分享:

一、LED和LCD的矛盾在哪

在这里插入图片描述

上面是官方提供控制LED的原理图。控制LED状态用到的芯片是SN74HC573ADWR,我们可以控制PC8~ PC15引脚输出高低电平到D端。当LE脚(PD2)输入为高电平时,D端输入的电平传输到Q端输出;当LE脚输入为低电平时,Q端输出被锁存。那点亮LED1的步骤就是PC8输出低电平,PD2输出高电平再输出低电平,这样LED1就可以被点亮了

在这里插入图片描述这张是LCD的原理图,从两图中可以看出控制LED和LCD的引脚都有PC8 ~ PC15,这八个引脚对应的正好就是LED1 ~ LED8。

那么当需要实时更新数据就会出现D端数据被修改的情况,LED1就无法正常闪烁。比如LED1要以0.5s的频率闪烁(若使用Toggle函数实现),当前状态为灭,那下一状态应该为亮,这时LCD更新显示PC8引脚电平就无法确定了,那Toggle后的结果自然也无法确定,这时LED1便不能以固定频率进行闪烁

二、部分真题要求解析

(按照从易到难的顺序展示、解析,下同)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

综合分析

从以上三图+第十二届题目(无需解决冲突)综合分析,似乎官方对于解决冲突的考察力度有所降低,从第八届(实时时钟显示+流水灯)到第十届(实时时钟显示+LED闪烁)到第十届(电压检测+LED闪烁)再到十二届(……😃),难度都在下降。

为什么还要讲

虽然对于解决冲突的考察力度有所降低,但考察概率仍然很大,所以需掌握解决冲突最基本的方法(LED状态数组+定时器),这里会将上面设计到的三种情况都做详细说明,最基本的掌握LED状态数组+定时器即可

真题涉及矛盾

1.第十届省赛真题
虽然难度有所降低,但题目的要求比往年都更加具体:
a.一状态LED以固定频率闪烁,另一状态LED熄灭。
b.除提醒功能的指示灯外,其他指示灯均处于熄灭状态。
c.实时获取电压值的情况下保持LED以固定频率闪烁。

2.第九届省赛真题
a.在实时时钟显示情况下保持LED以固定频率闪烁。

3.第八届省赛真题
a.在实时时钟显示的情况下展示流水灯效果。

三、解决方法

第十届省赛真题(数组法)

数组

既然LCD更新显示会使D端数据无法确定,那便造一个数组用于存储LED1~LED8的当前状态,我将其命名为LED_Close(随意,开心就好……),这样命名是为了和原理图逻辑相同,数组元素为1则下标对应LED灯灭,为0则亮,如LED_Close[1]=0,那LED1当前状态就是亮。数组长度根据题目使用LED灯数量决定,第零号元素不用。

uint8_t LED_Close[2]={1,1};//如果只用LED1 那我长这样

函数

有了当前状态的存储数组,那怎么使LED闪烁呢?请看下面两个函数。

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(htim->Instance==TIM6)//定时器6中断
	{
		LED_Close[1]=!LED_Close[1];//状态反转
	}
}
void LED_AllClose(uint8_t *LED_Close)//LED状态改变函数
{
	uint8_t i;
	LED1(ON);//默认开启
	for(i=1;i<=1;i++)
	{
		if(LED_Close[i])//如果值为1
		{
			switch(i)//则下标对应LED灯关闭
			{
				case 1:
					LED1(OFF);//为1关闭
					break;
			}
		}
	}
	LED2(OFF);//不使用的默认关闭 使用就像LED1一样操作即可(默认开启,增加case)
	LED3(OFF);
	LED4(OFF);
	LED5(OFF);
	LED6(OFF);
	LED7(OFF);
	LED8(OFF);
	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
}

LED_AllClose函数中,默认认为LED1为亮,一旦LED_Close[1]的值为1,则将LED1状态更改为灭,最后再用锁存器锁存

当只使用LED1进行闪烁时,可以使用定时器控制LED1闪烁频率,即每次定时器中断时将当前存储的状态反转一次,再调用LED_AllClose函数对LED1进行更新显示即可实现闪烁效果。

第九届省赛真题(秒中断+数组法)

第九届省赛题仍然沿用上面讲的数组法对LED闪烁频率进行精准把控。
Q:那还要秒中断干嘛?
A:秒中断存在的目的是让时钟精确地显示
Q:用定时器一秒显示一次不可以吗?
A:可以,但误差相对较大,有时计数到一个数时会停留较长时间(秒中断可以完美解决此问题)。

秒中断详细实现可参考STM32RTC秒中断–基于HAL库(一文看懂如何配置并使用)

第八届省赛真题

第八届省赛题涉及LED闪烁,实时时钟,还涉及到流水灯(……😃)。
LED闪烁仍然可以使用数组法解决,实时时钟用秒中断解决,那流水灯呢?
将流水灯放在数循环中跑时,会出现一个现象:流水灯跑着的时候,时钟更新显示了,根据原理可知D端数据被改变了,这就会直接导致流水灯显示错误(断水灯?)。
Q:那如何解决?
A:解决的方法其实很简单,就是在D端数据不变时再跑流水灯,简单讲就是时钟更新后,再跑流水灯,这样LCD就不会影响到LED了

四、源码(转载请注明出处)

写了个测试用例供大家测试使用,只有多动手测试,才能熟练掌握!
在这里插入图片描述


总结

以上就是全部内容,如有错误请批评指正。

  • 16
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AゞOctopus๊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值