0e1414fc507840f9a1a1393589bd3c4a
本帖最后由 jf_1137202360 于 2022-12-25 22:51 编辑
工程配置 基于N32G457xx_V3.0.06-软件开发套件(Software Development Kit)Nationstech.N32G45x_Library.2.1.0projectsn32g45x_EVALexamplesUSARTPrintfMDK-ARM工程。配置参考https://bbs.elecfans.com/jishu_2325147_1_1.html。
LCD接口 这里选用的是1.3寸,240x240RGB,驱动器为ST7789的LCD。接口为SPI,时钟标注的是SCL和SDA实际就是SPI接口。BLK默认常高可以不接。所以只需要接电源2个引脚,RES(复位),DC(命令选择),SCL(SCK),SDA(MOSI)四个信号引脚。CS固定是低没有引出。
选用SPI1 PA5-SPI1_CLK PA7-SPI1_MOSI
还需要两个IO分别接RES和DC,这里选用PA4和PA6. DC为高时表示发送数据,否则发送命令。
LCD驱动
SPI接口
SPI1的时钟来源于PCLK2.默认配置为最大值72MHz。 在设置64分频时理论应该是72/64=1.125MHz,实测是1.143MHz,由于逻辑分析仪测量还有误差所以差一点,确认了SPI时钟频率OK。 SPI_InitStructure.BaudRatePres = SPI_BR_PRESCALER_64;
LCD_SendCmd(0x11); //Sleep Out 对应值如下 发送命令时DC=0,发送数据时DC=1,确认OK。 空闲时CLK=0,确认OK 第一个边沿采样,确认OK
复位
Res引脚拉低最少10uS,复位后等待120mS再进行其他操作。
- static void LCD_DelayMs(uint32_t timeout)
- {
- volatile uint32_t t = timeout;
- volatile uint32_t ms = 20568; /* 该值需要根据实际调整 */
- while(timeout--)
- {
- ms = 20568;
- while(ms--);
- }
- }
-
- static void LCD_Reset(void)
- {
- GPIO_ResetBits(GPIOA, GPIO_PIN_4);
- LCD_DelayMs(1ul);
- GPIO_SetBits(GPIOA, GPIO_PIN_4);
- LCD_DelayMs(120ul);
- }
-
复制代码
逻辑分析仪实测拉低1mS和等待120mS均正确
写命令这一用BUSY标志判断是否发送完,才能发送下一个bit,而不是用TE标志,TE标志只是表示缓冲区空,并不一定发送完。只有发送完才修改DC的状态。
- static void LCD_SendCmd(uint8_t data)
- {
- while (SPI_I2S_GetStatus(SPI1, SPI_I2S_BUSY_FLAG) == SET);
- GPIO_ResetBits(GPIOA, GPIO_PIN_6);
- SPI_I2S_TransmitData(SPI1, data);
- }
-
复制代码
写数据
- static void LCD_SendData(uint8_t data)
- {
- while (SPI_I2S_GetStatus(SPI1, SPI_I2S_BUSY_FLAG) == SET);
- GPIO_SetBits(GPIOA, GPIO_PIN_6);
- SPI_I2S_TransmitData(SPI1, data);
- }
复制代码
初始化
初始化这里需要注意一点,实际应该是以CS拉低作为一次通讯的开始的,但是板子没有引出CS,CS默认都是使能的,所以必须PA5先初始化为IO输出高,然后复位。复位之后再初始化PA5为SPI1_CLK,设置CLK空闲低,也就是在复位之后CLK由高到低表示通讯开始。这是由于硬件设计导致的一点特殊处理,最好还是CS引出更可靠,否则一旦通讯有一点错误,就可能导致后面完全混乱识别不到新的通讯开始,必须重新复位处理。 刷屏测试
- void LCD_Fill(uint16_t color)
- {
- uint16_t x,y;
- LCD_SendCmd(0x2a); //Column address set
- LCD_SendData(0x00); //start column
- LCD_SendData(0x00);
- LCD_SendData(0x00); //end column
- LCD_SendData(0xF0);
-
- LCD_SendCmd(0x2b); //Row address set
- LCD_SendData(0x00); //start row
- LCD_SendData(0x00);
- LCD_SendData(0x00); //end row
- LCD_SendData(0xF0);
- LCD_SendCmd(0x2C); //Memory write
- for(x=0; x
- {
- for(y=0; y
- {
- LCD_SendData(color>>8);
- LCD_SendData(color);
- }
- }
- }
复制代码
总结 本篇完成了基于SPI接口的LCD驱动实现,进行刷屏测试可以看到速度还可以,后面就可以进行LVGL移植了。
|