[应用相关] FSMC工程 ILI9325驱动LCD

[复制链接]
 楼主| sensitivity 发表于 2020-5-17 09:42 | 显示全部楼层 |阅读模式
使用STM32CubeMx创建FSMC工程,生成后使用keil5创建TFT-LCD驱动程序,实现在LCD上显示。


开发环境:
STM32F103ZET6      STM32CubeMX      Keil5

 楼主| sensitivity 发表于 2020-5-17 09:43 | 显示全部楼层
网上有一些配置FSMC的,有驱动TFT-LCD的程序,不过大多是标准库的,有一些找到的驱动程序可是试了试,没有效果,所以自己修改。
 楼主| sensitivity 发表于 2020-5-17 09:43 | 显示全部楼层
现在有四块屏,1602(显示一些数字),128604(显示字符,简单图片),2.4寸TFT液晶屏(ili9325驱动,可触摸,240*320),3.5寸TFT(hx8357驱动,可触摸),此篇只写2.4寸TFT液晶屏,基本方法是修改厂家提供的使用FSMC的驱动文件,将标准库文件修改为在HAL库中可以运行的文件,因为之前将12864的标准库程序修改为HAL库程序成功,所以可以借鉴。
 楼主| sensitivity 发表于 2020-5-17 09:44 | 显示全部楼层
 楼主| sensitivity 发表于 2020-5-17 09:45 | 显示全部楼层
722685ec0971ad83f9.png
792375ec097250521d.png
在网上使用STM32CubeMx配置FSMC的工程有一些,不过存在问题
 楼主| sensitivity 发表于 2020-5-17 09:46 | 显示全部楼层
使用STM32CubeMx配置FSMC,GPIO
FSMC介绍

1. STM32CubeMx如何配置FSMC

按照上一篇的方法创建一个工程后,在引脚设置页面的左侧有FSMC的配置,不过STM32CubeMx的版本不同,STM芯片的选择不同,FSMC配置选项也不同,

48735ec0974b46c54.png
 楼主| sensitivity 发表于 2020-5-17 09:46 | 显示全部楼层
FSMC(16位)主要配置的引脚为

      CS 液晶屏片选    NE4

      RS  即LCD Register Select  PG0  (A10)

      WR  写信号    PD5

      RD 读信号    PD4

      以及16位数据总线,高八位和第八位

不过液晶屏会有BL背光控制和RST复位引脚,需要在配置完FSMC后再添加两个输出引脚。
 楼主| sensitivity 发表于 2020-5-17 09:47 | 显示全部楼层
那么问题来了,FSMC配置中的内存类型怎么选,是选SRAM还是其他?

      我觉得选图中所示可以直接选择寄存器数据选择信号引脚为A10即PG0,这符合我的彩屏的实际情况,具体怎么选要先看一下自己彩屏正常工作时配置了那些引脚。

在配置了FSMC后再经过一些小的修改就可以生成工程,添加自己的代码。

 楼主| sensitivity 发表于 2020-5-17 09:47 | 显示全部楼层
注意:

使用不同驱动的彩屏在初始化时对寄存器的操作都是不同的,一定要找到可以在自己彩屏上正常运行的程序,因为在初始化函数中都会对很多寄存器写入不同的值,错一个可能就无法初始化成功。
 楼主| sensitivity 发表于 2020-5-17 09:48 | 显示全部楼层
使用NOR/SRAM的 Bank1.sector4,地址位HADDR[27,26]=11,A10作为数据命令区分线,注意设置时STM32内部会右移一位对其! 111110=0X3E。

因为在标准库中和HAL库中数据类型本质相同,但表示不同,比如在标准库中为u16,不过在HAL库中却是uint16_t,需要注意。

在标准库中GPIO和FSMC相关结构体具体定义是不同的,也需要修改。

 楼主| sensitivity 发表于 2020-5-17 09:51 | 显示全部楼层
基本步骤:
修改向寄存器地址写数据和命令的函数

注意是否在STM32CUBEMX中配置好时钟,时钟配置是很重要的

修改LCD的初始化函数

修改GPIO初始化函数,还要使能相关引脚时钟

