BearPi上和正点原子的潘多拉开发板上一样,安装了一个1.3寸,分辨率240*240,色彩深度16bit 的SPI通信接口的TFTLCD液晶彩屏,其驱动芯片为ST7789V2,且连接方式都一样采用4线SPI,如下所示,左边是BearPi,右边是atk-pandora的连接图。
打开board.h
文件,找到SPI
的配置处,按照其提示配置:
首先,打开【RT-Thread Settings】,找到SPI设备驱动程序,将其选中,然后保存使之生效
通过查看原理图,可以知道,其连接到的引脚如下所示:
LCD引脚 | MCU引脚 |
---|---|
SPI2_MPSI | PC3 |
SPI2_SCK | PB13 |
LCD_WR_RS | PC6 |
LCD_EESET | PC7 |
LCD_POWER | PB15 |
将board.h的SPI2
的注释打开,
接下来使用CubeMx生成HAL_SPI_MspInit()函数,将SPI以及LCD需要的控制引脚设置为如图所示:
将HAL_SPI_MspInit()
复制到board.c里
void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(spiHandle->Instance==SPI2)
{
/* USER CODE BEGIN SPI2_MspInit 0 */
/* USER CODE END SPI2_MspInit 0 */
/* SPI2 clock enable */
__HAL_RCC_SPI2_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/**SPI2 GPIO Configuration
PC3 ------> SPI2_MOSI
PB13 ------> SPI2_SCK
*/
GPIO_InitStruct.Pin = GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_13;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* USER CODE BEGIN SPI2_MspInit 1 */
/* USER CODE END SPI2_MspInit 1 */
}
}
然后打开stm32xxxx_hal_config.h
文件,将#define HAL_SPI_MODULE_ENABLED
的注释去掉:
然后编译下载运行,在msh下输入list_device
,可以看到,spi2已经注册上去了
在packages
文件夹下新建lcd_st7789v2
文件夹,并将并将潘多拉开发板IoT_Board
的drv_lcd.c
、drv_lcd.h
、drv_lcd_font.h
三个文件放入其中,获取方式为:从 Github 获取 或 从 Gitee 获取。
然后我们需要对drv_lcd.c
做一些修改,首先,去掉gpio.h
头文件:
然后修改LCD_PWR_PIN
,LCD_DC_PIN
,LCD_RES_PIN
引脚定义:
#define LCD_PWR_PIN GET_PIN(B, 15)
#define LCD_DC_PIN GET_PIN(C, 6)
#define LCD_RES_PIN GET_PIN(C, 7)
接下来,在rt_hw_lcd_config()
函数修改两行代码,添加一行代码:
spi_dev_lcd = (struct rt_spi_device *)rt_device_find("spi20"); //修改
cfg.mode = RT_SPI_MASTER | RT_SPI_MODE_2 | RT_SPI_MSB; //修改
spi_dev_lcd->bus->owner = spi_dev_lcd; //添加
然后,我们对rt_hw_lcd_init()
需要做比较大的修改,就直接贴上修改完成的代码:
static int rt_hw_lcd_init(void)
{
rt_hw_spi_device_attach("spi2", "spi20", GPIOC, GPIO_PIN_13);
lcd_gpio_init();
rt_thread_mdelay(50);
rt_pin_write(LCD_PWR_PIN, PIN_LOW);
rt_pin_write(LCD_RES_PIN, PIN_LOW);
rt_thread_mdelay(12);
rt_pin_write(LCD_RES_PIN, PIN_HIGH);
rt_pin_write(LCD_PWR_PIN, PIN_LOW);
rt_pin_write(LCD_RES_PIN, PIN_LOW);
rt_thread_mdelay(12);
rt_pin_write(LCD_RES_PIN, PIN_HIGH);
rt_thread_mdelay(12);
/* Sleep Out */
lcd_write_cmd(0x11);
/* wait for power stability */
rt_thread_mdelay(12);
/* Memory Data Access Control */
lcd_write_cmd(0x36);
lcd_write_data(0x00);
/* RGB 5-6-5-bit */
lcd_write_cmd(0x3A);
lcd_write_data(0x65);
/* Porch Setting */
lcd_write_cmd(0xB2);
lcd_write_data(0x0C);
lcd_write_data(0x0C);
lcd_write_data(0x00);
lcd_write_data(0x33);
lcd_write_data(0x33);
/* Gate Control */
lcd_write_cmd(0xB7);
lcd_write_data(0x72);
/* VCOM Setting */
lcd_write_cmd(0xBB);
lcd_write_data(0x3D);
/* LCM Control */
lcd_write_cmd(0xC0);
lcd_write_data(0x2C);
/* VDV and VRH Command Enable */
lcd_write_cmd(0xC2);
lcd_write_data(0x01);
/* VRH Set */
lcd_write_cmd(0xC3);
lcd_write_data(0x19);
/* VDV Set */
lcd_write_cmd(0xC4);
lcd_write_data(0x20);
/* Frame Rate Control in Normal Mode */
lcd_write_cmd(0xC6);
lcd_write_data(0x0F);
/* Power Control 1 */
lcd_write_cmd(0xD0);
lcd_write_data(0xA4);
lcd_write_data(0xA1);
/* Positive Voltage Gamma Control */
lcd_write_cmd(0xE0);
lcd_write_data(0xD0);
lcd_write_data(0x04);
lcd_write_data(0x0D);
lcd_write_data(0x11);
lcd_write_data(0x13);
lcd_write_data(0x2B);
lcd_write_data(0x3F);
lcd_write_data(0x54);
lcd_write_data(0x4C);
lcd_write_data(0x18);
lcd_write_data(0x0D);
lcd_write_data(0x0B);
lcd_write_data(0x1F);
lcd_write_data(0x23);
/* Negative Voltage Gamma Control */
lcd_write_cmd(0xE1);
lcd_write_data(0xD0);
lcd_write_data(0x04);
lcd_write_data(0x0C);
lcd_write_data(0x11);
lcd_write_data(0x13);
lcd_write_data(0x2C);
lcd_write_data(0x3F);
lcd_write_data(0x44);
lcd_write_data(0x51);
lcd_write_data(0x2F);
lcd_write_data(0x1F);
lcd_write_data(0x1F);
lcd_write_data(0x20);
lcd_write_data(0x23);
/* Display Inversion On */
lcd_write_cmd(0x21);
lcd_write_cmd(0x29);
lcd_address_set(0, 0, 240 - 1, 240 - 1);
lcd_clear(WHITE);
/* display on */
rt_pin_write(LCD_PWR_PIN, PIN_HIGH);
return RT_EOK;
}
INIT_COMPONENT_EXPORT(rt_hw_lcd_init);
接下来添加头文件,在工具设置配置页,点击GNU ARM Cross C Compiler
下的Includes
配置项即可打开头文件路径配置参数,点击Inlucde paths(-I)
配置栏的添加按钮即将’lcd_st7789v2`目录添加进来,如下图所示:
在main.c里添加头文件,
#include "drv_lcd.h"
然后测试几个函数:
/* 设置背景色和前景色 */
lcd_set_color(WHITE, BLACK);
/* 在 LCD 上显示字符 */
lcd_show_string(10, 60, 32, "Hello!");
lcd_show_string(10, 100, 32, "RT-Thread");
/* 在 LCD 上画线 */
lcd_draw_line(0, 69+16+24+32, 240, 69+16+24+32);
/* 在 LCD 上画一个同心圆 */
lcd_draw_point(120, 194);
for (int i = 0; i < 46; i += 4)
{
lcd_draw_circle(120, 194, i);
}
编译下载运行,可以看到: