看原理图就可以知道,这是想用FSMC来驱动液晶。在STM32F107中是没有FSMC的,而GD32F107中带有FSMC,所以在使用固件库的时候需要修改一处地方:
将RCC_AHBPeriph_FSMC移到#ifndef STM32F10X_CL上面。这也表明GD32的片内资源比STM32的同等型号丰富。那么接着就按照FSMC的方式来驱动液晶。
1、首先来确定地址:
更具原理图可以看出RS引脚是接在 EXMC_A23 , CS引脚是接在EXMC_NE1
将LCD当做SRAM操作,在存储块1 HADDR[27.26] = 00 地址范围:0x6000,0000~0x63ff,ffff
根据上图红线所标记的地方,来确定LCD的读写地址。
typedef struct
{
u16 Lcd_Command;
u16 Lcd_Data;
}LcdTypedef;
#define LCD_ADDR_BASE ((u32)(0X60000000 | 0X00FFFFFE))
#define MY_LCD ((LcdTypedef *)LCD_ADDR_BASE)
RS引脚是接在A23处,所以对于HADDR的第24位,按照上面代码的定义方式,就可以这样操作LCD:
void LcdWriteCommand(u16 cmd)
{
MY_LCD->Lcd_Command = cmd;
}
void LcdWriteData(u16 dat)
{
MY_LCD->Lcd_Data = dat;
}
u16 LcdReadData()
{
return MY_LCD->Lcd_Data;
}
在底层函数完成后,开始来操作TFT液晶。先读取液晶的ID,看其控制芯片是什么型号,在线调试读出的ID值为0X8989。附上一份资料SSD1289(ID8989).zip
完成读写寄存器的函数:
void LcdWriteRegist(u16 addr,u16 dat)
{
MY_LCD->Lcd_Command = addr;
MY_LCD->Lcd_Data = dat;
}
u16 LcdReadRegist(u16 addr)
{
MY_LCD->Lcd_Command = addr;
return MY_LCD->Lcd_Data;
}
那么初始化TFT液晶:
1、初始化IO口
2、初始化FSMC
3、初始化TFT液晶
void LcdInit()
{
GPIO_InitTypeDef GPIO_InitStruct;
FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStruct;
FSMC_NORSRAMTimingInitTypeDef FSMC_WriteTimingStruct;
FSMC_NORSRAMTimingInitTypeDef FSMC_ReadTimingStruct;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC,ENABLE );
RCC_APB2PeriphClockCmd (RCC_LCD_GPIO,ENABLE);
GPIO_InitStruct.GPIO_Pin = LCD_RS_Pin;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz ;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP ;
GPIO_Init (LCD_RS_GPIO,&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = LCD_WR_Pin;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz ;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP ;
GPIO_Init (LCD_WR_GPIO,&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = LCD_RD_Pin;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz ;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP ;
GPIO_Init (LCD_RD_GPIO,&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = LCD_CS_Pin;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz ;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP ;
GPIO_Init (LCD_CS_GPIO,&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = LCD_DAT_Pin_Part1;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz ;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP ;
GPIO_Init (LCD_DAT_GPIO_Part1,&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = LCD_DAT_Pin_Part2;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz ;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP ;
GPIO_Init (LCD_DAT_GPIO_Part2,&GPIO_InitStruct);
/**************************************************************************************/
FSMC_ReadTimingStruct.FSMC_AddressSetupTime = 0X01;
FSMC_ReadTimingStruct.FSMC_AddressHoldTime = 0X00;
FSMC_ReadTimingStruct.FSMC_DataSetupTime = 0X0F;
FSMC_ReadTimingStruct.FSMC_BusTurnAroundDuration = 0X00;
FSMC_ReadTimingStruct.FSMC_CLKDivision = 0X00;
FSMC_ReadTimingStruct.FSMC_DataLatency = 0X00;
FSMC_ReadTimingStruct.FSMC_AccessMode = FSMC_AccessMode_A ;
FSMC_WriteTimingStruct.FSMC_AddressSetupTime = 0X00;
FSMC_WriteTimingStruct.FSMC_AddressHoldTime = 0X00;
FSMC_WriteTimingStruct.FSMC_DataSetupTime = 0X03;
FSMC_WriteTimingStruct.FSMC_BusTurnAroundDuration = 0X00;
FSMC_WriteTimingStruct.FSMC_CLKDivision = 0X00;
FSMC_WriteTimingStruct.FSMC_DataLatency = 0X00;
FSMC_WriteTimingStruct.FSMC_AccessMode = FSMC_AccessMode_A ;
FSMC_NORSRAMInitStruct.FSMC_Bank = LCD_FSMC_Bank ;
FSMC_NORSRAMInitStruct.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable ;
FSMC_NORSRAMInitStruct.FSMC_MemoryType = FSMC_MemoryType_SRAM ;
FSMC_NORSRAMInitStruct.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
FSMC_NORSRAMInitStruct.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable ;
FSMC_NORSRAMInitStruct.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable ;
FSMC_NORSRAMInitStruct.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
FSMC_NORSRAMInitStruct.FSMC_WrapMode = FSMC_WrapMode_Disable ;
FSMC_NORSRAMInitStruct.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState ;
FSMC_NORSRAMInitStruct.FSMC_WriteOperation = FSMC_WriteOperation_Enable ;
FSMC_NORSRAMInitStruct.FSMC_WaitSignal = FSMC_WaitSignal_Disable ;
FSMC_NORSRAMInitStruct.FSMC_ExtendedMode = FSMC_ExtendedMode_Enable;
FSMC_NORSRAMInitStruct.FSMC_WriteBurst = FSMC_WriteBurst_Disable ;
FSMC_NORSRAMInitStruct.FSMC_ReadWriteTimingStruct = &FSMC_ReadTimingStruct;
FSMC_NORSRAMInitStruct.FSMC_WriteTimingStruct = &FSMC_WriteTimingStruct;
FSMC_NORSRAMInit (&FSMC_NORSRAMInitStruct);
FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM1,ENABLE );
DelayMs(50);
LcdWriteRegist(0x0000,0x0001);
DelayMs(50);
Lcd_InfoStruct.id = LcdReadRegist(0x0000);
if(Lcd_InfoStruct.id < 0XFF || Lcd_InfoStruct.id == 0XFFFF || Lcd_InfoStruct.id == 0X9300)
{
LcdWriteCommand(0XD3);
LcdReadData(); //dummy read
LcdReadData();
Lcd_InfoStruct.id=LcdReadData();
Lcd_InfoStruct.id <<= 8;
Lcd_InfoStruct.id |= LcdReadData();
}
if(Lcd_InfoStruct.id == MYLCD_ID)
{
Lcd_InfoStruct.b_color = RED;
Lcd_InfoStruct.f_color = WHITE;
Lcd_InfoStruct.gram_cmd = R34;
Lcd_InfoStruct.height = 320;
Lcd_InfoStruct.mode = V_Screen;
Lcd_InfoStruct.width = 240;
Lcd_InfoStruct.xcmd = 0X4E;
Lcd_InfoStruct.ycmd = 0X4F;
LcdWriteRegist(0x0000,0x0001);
LcdWriteRegist(0x0003,0xA8A4);
LcdWriteRegist(0x000C,0x0000);
LcdWriteRegist(0x000D,0x080C);
LcdWriteRegist(0x000E,0x2B00);
LcdWriteRegist(0x001E,0x00B0);
LcdWriteRegist(0x0001,0x2B3F);
LcdWriteRegist(0x0002,0x0600);
LcdWriteRegist(0x0010,0x0000);
LcdWriteRegist(0x0011,0x6078);
LcdWriteRegist(0x0005,0x0000);
LcdWriteRegist(0x0006,0x0000);
LcdWriteRegist(0x0016,0xEF1C);
LcdWriteRegist(0x0017,0x0003);
LcdWriteRegist(0x0007,0x0233);
LcdWriteRegist(0x000B,0x0000);
LcdWriteRegist(0x000F,0x0000);
LcdWriteRegist(0x0041,0x0000);
LcdWriteRegist(0x0042,0x0000);
LcdWriteRegist(0x0048,0x0000);
LcdWriteRegist(0x0049,0x013F);
LcdWriteRegist(0x004A,0x0000);
LcdWriteRegist(0x004B,0x0000);
LcdWriteRegist(0x0044,0xEF00);
LcdWriteRegist(0x0045,0x0000);
LcdWriteRegist(0x0046,0x013F);
LcdWriteRegist(0x0030,0x0707);
LcdWriteRegist(0x0031,0x0204);
LcdWriteRegist(0x0032,0x0204);
LcdWriteRegist(0x0033,0x0502);
LcdWriteRegist(0x0034,0x0507);
LcdWriteRegist(0x0035,0x0204);
LcdWriteRegist(0x0036,0x0204);
LcdWriteRegist(0x0037,0x0502);
LcdWriteRegist(0x003A,0x0302);
LcdWriteRegist(0x003B,0x0302);
LcdWriteRegist(0x0023,0x0000);
LcdWriteRegist(0x0024,0x0000);
LcdWriteRegist(0x0025,0x8000);
LcdWriteRegist(0x004f,0);
LcdWriteRegist(0x004e,0);
}
}
此液晶型号的资料以及寄存器的介绍都在上面的附件中,当初始化完成后,剩下的操作就是设置坐标,写入颜色。下面是清屏的函数:
void LcdSetPart(u16 xS,u16 yS,u16 xE,u16 yE)
{
LcdWriteRegist(0x0044,((xE << 8) | xS));
LcdWriteRegist(0x0045,yS);
LcdWriteRegist(0x0046,yE);
}
void LcdClearScreen(u16 Color)
{
u32 i = 0;
LcdSetPart(0,0,Lcd_InfoStruct.width - 1,Lcd_InfoStruct.height - 1);
LcdWriteCommand(Lcd_InfoStruct.gram_cmd);
for(i = 0;i < 76800;i++)
{
LcdWriteData(Color);
}
}
主函数:
int main()
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
LedPinInit();
SysTickInit();
LcdInit();
LcdClearScreen(Lcd_InfoStruct.b_color);
LcdDispString(0,0,(u8 *)"hello world",0,Lcd_InfoStruct.b_color,Lcd_InfoStruct.f_color);
LcdDispString(0,20,(u8 *)"www.eepw.com.cn",0,Lcd_InfoStruct.b_color,Lcd_InfoStruct.f_color);
LcdDispString(0,40,(u8 *)"liklon -->GD32107V-EVAL",0,Lcd_InfoStruct.b_color,Lcd_InfoStruct.f_color);
while(1)
{
;
}
}
函数比较多,不一一贴出,,将在导航帖附上代码。
效果图:
通过查看效果,刷屏速度也是相当不错,也可以看出GD32对比STM32同等型号的片子,其资源相对更加丰富,操作起来更方便。那GD32F107与STM32F107想比较,GD32在资源方面就占了优势。
我要赚赏金