注意除了FSMC相关引脚配置为复用推挽输出外,PB0和PC5需要配置为推挽输出

修改FSMC初始函数,需要使能FSMC时钟
 楼主| sensitivity 发表于 2020-5-17 09:53 | 显示全部楼层
需要注意的是在标准库中和在HAL库中FSMC的配置有不小的不同,首先是FSMC相关结构体和标准库中不同,有一些在标准库中可以配置的选项在HAL库中并不存在,还有FSMC配置完成后初始化FSMC的函数和标准库中也有很大不同,如果使用了两个FSMC_NORSRAM_TimingTypeDef,则要使用HAL_SRAM_Init()函数进行初始化。还需要注意的是要使能BANK1。

 楼主| sensitivity 发表于 2020-5-17 09:55 | 显示全部楼层
修改复位函数

还有其他一些修改,改动不大

rebuild工程,如果没有错误,在main函数中调用LCD初始化函数,就可以直接使用标准库中可以使用的绘制函数了。
 楼主| sensitivity 发表于 2020-5-17 09:55 | 显示全部楼层
修改后的GPIO初始化函数

  1. void LCD_GPIOInit(void)

  2. {

  3. GPIO_InitTypeDef GPIO_InitStruct;

  4. //FSMC_NORSRAM_InitTypeDef  FSMC_NORSRAMInitStructure;

  5. FSMC_NORSRAM_TimingTypeDef  readWriteTiming;

  6. FSMC_NORSRAM_TimingTypeDef  writeTiming;

  7. hsram2.Instance = FSMC_NORSRAM_DEVICE;

  8. hsram2.Extended = FSMC_NORSRAM_EXTENDED_DEVICE;

  9. __HAL_RCC_FSMC_CLK_ENABLE();//ʹÄÜFSMCʱÖÓ

  10. //RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC,ENABLE);        //ʹÄÜFSMCʱÖÓ

  11. __HAL_RCC_GPIOC_CLK_ENABLE();

  12. __HAL_RCC_GPIOB_CLK_ENABLE();

  13. __HAL_RCC_GPIOG_CLK_ENABLE();

  14. __HAL_RCC_GPIOE_CLK_ENABLE();

  15. __HAL_RCC_GPIOD_CLK_ENABLE();

  16. __HAL_RCC_GPIOA_CLK_ENABLE();

  17. //RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOE|RCC_APB2Periph_GPIOG|RCC_APB2Periph_AFIO,ENABLE);//ʹÄÜPORTB,D,E,GÒÔ¼°AFIO¸´Óù¦ÄÜʱÖÓ

  18. /*Configure GPIO pin : PC5 */

  19. GPIO_InitStruct.Pin = GPIO_PIN_5;

  20. GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

  21. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;

  22. HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

  23. /*Configure GPIO pin : PB0 */

  24. GPIO_InitStruct.Pin = GPIO_PIN_0;

  25. GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

  26. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;

  27. HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  28. /* GPIO_InitStruct */

  29. GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_12;

  30. GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

  31. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;

  32. HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);

  33. /* GPIO_InitStruct */

  34. GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10

  35. |GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14

  36. |GPIO_PIN_15;

  37. GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

  38. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;

  39. HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

  40. /* GPIO_InitStruct */

  41. GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_14

  42. |GPIO_PIN_15|GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_4

  43. |GPIO_PIN_5;

  44. GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

  45. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;

  46. HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

  47. readWriteTiming.AddressSetupTime = 0x01;        //µØÖ·½¨Á¢Ê±¼ä£¨ADDSET£©Îª2¸öHCLK 1/36M=27ns

  48. readWriteTiming.AddressHoldTime = 0x00;        //µØÖ·±£³Öʱ¼ä£¨ADDHLD£©Ä£Ê½AδÓõ½

  49. readWriteTiming.DataSetupTime = 0x0f;        // Êý¾Ý±£´æÊ±¼äΪ16¸öHCLK,ÒòΪҺ¾§Çý¶¯ICµÄ¶ÁÊý¾ÝµÄʱºò£¬ËٶȲ»ÄÜÌ«¿ì£¬ÓÈÆä¶Ô1289Õâ¸öIC¡£

  50. readWriteTiming.BusTurnAroundDuration = 0x00;

  51. readWriteTiming.CLKDivision = 0x00;

  52. readWriteTiming.DataLatency = 0x00;

  53. readWriteTiming.AccessMode = FSMC_ACCESS_MODE_A;        //ģʽA

  54. writeTiming.AddressSetupTime = 0x02;        //0x01 µØÖ·½¨Á¢Ê±¼ä£¨ADDSET£©Îª1¸öHCLK

  55. writeTiming.AddressHoldTime = 0x00;        //µØÖ·±£³Öʱ¼ä£¨A

  56. writeTiming.DataSetupTime = 0x05;        ////0x03 Êý¾Ý±£´æÊ±¼äΪ4¸öHCLK

  57. writeTiming.BusTurnAroundDuration = 0x00;

  58. writeTiming.CLKDivision = 0x00;

  59. writeTiming.DataLatency = 0x00;

  60. writeTiming.AccessMode = FSMC_ACCESS_MODE_A;        //ģʽA

  61. hsram2.Init.NSBank = FSMC_NORSRAM_BANK4;//  ÕâÀïÎÒÃÇʹÓÃNE4 £¬Ò²¾Í¶ÔÓ¦BTCR[6],[7]¡£

  62. hsram2.Init.DataAddressMux = FSMC_DATA_ADDRESS_MUX_DISABLE; // ²»¸´ÓÃÊý¾ÝµØÖ·

  63. hsram2.Init.MemoryType =FSMC_MEMORY_TYPE_SRAM;// FSMC_MemoryType_SRAM;  //SRAM

  64. hsram2.Init.MemoryDataWidth = FSMC_NORSRAM_MEM_BUS_WIDTH_16;//´æ´¢Æ÷Êý¾Ý¿í¶ÈΪ16bit

  65. hsram2.Init.BurstAccessMode =FSMC_BURST_ACCESS_MODE_DISABLE;// FSMC_BurstAccessMode_Disable;

  66. hsram2.Init.WaitSignalPolarity = FSMC_WAIT_SIGNAL_POLARITY_LOW;

  67. hsram2.Init.AsynchronousWait=FSMC_ASYNCHRONOUS_WAIT_DISABLE;

  68. hsram2.Init.WrapMode = FSMC_WRAP_MODE_DISABLE;

  69. hsram2.Init.WaitSignalActive = FSMC_WAIT_TIMING_BEFORE_WS;

  70. hsram2.Init.WriteOperation = FSMC_WRITE_OPERATION_ENABLE;        //  ´æ´¢Æ÷дʹÄÜ

  71. hsram2.Init.WaitSignal = FSMC_WAIT_SIGNAL_DISABLE;

  72. hsram2.Init.ExtendedMode = FSMC_EXTENDED_MODE_ENABLE; // ¶ÁдʹÓò»Í¬µÄʱÐò

  73. hsram2.Init.WriteBurst = FSMC_WRITE_BURST_DISABLE;

  74. //FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &readWriteTiming; //¶ÁдʱÐò

  75. //FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &writeTiming;  //дʱÐò

  76. if (HAL_SRAM_Init(&hsram2, &readWriteTiming, &writeTiming) != HAL_OK)

  77. {

  78. _Error_Handler(__FILE__, __LINE__);

  79. }

  80. __FSMC_NORSRAM_ENABLE(FSMC_NORSRAM_DEVICE,FSMC_NORSRAM_BANK4);

  81. }
 楼主| sensitivity 发表于 2020-5-17 09:56 | 显示全部楼层
