关于STMCubeMx生成FSMC驱动,把相关配置参数贴上来。
1.pinout配置。LCD register select A0,是选择FSMC地址线A0作为SSD1963 寄存器/数据选择位(RS)。
2.时钟配置。
3.FSMC配置。
操作SSD1963实际上只操作两个16位大小的地址,一个当做命令寄存器来操作,一个当做数据缓存来操作。
(地址线A0为1时是写数据操作,A0为0时是写命令操作)
例如:
/* USER CODE BEGIN 0 */
#define LCD_REG (volatile uint16_t *)(0x6c000000)
#define LCD_RAM (volatile uint16_t *)(0x6c000002)
void LCD_WREG(uint16_t command)
{
*LCD_REG = command;
}
void LCD_WRAM(uint16_t data)
{
*LCD_RAM = data ;
}
相关概念:前廊,后廊
显示器的一帧由若干横行组成,比如AT043TN25是800*272的屏就是有272个横行。SSD1963上的驱动信号比272多几个,多的就是FP(前廊) 和BP(后廊)。
这两段时间内,显示数据是不会刷新到屏上的。
main.c中的一段代码如下:
#define SSD_HOR_RESOLUTION 800 //水平像素
#define SSD_VER_RESOLUTION 272 //垂直像素
#define SSD_HOR_BACK_PORCH 46 //水平后廊
#define SSD_HOR_FRONT_PORCH 210 //水平前廊
#define SSD_VER_BACK_PORCH 23 //垂直后廊
#define SSD_VER_FRONT_PORCH 22 //垂直前廊
#define SSD_HT (SSD_HOR_RESOLUTION+SSD_HOR_BACK_PORCH+SSD_HOR_FRONT_PORCH)//显示+不显示
#define SSD_HPS (SSD_HOR_BACK_PORCH) //不显示
#define SSD_VT (SSD_VER_RESOLUTION+SSD_VER_BACK_PORCH+SSD_VER_FRONT_PORCH)//显示+不显示
#define SSD_VPS (SSD_VER_BACK_PORCH) //不显示
篇幅限制,部分main.c如下:
- /* USER CODE BEGIN 0 */
- #define LCD_REG (volatile uint16_t *)(0x6c000000)
- #define LCD_RAM (volatile uint16_t *)(0x6c000002)
- //LCD·Ö±æÂÊÉèÖÃ
- #define SSD_HOR_RESOLUTION 800 //LCDˮƽ·Ö±æÂÊ
- #define SSD_VER_RESOLUTION 272 //LCD´¹Ö±·Ö±æÂÊ
- #define SSD_HOR_PULSE_WIDTH 1 //ˮƽÂö¿í
- #define SSD_HOR_BACK_PORCH 46 //ˮƽǰÀÈ
- #define SSD_HOR_FRONT_PORCH 210 //ˮƽºóÀÈ
- #define SSD_VER_PULSE_WIDTH 1 //´¹Ö±Âö¿í
- #define SSD_VER_BACK_PORCH 23 //´¹Ö±Ç°ÀÈ
- #define SSD_VER_FRONT_PORCH 22 //´¹Ö±Ç°ÀÈ
- #define SSD_HT (SSD_HOR_RESOLUTION+SSD_HOR_BACK_PORCH+SSD_HOR_FRONT_PORCH)//×ܵÄÖÜÆÚÊý£¬ÏÔʾµÄ+²»ÏÔʾµÄ
- #define SSD_HPS (SSD_HOR_BACK_PORCH) //²»ÏÔʾµÄ
- #define SSD_VT (SSD_VER_RESOLUTION+SSD_VER_BACK_PORCH+SSD_VER_FRONT_PORCH)//×ܵÄÖÜÆÚÊý£¬ÏÔʾµÄ+²»ÏÔʾµÄ
- #define SSD_VPS (SSD_VER_BACK_PORCH) //²»ÏÔʾµÄ
- //LCDÖØÒª²ÎÊý¼¯
- typedef struct
- {
- uint16_t width; //LCD ¿í¶È
- uint16_t height; //LCD ¸ß¶È
- uint16_t ID;
- uint8_t dir; //ºáÆÁ»¹ÊÇÊúÆÁ¿ØÖÆ£º0£¬ÊúÆÁ£»1£¬ºáÆÁ¡£
- uint16_t wramcmd; //¿ªÊ¼Ð´gramÖ¸Áî
- uint16_t setxcmd; //ÉèÖÃx×ø±êÖ¸Áî
- uint16_t setycmd; //ÉèÖÃy×ø±êÖ¸Áî
- } _lcd_dev;
- //LCD²ÎÊý
- _lcd_dev lcddev; //¹ÜÀíLCDÖØÒª²ÎÊý
- uint16_t result;
- uint32_t i ;
- uint16_t color=0,pan=0;
- void LCD_WREG(uint16_t command)
- {
- *LCD_REG = command;
- }
- void LCD_WRAM(uint16_t data)
- {
- *LCD_RAM = data ;
- }
- uint16_t LCD_RRAM(void)
- {
- uint16_t data;
- data = *LCD_RAM;
- return(data);
- }
- uint16_t LCD_Read_REG(uint16_t reg)
- {
- uint16_t ram;
- LCD_WREG(reg);
- HAL_Delay(1);
- ram = LCD_RRAM();
- return(ram);
- }
- void SSD1963_43_Init(void)
- {
- HAL_Delay(1);
- LCD_WREG(0XA1);
- result = LCD_RRAM();
- result = LCD_RRAM(); //¶Á»Ø0X57
- result <<= 8;
- result |= LCD_RRAM(); //¶Á»Ø0X61
- if(result == 0x5761)
- result = 0x1963;
- printf("ID = %x\n", result);
- /*
- set_pll_mn
- Command 0xE2
- Parameters 3
- D/C D7 D6 D5 D4 D3 D2 D1 D0 Hex
- Command 0 1 1 1 0 0 0 1 0 E2
- Parameter 1 1 M7 M6 M5 M4 M3 M2 M1 M0 xx
- Parameter 2 1 0 0 0 0 N3 N2 N1 N0 xx
- Parameter 3 1 0 0 0 0 0 C2 0 0 xx
- Description
- Set the MN of PLL
- M[7:0] : Multiplier (M) of PLL. (POR = 00101101)
- N[3:0] : Divider (N) of PLL. (POR = 0011)
- C[2] : Effectuate MN value (POR = 0)
- 0 Ignore the multiplier (N) and divider (N) values
- 1 Effectuate the multiplier and divider value
- VCO = Reference input clock x (M + 1)
- PLL frequency = VCO / (N + 1)
- * Note : 250MHz < VCO < 800MHz
- For a 10MHz reference clock to obtain 100MHz PLL frequency, user cannot program M = 19 and N = 1. The setting in
- this situation is setting M=29 and N=2, where 10 x 30 / 3 = 100MHz.
- */
- LCD_WREG(0xE2); //Set PLL with OSC = 10MHz (hardware), Multiplier N = 35, 250MHz < VCO < 800MHz = OSC*(N+1), VCO = 300MHz
- LCD_WRAM(0x1D); //²ÎÊý1 M=29
- LCD_WRAM(0x02); //²ÎÊý2 N=2
- LCD_WRAM(0x04); //²ÎÊý3 Ó¦ÓòÎÊý
- printf("PLL frequency= 100M\n");
- HAL_Delay(1);
- /*
- set_pll
- Command 0xE0
- Parameters 1
- D/C D7 D6 D5 D4 D3 D2 D1 D0 Hex
- Command 0 1 1 1 0 0 0 0 0 E0
- Parameter 1 1 0 0 0 0 0 0 A1 A0 xx
- Description
- Start the PLL. Before the start, the system was operated with the crystal oscillator or clock input.
- A[1] : Lock PLL (POR = 0)
- After PLL enabled for 100us, can start to lock PLL
- 0 Use reference clock as system clock
- 1 Use PLL output as system clock
- A[0] : Enable PLL (POR = 0)
- 0 Disable PLL
- 1 Enable PLL
- Before enabling PLL, the PLL setting (“0xE2”) have to be configured first. After PLL enabled for 100us, can start to
- lock PLL. SSD1963 needed to switch to PLL output as system clock after PLL is locked. The following is the program
- sequence.
- WRITE COMMAND “0xE0”
- WRITE DATA “0x01”
- Wait 100us to let the PLL stable
- WRITE COMMAND “0xE0”
- WRITE DATA “0x03”
- WRITE COMMAND “0x01”
- * Note : SSD1963 is operating under reference clock before PLL is locked, registers cannot be set faster than half of the
- reference clock frequency. For instance, SSD1963 with a 10MHz reference clock is not allowed to be programmed
- higher than 5M words/s.
- */
- LCD_WREG(0xE0); // Start PLL command
- LCD_WRAM(0x01); // enable PLL
- HAL_Delay(1);
- LCD_WREG(0xE0); // Start PLL command again
- LCD_WRAM(0x03); // now, use PLL output as system clock
- HAL_Delay(1);
- LCD_WREG(0x01); //Èí¸´Î»
- HAL_Delay(1);
- /*
- set_lshift_freq
- Command 0xE6
- Parameters 3
- D/C D7 D6 D5 D4 D3 D2 D1 D0 Hex
- Command 0 1 1 1 0 0 1 1 0 E6
- Parameter 1 1 0 0 0 0 LCDC_FPR19 LCDC_FPR18 LCDC_FPR17 LCDC_FPR16 xx
- Parameter 2 1 LCDC_FPR15 LCDC_FPR14 LCDC_FPR13 LCDC_FPR12 LCDC_FPR11 LCDC_FPR10 LCDC_FPR9 LCDC_FPR8 xx
- Parameter 3 1 LCDC_FPR7 LCDC_FPR6 LCDC_FPR 5 LCDC_FPR4 LCDC_FPR 3 LCDC_FPR2 LCDC_FPR1 LCDC_FPR0 xx
- Description
- Set the LSHIFT (pixel clock) frequency
- LCDC_FPR[19:16] : The highest 4 bits for the pixel clock frequency settings. (POR = 0111)
- LCDC_FPR[15:8] : The higher byte for the pixel clock frequency settings. (POR = 11111111)
- LCDC_FPR[7:0] : The low byte for the pixel clock frequency settings. (POR = 11111111)
- For parallel LCD interface:
- Configure the pixel clock to PLL freq x ((LCDC_FPR + 1) / 1048576)
- To obtain PCLK = 5.3MHz with PLL Frequency = 100MHz,
- 5.3MHz = 100MHz * ( LCDC_FPR+ 1) / 1048576
- LCDC_FPR = 55574
- WRITE COMMAND “0xE6”
- WRITE DATA “0x00” (LCDC_FPR = 55574)
- WRITE DATA “0xD9”
- WRITE DATA “0x16”
- For serial LCD interface:
- Configure the pixel clock to PLL freq x ((LCDC_FPR + 1) / 1048576) *4
- To obtain PCLK = 5.3MHz with PLL Frequency = 100MHz,
- 5.3MHz = 100MHz * ( ( LCDC_FPR+ 1) / 1048576 )*4
- LCDC_FPR = 13892
- WRITE COMMAND “0xE6”
- WRITE DATA “0x00” (LCDC_FPR = 13892)
- WRITE DATA “0x36”
- WRITE DATA “0x44”
- */
- LCD_WREG(0xE6); //ÉèÖÃÏñËØÆµÂÊ,300Mhz
- LCD_WRAM(0x2F);
- LCD_WRAM(0xFF);
- LCD_WRAM(0xFF);
- /*
- set_lcd_mode
- Command 0xB0
- Parameters 7
- D/C D7 D6 D5 D4 D3 D2 D1 D0 Hex
- Command 0 1 0 1 1 0 0 0 0 B0
- Parameter 1 1 0 0 A5 A4 A3 A2 A1 A0 xx
- Parameter 2 1 0 B6 B5 0 0 0 0 0 xx
- Parameter 3 1 0 0 0 0 0 HDP10 HDP9 HDP8 xx
- Parameter 4 1 HDP7 HDP6 HDP5 HDP4 HDP3 HDP2 HDP1 HDP0 xx
- Parameter 5 1 0 0 0 0 0 VDP10 VDP9 VDP8 xx
- Parameter 6 1 VDP7 VDP6 VDP5 VDP4 VDP3 VDP2 VDP1 VDP0 xx
- Parameter 7 1 0 0 G5 G4 G3 G2 G1 G0 xx
- Description
- Set the LCD panel mode and resolution
- A[5] : TFT panel data width (POR = 0)
- 0 18-bit
- 1 24-bit
- A[4] : TFT color depth enhancement enable (POR = 0)
- 0 Disable FRC or dithering
- 1 Enable FRC or dithering for color depth enhancement
- If the panel data width was set to 24-bit,
- FRC and dithering feature will be disabled automatic regardless the value of this register.
- A[3] : TFT FRC enable (POR = 0)
- 0 TFT dithering enable
- 1 TFT FRC enableSSD1963 Rev 1.1 P 45/93 Jan 2010 Solomon Systech
- A[5] A[4] A[3] TFT FRC TFT dithering
- 0 0 X Disable Disable
- 0 1 0 Disable Enable
- 0 1 1 Enable Disable
- 1 X X Disable Disable
- A[2] : LSHIFT polarity (POR = 0)
- Set the dot clock pulse polarity.
- 0 Data latch in falling edge
- 1 Data latch in rising edge
- A[1] : LLINE polarity (POR = 0)
- Set the horizontal sync pulse polarity.
- 0 Active low
- 1 Active high
- A[0] : LFRAME polarity (POR = 0)
- Set the vertical sync pulse polarity.
- 0 Active low
- 1 Active high
- B[6:5] : TFT type (POR = 01)
- 00, 01 TFT mode
- 10 Serial RGB mode
- 11 Serial RGB+dummy mode
- HDP [10:8] : High byte of the horizontal panel size (POR = 010)
- HDP [7:0] : Low byte of the horizontal panel size (POR = 01111111)
- Horizontal panel size = (HDP + 1) pixels
- VDP [10:8] : High byte of the vertical panel size (POR = 001)
- VDP [7:0] : Low byte of the vertical panel size (POR = 11011111)
- Vertical panel size = (VDP + 1) lines
- G[5:3] : Even line RGB sequence for serial TFT interface (POR = 000)
- 000 RGB
- 001 RBG
- 010 GRB
- 011 GBR
- 100 BRG
- 101 BGR
- 11x Reserved
- G[2:0] : Odd line RGB sequence for serial TFT interface (POR = 000)
- 000 RGB
- 001 RBG
- 010 GRB
- 011 GBR
- 100 BRG
- 101 BGR
- 11x Reserved
- */
- LCD_WREG(0xB0); //ÉèÖÃLCDģʽ
- LCD_WRAM(0x20); //24λģʽ
- LCD_WRAM(0x00); //TFT ģʽ
- LCD_WRAM((SSD_HOR_RESOLUTION - 1) >> 8); //ÉèÖÃLCDˮƽÏñËØ
- LCD_WRAM(SSD_HOR_RESOLUTION - 1);
- LCD_WRAM((SSD_VER_RESOLUTION - 1) >> 8); //ÉèÖÃLCD´¹Ö±ÏñËØ
- LCD_WRAM(SSD_VER_RESOLUTION - 1);
- LCD_WRAM(0x00); //RGBÐòÁÐ
- printf("set_lcd_mode\n");
- /*
- set_hori_period
- Command 0xB4
- Parameters 8
- D/C D7 D6 D5 D4 D3 D2 D1 D0 Hex
- Command 0 1 0 1 1 0 1 0 0 B4
- Parameter 1 1 0 0 0 0 0 HT10 HT9 HT8 xx
- Parameter 2 1 HT7 HT6 HT5 HT4 HT3 HT2 HT1 HT0 xx
- Parameter 3 1 0 0 0 0 0 HPS10 HPS9 HPS8 xx
- Parameter 4 1 HPS7 HPS6 HPS5 HPS4 HPS3 HPS2 HPS1 HPS0 xx
- Parameter 5 1 0 HPW6 HPW5 HPW4 HPW3 HPW2 HPW1 HPW0 xx
- Parameter 6 1 0 0 0 0 0 LPS10 LPS9 LPS8 xx
- Parameter 7 1 LPS7 LPS6 LPS5 LPS4 LPS3 LPS2 LPS1 LPS0 xx
- Parameter 8 1 0 0 0 0 0 0 LPSPP1 LPSPP0 xx
- Description
- Set front porch and back porch
- HT[10:8] : High byte of horizontal total period (display + non-display) in pixel clock (POR = 010)
- HT[7:0] : Low byte of the horizontal total period (display + non-display) in pixel clock (POR = 10101111)
- Horizontal total period = (HT + 1) pixels
- HPS[10:8] : High byte of the non-display period between the start of the horizontal sync (LLINE) signal and the first
- display data. (POR = 000)
- HPS[7:0] : Low byte of the non-display period between the start of the horizontal sync (LLINE) signal and the first
- display data. (POR = 00100000)
- For TFT : Horizontal Sync Pulse Start Position = HPS pixels
- For Serial TFT : Horizontal Sync Pulse Start Position = HPS pixels + LPSPP subpixels
- HPW[6:0] : Set the horizontal sync pulse width (LLINE) in pixel clock. (POR = 0000111)
- Horizontal Sync Pulse Width = (HPW + 1) pixelsSolomon Systech Jan 2010 P 48/93 Rev 1.1 SSD1963
- LPS[10:8] : Set the horizontal sync pulse (LLINE) start location in pixel clock. (POR = 000)
- LPS[7:0] : Set the horizontal sync pulse width (LLINE) in start. (POR = 00000000)
- Horizontal Display Period Start Position = LPS pixels
- LPSPP[1:0] : Set the horizontal sync pulse subpixel start position for serial TFT interface (POR = 00)
- */
- LCD_WREG(0xB4); //Set horizontal period
- LCD_WRAM((SSD_HT - 1) >> 8);
- LCD_WRAM(SSD_HT - 1);
- LCD_WRAM(SSD_HPS >> 8);
- LCD_WRAM(SSD_HPS);
- LCD_WRAM(SSD_HOR_PULSE_WIDTH - 1);
- LCD_WRAM(0x00);
- LCD_WRAM(0x00);
- LCD_WRAM(0x00);
- LCD_WREG(0xB6); //Set vertical period
- LCD_WRAM((SSD_VT - 1) >> 8);
- LCD_WRAM(SSD_VT - 1);
- LCD_WRAM(SSD_VPS >> 8);
- LCD_WRAM(SSD_VPS);
- LCD_WRAM(SSD_VER_FRONT_PORCH - 1);
- LCD_WRAM(0x00);
- LCD_WRAM(0x00);
- printf("set_hori_period\n");
- /*
- set_pixel_data_interface
- Command 0xF0
- Parameters 1
- D/C D7 D6 D5 D4 D3 D2 D1 D0 Hex
- Command 0 1 1 1 1 0 0 0 0 F0
- Parameter 1 1 0 0 0 0 0 A2 A1 A0 xx
- Description
- Set the pixel data format to 8-bit / 9-bit / 12-bit / 16-bit / 16-bit(565) / 18-bit / 24-bit in the parallel host processor
- interface. This command is used for display data only, the command format is always 8 bit.
- A[2:0] : Pixel Data Interface Format (POR = 101)
- 000 8-bit
- 001 12-bit
- 010 16-bit packed
- 011 16-bit (565 format)
- 100 18-bit
- 101 24-bit
- 110 9-bit
- Others Reserved
- * Note : The un-used data bus will be driven to ground by SSD1963, so don’t connect the un-used data bus to
- MCU
- */
- LCD_WREG(0xF0); //ÉèÖÃSSD1963ÓëCPU½Ó¿ÚΪ16bit
- LCD_WRAM(0x03); //16-bit(565 format) data for 16bpp
- printf("set_pixel_data_interface\n");
- /*
- set_display_on
- Command 0x29
- Parameters None
- D/C D7 D6 D5 D4 D3 D2 D1 D0 Hex
- Command 0 0 0 1 0 1 0 0 1 29
- Description
- Show the image on the display panel
- */
- LCD_WREG(0x29); //¿ªÆôÏÔʾ
- printf("set_display_on\n");
- /*
- //ÉèÖÃPWMÊä³ö ±³¹âͨ¹ýÕ¼¿Õ±È¿Éµ÷
- LCD_WREG(0xD0); //ÉèÖÃ×Ô¶¯°×ƽºâDBC
- LCD_WRAM(0x00); //disable
- LCD_WREG(0xBE); //ÅäÖÃPWMÊä³ö
- LCD_WRAM(0x05); //1ÉèÖÃPWMƵÂÊ
- LCD_WRAM(0xFE); //2ÉèÖÃPWMÕ¼¿Õ±È
- LCD_WRAM(0x01); //3ÉèÖÃC
- LCD_WRAM(0x00); //4ÉèÖÃD
- LCD_WRAM(0x00); //5ÉèÖÃE
- LCD_WRAM(0x00); //6ÉèÖÃF
- LCD_WREG(0xB8); //ÉèÖÃGPIOÅäÖÃ
- LCD_WRAM(0x03); //2¸öIO¿ÚÉèÖóÉÊä³ö
- LCD_WRAM(0x01); //GPIOʹÓÃÕý³£µÄIO¹¦ÄÜ
- LCD_WREG(0xBA);
- LCD_WRAM(0X01); //GPIO[1:0]=01,¿ØÖÆLCD·½Ïò
- */
- LCD_WREG(0x36); //ÉèÖÃɨÃèģʽ
- LCD_WRAM(0x00);
- }
- /* USER CODE END 0 */
- int main(void)
- {
- /* USER CODE BEGIN 1 */
- /* USER CODE END 1 */
- /* MCU Configuration----------------------------------------------------------*/
- /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
- HAL_Init();
- /* Configure the system clock */
- SystemClock_Config();
- /* Initialize all configured peripherals */
- MX_GPIO_Init();
- MX_FSMC_Init();
- /* USER CODE BEGIN 2 */
- SSD1963_43_Init();
- printf("init end\n");
- /* USER CODE END 2 */
- /* Infinite loop */
- /* USER CODE BEGIN WHILE */
- while (1)
- {
- /* USER CODE END WHILE */
- /* USER CODE BEGIN 3 */
- lcddev.wramcmd = 0X2C; //ÉèÖÃдÈëGRAMµÄÖ¸Áî
- lcddev.setxcmd = 0X2A; //ÉèÖÃдX×ø±êÖ¸Áî
- lcddev.setycmd = 0X2B; //ÉèÖÃдY×ø±êÖ¸Áî
- lcddev.width = 800; //ÉèÖÿí¶È800
- lcddev.height = 272; //ÉèÖø߶È272
- LCD_WREG(lcddev.setxcmd);//ÉèÖùâ±êλÖÃ
- LCD_WRAM(0);
- LCD_WRAM(0);
- LCD_WRAM((lcddev.width - 1) >> 8);
- LCD_WRAM((lcddev.width - 1) & 0XFF);
- LCD_WREG(lcddev.setycmd);//ÉèÖùâ±êλÖÃ
- LCD_WRAM(0);
- LCD_WRAM(0);
- LCD_WRAM((lcddev.height - 1) >> 8);
- LCD_WRAM((lcddev.height - 1) & 0XFF);
- LCD_WREG(lcddev.wramcmd);
- color = 0;
- pan = 0;
- for(i = 0; i < (lcddev.width * lcddev.height); i++)
- {
- pan = pan & 0xFF;
- pan ++;
-
- if(pan > 0xFF)
- {
- color += 15;
- }
-
- *LCD_RAM = color;
- }
- while(1);
- }
- /* USER CODE END 3 */
- }
测试打印结果如下:
|