[活动专区] 【AT-START-F405测评】SPI LCD 驱动移植

[复制链接]
6447|4
 楼主| [鑫森淼焱垚] 发表于 2024-5-5 16:26 | 显示全部楼层 |阅读模式
本帖最后由 [鑫森淼焱垚] 于 2024-5-5 16:26 编辑

SPI LCD 简介
此款显示屏是从某宝购买的,型号是 MSP3223,是一款3.2寸IPS彩色液晶显示模块,支持电容触摸。显示模块采用4线制SPI接口,只需要5个IO即可显示显示,240x320标清分辨率,可应用于各种需要屏显功能的产品。

1258866373df8eb782.png

液晶屏参数

4672366373e3563b31.png

引脚确定

开发板上J7接口有 SPI 管脚,查阅原理图 AT_START_F405_V1.0_SCH.pdf,确定其引脚标号。

这里只关注以下3个管脚,将在 AT32 WorkBench 中进行配置。


  • PB13, SCK
  • PC2, MISO
  • PC3, MOSI


6748466373e641e15c.png

对比 SPI LCD 的管脚,最终确定显示屏和开发板的连接关系如下表所示:

3159066373e9948d3c.png



WorkBench 创建工程
选择 MCU

双击 AT32_Work_Bench.exe 打开软件,开始一个新设计,按照下图设置 MCU 系列为 AT32F405,MCU 型号为 AT32F405RCT7-7

6446266373f27128a3.png

SPI2 配置参数

选择 Pin布局和配置,依次点击 外设 --> SPI --> SPI2

配置 SPI2 功能为 主机双线单向全双工模式,关闭硬件CS信号

SPI 参数配置如下图所示,Motorola 模式8bit模式MSB优先传输时钟分频系数为3时钟极性为高电平时钟相位为第二个边沿进行数据捕获CRC校验关闭CS信号类型为软件CS


6866966373f7c0c1fd.png

SPI2 GPIO配置
按照下图配置 SPI2 的 GPIO,并且修改了用户标签。对应右侧的红框中的3个管脚。

  • LCD_SCK 为 PB13
  • LCD_MOSI 为 PC3
  • LCD_MISO 为 PC2



7623466373fa53afc2.png
SPI2 时钟配置
在时钟配置界面找到 apb1 展开即可看到 SPI2 挂在 APB1 上。当前把 apb1div 设置为4分频,即 SPI2 时钟源为 54MHz。
8021466373fde5c563.png

再回到 SPI2 模式和配置中,其时钟参数配置分频系数为3,即SCK时钟只有 54MHz/3=18MHz 对应上了。

7252366373ff947ddb.png

LCD的控制管脚

SPI LCD除了SPI收发数据,还需要额外的管脚控制时序,例如

  • LCD_CS,用一个管脚用作 SPI 片选 -- PC5 管脚;
  • LCD_RST,用一个管脚控制 LCD 复位 -- PB1 管脚;
  • LCD_RS,用一个管脚选择 data/cmd -- PB10 管脚;


这三个管脚的配置如下图所示。

987646637401ab80b1.png

USART1 配置参数

为了重定向 printf() 函数,查看打印日志,这里配置 USART1,配置为异步模式,关闭硬件流控。

串口常用配置选项为:926100, 8bit 数据,无奇偶校验,1个停止位。

690706637403820fe3.png

USART1 配置GPIO

67736637404297938.png

生成代码

配置完成后,选择菜单栏 生成代码,然后配置项目。

设置项目名称为 AT32F405-LCD

项目位置,根据需要设置到合适的目录。

工具链,这里选择 MDK_V5.

勾选重新生成代码时保留用户代码

5719866374071e1b4f.png

WorkBench 安装固件包
如果是第一次生成代码,可能固件包没有安装。点击右侧的固件包管理

33837663740a5f32b5.png

点击从本地安装,浏览固件库,直接选择 zip 文件即可。
49265663740e7e801a.png

25095663740f3c3a78.png

等待固件包安装成功,之后就可以愉快地使用 WorkBench 创建初始化代码。

14666663740dd872d9.png
关键代码

主流程
AT32 WorkBench 自动创建的初始化代码以 wk_ 开头,如下图中的 wk_usart1_init() , wk_spi2_init() 和 wk_gpio_config() 等函数。

这个先初始化了时钟,USART1 和 SPI2 外设,并配置了管脚,然后调用 LCD_Init() 初始化 LCD 显示屏。

由于我移植了AT32固件库中的 FreeRTOS,所以在 init_tasks() 中创建 LCD 应用程序。


808856637419baa29b.png