修改后的LCD初始化函数

  1. void LCD_Init(void)

  2. {

  3. LCD_GPIOInit();

  4. LCD_RESET();

  5. //************* Start Initial Sequence **********//

  6. LCD_WriteReg(0x00E5,0x78F0);

  7. LCD_WriteReg(0x0001,0x0100);

  8. LCD_WriteReg(0x0002,0x0700);

  9. LCD_WriteReg(0x0003,0x1030);

  10. LCD_WriteReg(0x0004,0x0000);

  11. LCD_WriteReg(0x0008,0x0202);

  12. LCD_WriteReg(0x0009,0x0000);

  13. LCD_WriteReg(0x000A,0x0000);

  14. LCD_WriteReg(0x000C,0x0000);

  15. LCD_WriteReg(0x000D,0x0000);

  16. LCD_WriteReg(0x000F,0x0000);

  17. //power on sequence VGHVGL

  18. LCD_WriteReg(0x0010,0x0000);

  19. LCD_WriteReg(0x0011,0x0007);

  20. LCD_WriteReg(0x0012,0x0000);

  21. LCD_WriteReg(0x0013,0x0000);

  22. LCD_WriteReg(0x0007,0x0000);

  23. //vgh

  24. LCD_WriteReg(0x0010,0x1690);

  25. LCD_WriteReg(0x0011,0x0227);

  26. //delay_ms(100);

  27. //vregiout

  28. LCD_WriteReg(0x0012,0x009D); //0x001b

  29. //delay_ms(100);

  30. //vom amplitude

  31. LCD_WriteReg(0x0013,0x1900);

  32. //delay_ms(100);

  33. //vom H

  34. LCD_WriteReg(0x0029,0x0025);

  35. LCD_WriteReg(0x002B,0x000D);

  36. //gamma

  37. LCD_WriteReg(0x0030,0x0007);

  38. LCD_WriteReg(0x0031,0x0303);

  39. LCD_WriteReg(0x0032,0x0003);// 0006

  40. LCD_WriteReg(0x0035,0x0206);

  41. LCD_WriteReg(0x0036,0x0008);

  42. LCD_WriteReg(0x0037,0x0406);

  43. LCD_WriteReg(0x0038,0x0304);//0200

  44. LCD_WriteReg(0x0039,0x0007);

  45. LCD_WriteReg(0x003C,0x0602);// 0504

  46. LCD_WriteReg(0x003D,0x0008);

  47. //ram

  48. LCD_WriteReg(0x0050,0x0000);

  49. LCD_WriteReg(0x0051,0x00EF);

  50. LCD_WriteReg(0x0052,0x0000);

  51. LCD_WriteReg(0x0053,0x013F);

  52. LCD_WriteReg(0x0060,0xA700);

  53. LCD_WriteReg(0x0061,0x0001);

  54. LCD_WriteReg(0x006A,0x0000);

  55. //

  56. LCD_WriteReg(0x0080,0x0000);

  57. LCD_WriteReg(0x0081,0x0000);

  58. LCD_WriteReg(0x0082,0x0000);

  59. LCD_WriteReg(0x0083,0x0000);

  60. LCD_WriteReg(0x0084,0x0000);

  61. LCD_WriteReg(0x0085,0x0000);

  62. //

  63. LCD_WriteReg(0x0090,0x0010);

  64. LCD_WriteReg(0x0092,0x0600);

  65. LCD_WriteReg(0x0007,0x0133);

  66. LCD_WriteReg(0x00,0x0022);//

  67. LCD_SetParam();//ÉèÖÃLCD²ÎÊý

  68. //LCD_LED=1;//µãÁÁ±³¹â

  69. HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET);

  70. LCD_Clear(WHITE);

  71. }
 楼主| sensitivity 发表于 2020-5-17 09:57 | 显示全部楼层
修改后在main函数中使用绘图函数时要注释掉原有的GPIO和FSMC初始化函数。

测试结果:
124745ec099da2ae26.png
728455ec09a0a08201.png
 楼主| sensitivity 发表于 2020-5-17 09:58 | 显示全部楼层
修改后即可以在STM32CubeMX中配置后就可以将之前修改好的文件直接添加到工程中使用,这样即可在LCD上显示其他功能的状态信息。
 楼主| sensitivity 发表于 2020-5-17 09:59 | 显示全部楼层

作者:停下浮躁的心
链接:https://www.jianshu.com/p/ab082c9290f7
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
wowu 发表于 2020-6-4 16:51 | 显示全部楼层
非常感谢楼主分享
xiaoqizi 发表于 2020-6-4 16:51 | 显示全部楼层
屏幕是串口屏吗
您需要登录后才可以回帖 登录 | 注册

本版积分规则

9

主题

216

帖子

0

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