标题:
ssd1289 STM32F103 LCD驱动程序
[打印本页]
作者:
dhma
时间:
2017-11-7 10:55
标题:
ssd1289 STM32F103 LCD驱动程序
STM32F103单片机下的 LCD驱动
0.png
(7.2 KB, 下载次数: 81)
下载附件
2017-11-8 02:39 上传
单片机源程序如下:
/*
*********************************************************************************************************
*
* 模块名称 : 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)
2017-11-7 10:55 上传
点击文件名下载附件
下载积分: 黑币 -5
作者:
syp999
时间:
2018-12-6 14:22
只有文件,没有整个工程,不能直接跑起来的
作者:
qqhuacong
时间:
2019-5-14 22:04
头回学习图形
作者:
lzhcccc
时间:
2019-9-23 09:25
qqhuacong 发表于 2019-5-14 22:04
头回学习图形
能用吗?
作者:
BBMBB
时间:
2019-10-28 21:46
PS[3:0]怎么接?
作者:
JaneJiang
时间:
2020-6-11 16:31
老板 想要资料
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1