STM32F103单片机下的 LCD驱动
单片机源程序如下:
- /*
- *********************************************************************************************************
- *
- * 模块名称 : TFT液晶显示器驱动模块
- * 文件名称 : LCD_tft_lcd.c
- * 版 本 : V1.0
- * 说 明 : 安富莱开发板标配的TFT显示器分辨率为240x400,3.0寸宽屏,带PWM背光调节功能。
- * 支持的LCD内部驱动芯片型号有:SPFD5420A、OTM4001A、R61509V
- * 驱动芯片的访问地址为: 0x60000000
- * 修改记录 :
- * 版本号 日期 作者 说明
- * v1.0 2011-08-21 armfly ST固件库版本 V3.5.0版本。
- * a) 取消访问寄存器的结构体,直接定义
- * V2.0 2011-10-16 armfly 增加R61509V驱动,实现图标显示函数
- *
- *
- *********************************************************************************************************
- */
- /*
- 友情提示:
- TFT控制器和一般的12864点阵显示器的控制器最大的区别在于引入了窗口绘图的机制,这个机制对于绘制局部图形
- 是非常有效的。TFT可以先指定一个绘图窗口,然后所有的读写显存的操作均在这个窗口之内,因此它不需要CPU在
- 内存中保存整个屏幕的像素数据。
- */
- #include "stm32f10x.h"
- #include <stdio.h>
- #include <string.h>
- #include "bsp_tft_lcd.h"
- #include "bsp_timer.h"
- #include "fonts.h"
- /* 定义LCD驱动器的访问地址
- TFT接口中的RS引脚连接FSMC_A0引脚,由于是16bit模式,RS对应A1地址线,因此
- LCD_RAM的地址是+2
- */
- #define LCD_BASE ((uint32_t)(0x60000000 | 0x0C000000))
- #define LCD_REG *(__IO uint16_t *)(LCD_BASE)
- #define LCD_RAM *(__IO uint16_t *)(LCD_BASE + 2)
- static __IO uint8_t s_RGBChgEn = 0; /* RGB转换使能, 4001屏写显存后读会的RGB格式和写入的不同 */
- static __IO uint8_t s_AddrAutoInc = 0; /* 读回一个像素后,显存地址是否自动增1 */
- void LCD_DrawCircle(uint16_t _usX, uint16_t _usY, uint16_t _usRadius, uint16_t _usColor);
- void LCD_WriteReg(__IO uint16_t _usAddr, uint16_t _usValue);
- uint16_t LCD_ReadReg(__IO uint16_t _usAddr);
- static void LCD_SetDispWin(uint16_t _usX, uint16_t _usY, uint16_t _usHeight, uint16_t _usWidth);
- static void LCD_QuitWinMode(void);
- static void LCD_SetCursor(uint16_t _usX, uint16_t _usY);
- static void LCD_CtrlLinesConfig(void);
- static void LCD_FSMCConfig(void);
- static void LCD_Init_ssd1289(void);
- //static void LCD_Init_61509(void);
- static uint16_t LCD_BGR2RGB(uint16_t _usRGB);
- /*
- *********************************************************************************************************
- * 函 数 名: LCD_InitHard
- * 功能说明: 初始化LCD
- * 形 参:无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- void LCD_InitHard(void)
- {
- uint16_t id;;
- /* 配置LCD控制口线GPIO */
- LCD_CtrlLinesConfig();
- /* 配置FSMC接口,数据总线 */
- LCD_FSMCConfig();
- /* FSMC重置后必须加延迟才能访问总线设备 */
- //bsp_DelayMS(10);
-
-
- id = LCD_GetID(); /* 读取LCD驱动芯片ID */
-
-
- if (id == 0x8989) /* 4001屏和5420相同,4001屏读回显存RGB时,需要进行转换,5420无需 */
- {
- // GPIO_ResetBits(GPIOE, GPIO_Pin_2); /* 点亮LED1 */
- // bsp_DelayMS(100);
- // GPIO_SetBits(GPIOE, GPIO_Pin_2); /* 关闭LED1 */
- // bsp_DelayMS(100);
- //
- // GPIO_ResetBits(GPIOE, GPIO_Pin_2); /* 点亮LED1 */
- // bsp_DelayMS(100);
- // GPIO_SetBits(GPIOE, GPIO_Pin_2); /* 关闭LED1 */
- // bsp_DelayMS(100);
-
- LCD_Init_ssd1289();
- }
- /* 清除显存 */
- LCD_ClrScr(CL_BLACK); /* 黑色 */
- }
- /*
- *********************************************************************************************************
- * 函 数 名: LCD_WriteReg
- * 功能说明: 修改LCD控制器的寄存器的值。
- * 形 参:
- * LCD_Reg :寄存器地址;
- * LCD_RegValue : 寄存器值
- * 返 回 值: 无
- *********************************************************************************************************
- */
- void LCD_WriteReg(__IO uint16_t _usAddr, uint16_t _usValue)
- {
- /* Write 16-bit Index, then Write Reg */
- LCD_REG = _usAddr;
- /* Write 16-bit Reg */
- LCD_RAM = _usValue;
- }
- /*
- *********************************************************************************************************
- * 函 数 名: LCD_ReadReg
- * 功能说明: 读取LCD控制器的寄存器的值。
- * 形 参:
- * LCD_Reg :寄存器地址;
- * LCD_RegValue : 寄存器值
- * 返 回 值: 无
- *********************************************************************************************************
- */
- uint16_t LCD_ReadReg(__IO uint16_t _usAddr)
- {
- /* Write 16-bit Index (then Read Reg) */
- LCD_REG = _usAddr;
- /* Read 16-bit Reg */
- return (LCD_RAM);
- }
- /*
- *********************************************************************************************************
- * 函 数 名: LCD_CtrlLinesConfig
- * 功能说明: 配置LCD控制口线,FSMC管脚设置为复用功能
- * 形 参:无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- static void LCD_CtrlLinesConfig(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC,ENABLE); //使能FSMC时钟
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOE|RCC_APB2Periph_GPIOF|RCC_APB2Periph_GPIOG|RCC_APB2Periph_AFIO,ENABLE);//使能PORTB,D,E,G以及AFIO复用功能时钟
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //PA8 推挽输出 背光
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
-
- //PORTD复用推挽输出
- /*
- PD0 -> D2
- PD1 -> D3
- PD4 -> RD(FSMC_NOE)
- PD5 -> WR(FSMC_NWE)
- PD8 -> D13
- PD9 -> D14
- PD10 -> D15
- PD14 -> D0
- PD15 -> D1
- */
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_14|GPIO_Pin_15; // //PORTD复用推挽输出
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOD, &GPIO_InitStructure);
-
- //PORTE复用推挽输出
- /*
- PE7 -> D4
- PE8 -> D5
- PE9 -> D6
- PE10 -> D7
- PE11 -> D8
- PE12 -> D9
- PE13 -> D10
- PE14 -> D11
- PE15 -> D12
- */
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15; // //PORTD复用推挽输出
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOE, &GPIO_InitStructure);
- //PORTG12复用推挽输出
- /*
- PG12 -> CS(FSCM_NE4)
- */
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; // //PORTD复用推挽输出
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOG, &GPIO_InitStructure);
-
- /* 设置 PF0(A0 (RS)) 为复用推挽输出 */
- /*
- PF0 -> RS(FSCM_A0)
- */
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; // //PORTF复用推挽输出
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOF, &GPIO_InitStructure);
- }
- /*
- *********************************************************************************************************
- * 函 数 名: LCD_FSMCConfig
- * 功能说明: 配置FSMC并口访问时序
- * 形 参:无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- static void LCD_FSMCConfig(void)
- {
- //两种不同的初始化
- // FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure;
- // FSMC_NORSRAMTimingInitTypeDef readWriteTiming;
- // FSMC_NORSRAMTimingInitTypeDef writeTiming;
- //
- //
- // readWriteTiming.FSMC_AddressSetupTime = 0x01; //地址建立时间(ADDSET)为2个HCLK 1/36M=27ns
- // readWriteTiming.FSMC_AddressHoldTime = 0x00; //地址保持时间(ADDHLD)模式A未用到
- // readWriteTiming.FSMC_DataSetupTime = 0x0f; // 数据保存时间为16个HCLK,因为液晶驱动IC的读数据的时候,速度不能太快,尤其对1289这个IC。
- // readWriteTiming.FSMC_BusTurnAroundDuration = 0x00;
- // readWriteTiming.FSMC_CLKDivision = 0x00;
- // readWriteTiming.FSMC_DataLatency = 0x00;
- // readWriteTiming.FSMC_AccessMode = FSMC_AccessMode_A; //模式A
- // writeTiming.FSMC_AddressSetupTime = 0x00; //0x01 地址建立时间(ADDSET)为1个HCLK
- // writeTiming.FSMC_AddressHoldTime = 0x00; //地址保持时间(A
- // writeTiming.FSMC_DataSetupTime = 0x03; ////0x03 数据保存时间为4个HCLK
- // writeTiming.FSMC_BusTurnAroundDuration = 0x00;
- // writeTiming.FSMC_CLKDivision = 0x00;
- // writeTiming.FSMC_DataLatency = 0x00;
- // writeTiming.FSMC_AccessMode = FSMC_AccessMode_A; //模式A
- //
- // FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM4;// 这里我们使用NE4 ,也就对应BTCR[6],[7]。
- // FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable; // 不复用数据地址
- // FSMC_NORSRAMInitStructure.FSMC_MemoryType =FSMC_MemoryType_SRAM;// FSMC_MemoryType_SRAM; //SRAM
- // FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;//存储器数据宽度为16bit
- // FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode =FSMC_BurstAccessMode_Disable;// FSMC_BurstAccessMode_Disable;
- // FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
- // FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait=FSMC_AsynchronousWait_Disable;
- // FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
- // FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
- // FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable; // 存储器写使能
- // FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
- // FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Enable; // 读写使用不同的时序
- // FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
- // FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &readWriteTiming; //读写时序
- // FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &writeTiming; //写时序
- // FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure); //初始化FSMC配置
- // FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM4, ENABLE); // 使能BANK1
- //
-
-
-
- FSMC_NORSRAMInitTypeDef init;
- FSMC_NORSRAMTimingInitTypeDef timing;
- /*-- FSMC Configuration ------------------------------------------------------*/
- /*----------------------- SRAM Bank 4 ----------------------------------------*/
- /* FSMC_Bank1_NORSRAM4 configuration */
- timing.FSMC_AddressSetupTime = 1;
- timing.FSMC_AddressHoldTime = 0;
- timing.FSMC_DataSetupTime = 0x3; //必须大于2
- timing.FSMC_BusTurnAroundDuration = 0;
- timing.FSMC_CLKDivision = 0;
- timing.FSMC_DataLatency = 0;
- timing.FSMC_AccessMode = FSMC_AccessMode_A;
- //timing.FSMC_AccessMode = FSMC_AccessMode_B;
- /*
- LCD configured as follow:
- - Data/Address MUX = Disable
- - Memory Type = SRAM
- - Data Width = 16bit
- - Write Operation = Enable
- - Extended Mode = Enable
- - Asynchronous Wait = Disable
- */
- init.FSMC_Bank = FSMC_Bank1_NORSRAM4;
- init.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
- init.FSMC_MemoryType = FSMC_MemoryType_SRAM;
- //init.FSMC_MemoryType = FSMC_MemoryType_NOR;
- init.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
- init.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
- init.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable;
- init.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
- init.FSMC_WrapMode = FSMC_WrapMode_Disable;
- init.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
- init.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
- init.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
- init.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
- init.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
- init.FSMC_ReadWriteTimingStruct = &timing;
- init.FSMC_WriteTimingStruct = &timing;
- FSMC_NORSRAMInit(&init);
- /* - BANK 3 (of NOR/SRAM Bank 1~4) is enabled */
- FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM4, ENABLE);
- }
- /*
- *********************************************************************************************************
- * 函 数 名: LCD_GetID
- * 功能说明: 读取LCD的器件ID
- * 形 参:无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- uint16_t LCD_GetID(void)
- {
- return LCD_ReadReg(0x0000);
- }
- /*
- *********************************************************************************************************
- * 函 数 名: LCD_Init_ssd1289
- * 功能说明: 初始化ssd1289屏
- * 形 参:无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- static void LCD_Init_ssd1289(void)
- {
- /* 初始化LCD,写LCD寄存器进行配置 */
- /*
- R003H 寄存器很关键, Entry Mode ,决定了扫描方向
- 参见:SPFD5420A.pdf 第15页
- 240x400屏幕物理坐标(px,py)如下:
- R003 = 0x1018 R003 = 0x1008
- ------------------- -------------------
- |(0,0) | |(0,0) |
- | | | |
- | ^ ^ | | ^ ^ |
- | | | | | | | |
- | | | | | | | |
- | | | | | | | |
- | | ------> | | | | <------ | |
- | | | | | | | |
- | | | | | | | |
- | | | | | | | |
- | | | | | | | |
- | | | |
- | | | |
- | (x=239,y=399)| | (x=239,y=399)|
- |-------------------| |-------------------|
- | | | |
- ------------------- -------------------
- 按照安富莱开发板LCD的方向,我们期望的虚拟坐标和扫描方向如下:(和上图第1个吻合)
- --------------------------------
- | |(0,0) |
- | | ---------> |
- | | | |
- | | | |
- | | | |
- | | V |
- | | ---------> |
- | | (399,239)|
- --------------------------------
- 虚拟坐标(x,y) 和物理坐标的转换关系
- x = 399 - py;
- y = px;
- py = 399 - x;
- px = y;
- */
- //************* Start Initial Sequence **********//
- //for 3.2_37Pin_SSD1289
- LCD_WriteReg(0x0000,0x0001);//打开晶振
- LCD_WriteReg(0x0003,0xA8A4);//0xA8A4
- LCD_WriteReg(0x000C,0x0000);
- LCD_WriteReg(0x000D,0x080C);
- LCD_WriteReg(0x000E,0x2B00);
- LCD_WriteReg(0x001E,0x00B0);
- LCD_WriteReg(0x0001,0x2B3F);//驱动输出控制320*240 0x6B3F
- LCD_WriteReg(0x0002,0x0600);
- LCD_WriteReg(0x0010,0x0000);
- LCD_WriteReg(0x0011,0x6070); //定义数据格式 16位色 横屏 0x6058
- LCD_WriteReg(0x0005,0x0000);
- LCD_WriteReg(0x0006,0x0000);
- LCD_WriteReg(0x0016,0xEF1C);
- LCD_WriteReg(0x0017,0x0003);
- LCD_WriteReg(0x0007,0x0233); //0x0233
- LCD_WriteReg(0x000B,0x0000);
- LCD_WriteReg(0x000F,0x0000); //扫描开始地址
- LCD_WriteReg(0x0041,0x0000);
- LCD_WriteReg(0x0042,0x0000);
- LCD_WriteReg(0x0048,0x0000);
- LCD_WriteReg(0x0049,0x013F);
- LCD_WriteReg(0x004A,0x0000);
- LCD_WriteReg(0x004B,0x0000);
- LCD_WriteReg(0x0044,0xEF00);
- LCD_WriteReg(0x0045,0x0000);
- LCD_WriteReg(0x0046,0x013F);
- LCD_WriteReg(0x0030,0x0707);
- LCD_WriteReg(0x0031,0x0204);
- LCD_WriteReg(0x0032,0x0204);
- LCD_WriteReg(0x0033,0x0502);
- LCD_WriteReg(0x0034,0x0507);
- LCD_WriteReg(0x0035,0x0204);
- LCD_WriteReg(0x0036,0x0204);
- LCD_WriteReg(0x0037,0x0502);
- LCD_WriteReg(0x003A,0x0302);
- LCD_WriteReg(0x003B,0x0302);
- LCD_WriteReg(0x0023,0x0000);
- LCD_WriteReg(0x0024,0x0000);
- LCD_WriteReg(0x0025,0x8000);
- LCD_WriteReg(0x004f,0); //行首址0
- LCD_WriteReg(0x004e,0); //列首址0
- }
- /*
- *********************************************************************************************************
- * 函 数 名: LCD_DispOn
- * 功能说明: 打开显示
- * 形 参:无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- void LCD_DispOn(void)
- {
- LCD_WriteReg(0x0007, 0x0033); /* 打开显示 */
- }
- /*
- *********************************************************************************************************
- * 函 数 名: LCD_DispOff
- * 功能说明: 关闭显示
- * 形 参:无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- void LCD_DispOff(void)
- {
- LCD_WriteReg(0x0007, 0x0000); /* 关闭显示*/
- }
- /*
- *********************************************************************************************************
- * 函 数 名: LCD_ClrScr
- * 功能说明: 根据输入的颜色值清屏
- * 形 参:_usColor : 背景色
- * 返 回 值: 无
- *********************************************************************************************************
- */
- void LCD_ClrScr(uint16_t _usColor)
- {
- uint32_t i;
- LCD_SetCursor(0, 0); /* 设置光标位置 */
- LCD_REG = LR_GRAM; /* 准备读写显存 */
- for (i = 0; i < LCD_HEIGHT * LCD_WIDTH; i++)
- {
- LCD_RAM = _usColor;
- }
- }
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
ssd1289.rar
(10.49 KB, 下载次数: 92)
|