【国民技术低功耗系列N32L43x测评】3、按键驱动+SPI_LCD屏驱
本帖最后由 emmnn 于 2022-7-11 16:36 编辑**目录 (Table of Contents)**
# 前言
在介绍完RTOS的移植后,今天介绍的是按键驱动和SPI-LCD屏驱的开发及功能演示。
#按键驱动
在官方提供的开发板上,除了reset和wakeup按键外,还提供了三个按键供我们使用。为了方便后续的应用开发,我找了一颗五向开关,另外接了其他IO做演示。
这种按键共有6个引脚,其中一个引脚接地,剩余5个引脚代表5个方向(上下左右以及按下)
将该开关引脚引出来,接到开发板空闲的IO上,并定好宏定义
```c
#define KEY_PORT_GROUP GPIOB
#define KEY_RCC_PERIPH RCC_APB2_PERIPH_GPIOB
#define KEY_UP_PIN GPIO_PIN_2
#define KEY_DOWN_PIN GPIO_PIN_11
#define KEY_LEFT_PIN GPIO_PIN_10
#define KEY_RIGHT_PIN GPIO_PIN_1
#define KEY_PRESSED_PIN GPIO_PIN_0
```
剩下的就是很简单的IO初始化及读IO获取按键状态的操作,具体代码可以查看附件工程。
在使用单片机做嵌入式开发中,按键可以说是最常见的一个模块。虽说对于MCU端来说,它要做的就是很简单的读IO操作,但是实际开发中,要考虑的问题点还是挺多的。比如如何做按键消抖处理,以及在实际应用中,对于各类按键事件(如短按,长按,单击,双击)如何做判断及处理。同时如何保证整个按键应用处理的业务逻辑能保持清晰不乱,完成功能的同时要把这些都做好,这还是挺难的。这里之所以把按键这部分单独拿出来讲,主要是想安利下最近在刷到的在Github上开源的一个简单易用的事件驱动型按键驱动模块。
GitHub地址如下:(https://github.com/0x1abin/MultiButton)
代码由纯C编写,代码简洁,可读性也特别好,200行左右的代码,就实现了按键的各类触发事件,可扩展性也很好,业务逻辑也很清晰(在这里默默地膜拜大佬)。
```c
/**
* @brief 按键事件及回调注册
*
* @return uint8_t
*/
uint8_t KeyRegister(void)
{
button_init(&dev_handler_s.dev_btn_s.btn_up, KeyScan, 0, KEY_UP_ID);
button_init(&dev_handler_s.dev_btn_s.btn_down, KeyScan, 0, KEY_DOWN_ID);
button_init(&dev_handler_s.dev_btn_s.btn_left, KeyScan, 0, KEY_LEFT_ID);
button_init(&dev_handler_s.dev_btn_s.btn_right, KeyScan, 0, KEY_RIGHT_ID);
button_init(&dev_handler_s.dev_btn_s.btn_ok, KeyScan, 0, KEY_PRESSED_ID);
button_attach(&dev_handler_s.dev_btn_s.btn_up, SINGLE_CLICK,BtnUp_Single_Clicked_Handler);
button_attach(&dev_handler_s.dev_btn_s.btn_down, SINGLE_CLICK, BtnDown_Single_Clicked_Handler);
button_attach(&dev_handler_s.dev_btn_s.btn_left, SINGLE_CLICK,BtnLeft_Single_Clicked_Handler);
button_attach(&dev_handler_s.dev_btn_s.btn_right, SINGLE_CLICK, BtnRight_Single_Clicked_Handler);
button_attach(&dev_handler_s.dev_btn_s.btn_ok, SINGLE_CLICK,BtnOk_Single_Clicked_Handler);
button_attach(&dev_handler_s.dev_btn_s.btn_ok, DOUBLE_CLICK,BtnOk_Single_Clicked_Handler);
button_start(&dev_handler_s.dev_btn_s.btn_up);
button_start(&dev_handler_s.dev_btn_s.btn_down);
button_start(&dev_handler_s.dev_btn_s.btn_left);
button_start(&dev_handler_s.dev_btn_s.btn_right);
button_start(&dev_handler_s.dev_btn_s.btn_ok);
dev_handler_s.dev_btn_s.btn_Timer = rt_timer_create("BTN Timer",
BtnTimerCb,
RT_NULL,
5,
RT_TIMER_FLAG_PERIODIC);
if (dev_handler_s.dev_btn_s.btn_Timer != RT_NULL)
rt_timer_start(dev_handler_s.dev_btn_s.btn_Timer);
}
```
根据例程演示,移植到我的工程上后,按键部分实现了我想要的效果。(源码部分只有200行左右,有时间的可以仔细研读下大佬的代码,学习下他的编程思想,可以学习到很多东西的)。
#SPI-LCD屏驱动
讲完了按键驱动模块,接下来讲解下使用MCU的SPI接口来驱动LCD屏。关于屏的话是某宝上很常见的SPI接口的屏,卖家也会提供一些示例驱动代码。
翻看芯片的数据手册及用户手册,得知该MCU有两路SPI外设接口可供我们使用。这里我们使用SPI2,查看数据手册关于引脚复用定义说明,我们使用PB13和PB15分别复用为SPI2的CLK和MOSI脚。
其他引脚定义如下
```c
#define SPI_SCK_RCC_PERIPH (RCC_APB2_PERIPH_GPIOC)
#define SPI_RCC_PERIPH (RCC_APB2_PERIPH_GPIOB)//RCC_APB2_PERIPH_GPIOA
/* RES Port/Pin definition */
#define RES_PORT (GPIOB)
#define RES_PIN (GPIO_PIN_14)
/* DC Port/Pin definition */
#define DC_PORT (GPIOC)
#define DC_PIN (GPIO_PIN_7)
/* BLK Port/Pin definition */
#define BLK_PORT (GPIOB)
#define BLK_PIN (GPIO_PIN_12)
#define SPI_PERIPH (SPI2)
#define SPI_LCD_CLK (RCC_APB2_PERIPH_SPI2)
/* Define port and pin for SDA and SCL */
#define SPI_SCK_PORT (GPIOB)
#define SPI_SCK_PIN (GPIO_PIN_13)
#define SPI_MOSI_PORT (GPIOB)
#define SPI_MOSI_PIN (GPIO_PIN_15)
```
其他部分参考官方例程和屏驱动例程,修改下,屏也能正常点亮。
#效果演示图
#问题点记录
在使用SPI接口驱动LCD屏的过程中,发现了一个问题。一开始,我使用的是PC7和PB15复用为SPI2的SCK和MOSI来驱动LCD,但是实际在使用过程中,用逻辑分析仪抓信号发现时钟引脚SCK始终没有信号输出,后将SCK引脚改为PA10亦是如此。将SCK改到PB13,也就是跟MOSI同属一个GPIO组后,SPI就能正常使用输出信号。不清楚是不是该单片机对于SPI的使用,IO口必须强制要求同属一个GPIO组,本人没有花时间去做更多的验证,之前在其他产家的MCU没遇到过这种问题,在官方提供的文档中也暂时没看到相关的说明。若是有大佬知道问题所在,还希望能帮忙解惑下。:Onion-39:最后工程的附件如下:
#附件
楼主是用的硬件SPI来驱动的吗?如果是软件SPI可以使用不同的端口,如果是硬件SPI,常规来讲应该是一个端口的吧,详细要看一下数据手册吧。 <p>,但是实际开发中,要考虑的问题点还是挺多的。比如如何做按键消抖处理,以及在实际应用中,对于各类按键事件(如短按,长按,单击,双击)如何做判断及处理。同时如何保证整个按键应用处理的业务逻辑能保持清晰不乱,完成功能的同时要把这些都做好,这还是挺难的。这里之所以把</p>
<p> </p>
<p>图文并茂,还做了目录,楼主用心了。</p>
lugl4313820 发表于 2022-7-11 17:41
楼主是用的硬件SPI来驱动的吗?如果是软件SPI可以使用不同的端口,如果是硬件SPI,常规来讲应该是一个端口的 ...
<p>使用的是硬件SPI来驱动的,前阵子公司产品使用过华大的芯片就没这个问题</p>
luojiazidi_87 发表于 2022-7-11 18:00
,但是实际开发中,要考虑的问题点还是挺多的。比如如何做按键消抖处理,以及在实际应用中,对于各类按键事 ...
<p>看样子您是新人,可能是需要赚取一些积分,希望您用心阅读作者的帖子后,再回复有意义的帖子,也是对楼辛苦发帖的尊重。加油!</p>
我看你的代码重映射是AF0, PB13对应是AF0。是不是配置PA10、PC7作为SCK时,没有配置重映射为AF5,GPIO_InitStructure.GPIO_Alternate = GPIO_AF5_SPI2;
页:
[1]