SPI2 初始化
此代码由 WorkBench 生成,配置了 SCK, MOSI, MISO 三个 GPIO 为复用模式,并配置 SPI2 参数。

  1. /**
  2.   * [url=home.php?mod=space&uid=247401]@brief[/url]  init spi2 function
  3.   * @param  none
  4.   * @retval none
  5.   */
  6. void wk_spi2_init(void)
  7. {
  8.   /* add user code begin spi2_init 0 */

  9.   /* add user code end spi2_init 0 */

  10.   gpio_init_type gpio_init_struct;
  11.   spi_init_type spi_init_struct;

  12.   gpio_default_para_init(&gpio_init_struct);
  13.   spi_default_para_init(&spi_init_struct);

  14.   /* add user code begin spi2_init 1 */

  15.   /* add user code end spi2_init 1 */

  16.   /* configure the SCK pin */
  17.   gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
  18.   gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
  19.   gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
  20.   gpio_init_struct.gpio_pins = LCD_SCK_PIN;
  21.   gpio_init_struct.gpio_pull = GPIO_PULL_UP;
  22.   gpio_init(LCD_SCK_GPIO_PORT, &gpio_init_struct);

  23.   gpio_pin_mux_config(LCD_SCK_GPIO_PORT, GPIO_PINS_SOURCE13, GPIO_MUX_5);

  24.   /* configure the MISO pin */
  25.   gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
  26.   gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
  27.   gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
  28.   gpio_init_struct.gpio_pins = LCD_MISO_PIN;
  29.   gpio_init_struct.gpio_pull = GPIO_PULL_UP;
  30.   gpio_init(LCD_MISO_GPIO_PORT, &gpio_init_struct);

  31.   gpio_pin_mux_config(LCD_MISO_GPIO_PORT, GPIO_PINS_SOURCE2, GPIO_MUX_5);

  32.   /* configure the MOSI pin */
  33.   gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
  34.   gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
  35.   gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
  36.   gpio_init_struct.gpio_pins = LCD_MOSI_PIN;
  37.   gpio_init_struct.gpio_pull = GPIO_PULL_UP;
  38.   gpio_init(LCD_MOSI_GPIO_PORT, &gpio_init_struct);

  39.   gpio_pin_mux_config(LCD_MOSI_GPIO_PORT, GPIO_PINS_SOURCE3, GPIO_MUX_5);

  40.   /* configure param */
  41.   spi_init_struct.transmission_mode = SPI_TRANSMIT_FULL_DUPLEX;
  42.   spi_init_struct.master_slave_mode = SPI_MODE_MASTER;
  43.   spi_init_struct.frame_bit_num = SPI_FRAME_8BIT;
  44.   spi_init_struct.first_bit_transmission = SPI_FIRST_BIT_MSB;
  45.   spi_init_struct.mclk_freq_division = SPI_MCLK_DIV_3;
  46.   spi_init_struct.clock_polarity = SPI_CLOCK_POLARITY_HIGH;
  47.   spi_init_struct.clock_phase = SPI_CLOCK_PHASE_2EDGE;
  48.   spi_init_struct.cs_mode_selection = SPI_CS_SOFTWARE_MODE;
  49.   spi_init(SPI2, &spi_init_struct);

  50.   spi_enable(SPI2, TRUE);

  51.   /* add user code begin spi2_init 2 */

  52.   /* add user code end spi2_init 2 */
  53. }



GPIO 初始化
由于 LCD 除了 SPI2 的 MOSI, MISO 和 SCK 管脚,还需要 LCD_CS, LCD_RST LCD_RS 三个GPIO管脚用以控制命令时序。

这三个 GPIO 的初始化在 WorkBench 中单独配置,生成的代码见 wk_gpio_config()



  1. /**
  2.   * @brief  init gpio_input/gpio_output/gpio_analog/eventout function.
  3.   * @param  none
  4.   * @retval none
  5.   */
  6. void wk_gpio_config(void)
  7. {
  8.   /* add user code begin gpio_config 0 */

  9.   /* add user code end gpio_config 0 */

  10.   gpio_init_type gpio_init_struct;
  11.   gpio_default_para_init(&gpio_init_struct);

  12.   /* add user code begin gpio_config 1 */

  13.   /* add user code end gpio_config 1 */

  14.   /* gpio output config */
  15.   gpio_bits_set(LCD_CS_GPIO_PORT, LCD_CS_PIN);
  16.   gpio_bits_reset(GPIOB, LCD_RST_PIN | LCD_RS_PIN);

  17.   gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
  18.   gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
  19.   gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT;
  20.   gpio_init_struct.gpio_pins = LCD_CS_PIN;
  21.   gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
  22.   gpio_init(LCD_CS_GPIO_PORT, &gpio_init_struct);

  23.   gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
  24.   gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
  25.   gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT;
  26.   gpio_init_struct.gpio_pins = LCD_RST_PIN | LCD_RS_PIN;
  27.   gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
  28.   gpio_init(GPIOB, &gpio_init_struct);

  29.   /* add user code begin gpio_config 2 */

  30.   /* add user code end gpio_config 2 */
  31. }



LCD 初始化

调用函数 LCD_Init() 进行初始化。

这个函数有3个步骤:

  • 初始化 GPIO,即配置 LCD_CS, LCD_RST LCD_RS 三个管脚初始化。由于已经在 wk_gpio_init() 中初始化了这三个管脚,这里实现为空;
  • 调用 LCD_RESET() 函数,操作 LCD_RST 管脚,拉高50毫秒,再拉低100毫秒,再拉高50毫秒,即可以复位 LCD;
  • 最后是下发 LCD 初始化参数,这些参数由屏幕产商提供。


966786637421c269a7.png

移植结果

  • 测试程序读取 LCD Driver IC 的 ID,成功读取数值为 0x9341。
  • 在屏幕上显示7种颜色,并读取某个点的颜色值并进行比对,比对成功。



22973663742852994a.png


chenqianqian 发表于 2024-5-10 20:06 来自手机 | 显示全部楼层
现在TFT LCE屏幕真的是白菜价了
trucyw 发表于 2024-6-10 18:01 | 显示全部楼层
gouguoccc 发表于 2024-6-10 22:38 来自手机 | 显示全部楼层
SPi的通信速率还是比串口高些,所以串口屏都是由厂家开发好。
可怜的小弗朗士 发表于 2024-6-12 13:50 | 显示全部楼层
这个屏幕挺好的,开发简单
您需要登录后才可以回帖 登录 | 注册

本版积分规则

20

主题

128

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部