蓝桥杯专题:STM32G431RBT6解决LED与LCD显示冲突实战指南
一、CubeMx的配置
见(蓝桥杯)STM32G431RBT6(按键上)的文章
二、LCD文件的导入
见(蓝桥杯)STM32G431RBT6(点亮LCD)的文章
三、模块化添加文件
见(蓝桥杯)STM32G431RBT6(按键中/模块化)的文章
四、KEY的代码导入
从(按键下)里面导入key.c,key.h,mian.c里面的所有函数代码
五、注意
这篇文章的代码的配置用的是LED2的名字,但实际上我想写的是LCD2,写错了
六、LCD与LED的冲突
在完成上面的(蓝桥杯)STM32G431RBT6(按键下)的CubeMx的配置,kile5里面的文件导入key.c,key.h,mian.c等这些文件的导入,包括lcd驱动文件的移植之后,写入LCD_DisplayStringLine(Line0 ,(unsigned char *)"hello world");就会发现,LCD能够显示,但是我的按键控制不了我的LED灯了,这是因为它们的端口冲突了,所以导致我按键控制LED灯的现象不能正常实现
七、解决办法一
这个程序的现象就是:我按下按键4,我的第4个灯由亮变灭,后面不管再怎么按都不会改变我的灯的状态
这个程序的理解逻辑:按键按下,我就打开我的使能端口,然后执行电平翻转,之后再关闭我的使能端口,关闭之后下面的液晶的函数去操纵PC端,改变PC端的数值之后是不会影响到灯的状态的,因为锁存器已经锁住了,保持住了我灯翻转之后的状态
八、这个程序的错误点
(1)我们首先去到电平翻转的函数,看看他的定义
我们首先获取LED1端口的值,然后进行翻转,然后来实现这个端口翻转之后的状态,所以我的LED才会电平翻转,实现亮灭亮灭
但是因为LCD占的有些端口是和LED的端口是相同的,所以最开始LCD的端口就会影响LED端口。假设我把LED端口的值全都置high,按道理来说,下载程序进去之后,应该都变灭了,但是因为我有LCD的端口的影响,所以我的LED的现象就一直是亮着的
然后我第一下按下我的按键,此时我的电平会由亮变灭,但此时我的PC8端口由亮变灭的这个值不知道是哪儿来的一个值,让他翻转了然后我的LED灯就变灭了
但是后面我的程序就开始执行我的LCD的程序,那么我给它写进去的“hello world”这里面的最后一个字符d也有数值,所以下一次翻转电平,翻转的数值就是d这个数值。因为我的字符是固定的,所以我后续的状态就全都是固定的,所以我的灯按下之后,再按多少次它的状态都不会改变
(2)HAL_GPIO_TogglePin ()的执行含义
HAL_GPIO_TogglePin这个是为了执行电平翻转,括号里面的东西就是让谁去翻转,相当于前面的就是武器,后面的就是选一个人,决定让谁去拿武器执行任务
(3)不理解
为什么我的按键第一次按下可以翻转我的电平,按道理来说,我的字符早就已经阻塞住了我的端口,它应该第一次按下也改变不了状态
九、解决办法二
(1)代码部分
因为翻转函数翻转的是端口的值,所以i我们要是想LCD和LED不冲突的话,我们就让LED的变化受另外一个变量的控制,让这个变量来控制LED灯的亮灭,而不是让PC8端口来控制LED灯的亮灭
uint8_t led_status=0;
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
if(get_key_status(1)==key_pressed)
{
HAL_GPIO_WritePin(LED_EN_GPIO_Port ,LED_EN_Pin ,GPIO_PIN_SET );
led_status=!led_status;
HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin ,led_status);
HAL_GPIO_WritePin(LED_EN_GPIO_Port ,LED_EN_Pin ,GPIO_PIN_RESET );
do_it_every_Nms(1,1000);
//这个就相当于是一个计时的作用,所以放在使能函数外面也没有关系
}
LCD_DisplayStringLine(Line0 ,(unsigned char *)"hello world");
}
代码部分要注意,按键的代码,LCD的代码,文件的移植和工程的配置,一步都不能出错,否则程序显现不出来都不知道是哪一步的问题。注意头文件不要少包含(key,h的头文件stm32和main都要包含),定义不要忘了定义(枚举类型,尤其注意有些文件里面写的是key_states,有些文件里面写的是key_states[],要看清楚自己是怎么写的,再使用状态的时候才不会出错。还有一些定义的数字也要记得定义),初始化函数要写(LCD的初始化函数一定要记得写),循环里面的函数要写得有逻辑性
(2)正确代码的逻辑
我们开启和关闭PD2的使能函数是为了不让LCD和LED冲突的端口上的值影响LED,所以按键按下我才进入LED的程序,按键松开,我就关闭LED的程序
按键按下之后,我们就对LED1进行一个写入函数,这个函数就是执行,当给LED的值为0时,就点亮LED,当LED的值不为0时,就关闭LED。
我们用了一个取反函数,按下一次取反一次,按下一次取反一次,所以LED灯就是亮灭亮灭
当我们长按的时候,先进行一个计时,到了1000ms就又对我的LED灯进行取反,所以可以实现周期性的亮灭亮灭
因为我们对LED灯输入的值是自己另外定义的一个变量,所以就算LCD把LED的端口给占用了,也影响不了我LED执行程序
(3)HAL_GPIO_WritePin()函数
这个函数主要就是执行的是看PinState是不是等于0,等于0 执行一个函数,不等于0就执行另外一个函数
这个PinState就相当于是一个参数,可以外界输入的,不是固定格式,是可以改变的
这个就是对led_status取反,给led_status的定义是0,取反之后的值就是255
所以我的HAL_GPIO_WritePin是可以写入led_status
作者:2301_81764359