#include "main.h"
#define LCD_Data_Addr ((u32)0x60020000) //A16做RS线
#define LCD_Reg_Addr ((u32)0x60000000)
void main(void);
void LCD_IO_Init(void);
void FSMC_LCD_Init(void);
void MyLcd_Reset(void);
void LCD_Configuration(void);
void SysTickInit (void);
void delay_us(uint16_t DelayTime);
void delay_ms(uint16_t DelayTime);
void MyLcd_WriteReg(u16 index,u16 dat);
void MyLcd_WriteIndex(u16 Index);
void MyLcd_WriteRAM(u16 data);
void LCD_SetPixel(uint16_t x,uint16_t y,uint16_t color);
void LCD_SetWindow(unsigned int x1,unsigned int y1,unsigned int x2,unsigned int y2);
void MyLcd_Clear(u16 color);
///////////////////////////////////////////////////////////////////////////////
u32 wCount = 0;
//主函数入口
void main(void)
{
//使用内部时钟。
SystemInit(); //设置STM32工作的时钟方式和工作频率 /
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |
RCC_APB2Periph_GPIOB |
RCC_APB2Periph_GPIOC |
RCC_APB2Periph_GPIOD |
RCC_APB2Periph_GPIOE |
RCC_APB2Periph_AFIO, ENABLE);//使用复用功能,必须开启AFIO时钟
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
SysTickInit(); //滴答时钟
LCD_Configuration(); //LCD屏配置
while(1)
{
wCount++;
delay_ms(1000);
}
}
void LCD_IO_Init(void)
{
//GPIO时钟必须使能,已在RCC中使能全部IO和AFIO。
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_LCDRST ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIO_LCDRST, &GPIO_InitStructure);
// LCD背光控制: PA8
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_LCDLAMP;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIO_LCDLAMP, &GPIO_InitStructure);
/*************LCD FSMC模式下数据线与控制线配置*******************/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_7 |
GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_14 |
GPIO_Pin_15;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOD, &GPIO_InitStructure);
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;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOE, &GPIO_InitStructure);
}
/*******************************************************************************
* Function Name : FSMC_LCD_Init
* Description : FSMC接口初始化.
* Input : None
* Output : None
* Return : None
* Date : 30/06/2011
* Other : FSMC的GPIO必须要先初始化
*******************************************************************************/
void FSMC_LCD_Init(void)
{
FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure;
FSMC_NORSRAMTimingInitTypeDef p;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE); //开启FSMC模式,TFT要用到
p.FSMC_AddressSetupTime = 0x01;//0x00
p.FSMC_AddressHoldTime = 0x00;
p.FSMC_DataSetupTime = 0x02;//0x01
p.FSMC_BusTurnAroundDuration = 0x00;
p.FSMC_CLKDivision = 0x00;
p.FSMC_DataLatency = 0x00;
p.FSMC_AccessMode = FSMC_AccessMode_B;
FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM1;
FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
// FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_NOR;
FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_PSRAM;
FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable; //根据网上建议增加,3.5库才有,旧版没有
FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
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_Disable;
FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p;
FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p;
FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);
/* Enable FSMC Bank1_SRAM Bank */
FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM1, ENABLE);
}
/****************************************************************************
* 名 称:void MyLcd_Reset()
* 功 能:复位 MyLcd 控制器
* 入口参数:无
* 出口参数:无
* 说 明:复位控制器,内部函数
* 调用方法:MyLcd_Reset()
****************************************************************************/
void MyLcd_Reset(void)
{
GPIO_SetBits(GPIO_LCDRST, GPIO_Pin_LCDRST);
delay_ms(100);
GPIO_ResetBits(GPIO_LCDRST, GPIO_Pin_LCDRST);
delay_ms(100);
GPIO_SetBits(GPIO_LCDRST, GPIO_Pin_LCDRST);
delay_ms(200);
}
void LCD_Configuration(void)
{
LCD_IO_Init(); //IO口初始化
FSMC_LCD_Init(); //FSMC初始化
Lcd_BackLightOn();
Lcd_BackLightOff();
Lcd_BackLightOn();
MyLcd_Reset();
MyLcd_WriteReg(0x0083,0x0002);
MyLcd_WriteReg(0x0085,0x0003);
MyLcd_WriteReg(0x008B,0x0000);
MyLcd_WriteReg(0x008C,0x0093);
MyLcd_WriteReg(0x0091,0x0001);
MyLcd_WriteReg(0x0083,0x0000);
MyLcd_WriteReg(0x003E,0x00B0);
MyLcd_WriteReg(0x003F,0x0003);
MyLcd_WriteReg(0x0040,0x0010);
MyLcd_WriteReg(0x0041,0x0056);
MyLcd_WriteReg(0x0042,0x0013);
MyLcd_WriteReg(0x0043,0x0046);
MyLcd_WriteReg(0x0044,0x0023);
MyLcd_WriteReg(0x0045,0x0076);
MyLcd_WriteReg(0x0046,0x0000);
MyLcd_WriteReg(0x0047,0x005E);
MyLcd_WriteReg(0x0048,0x004F);
MyLcd_WriteReg(0x0049,0x0040);
MyLcd_WriteReg(0x0017,0x0091);
MyLcd_WriteReg(0x002B,0x00F9);
delay_ms(10);
MyLcd_WriteReg(0x001B,0x0014);
MyLcd_WriteReg(0x001A,0x0011);
MyLcd_WriteReg(0x001C,0x0006);
MyLcd_WriteReg(0x001F,0x0042);
delay_ms(20);
MyLcd_WriteReg(0x0019,0x000A);
MyLcd_WriteReg(0x0019,0x000A);
delay_ms(40);
MyLcd_WriteReg(0x0019,0x0012);
delay_ms(40);
MyLcd_WriteReg(0x001E,0x0027);
delay_ms(100);
MyLcd_WriteReg(0x0024,0x0060);
MyLcd_WriteReg(0x003D,0x0040);
MyLcd_WriteReg(0x0034,0x0038);
MyLcd_WriteReg(0x0035,0x0038);
MyLcd_WriteReg(0x0024,0x0038);
delay_ms(10);
MyLcd_WriteReg(0x0024,0x003C);
MyLcd_WriteReg(0x0016,0x001C);
MyLcd_WriteReg(0x0001,0x0006);
MyLcd_WriteReg(0x0055,0x0000);
MyLcd_WriteReg(0x0002,0x0000);
MyLcd_WriteReg(0x0003,0x0000);
MyLcd_WriteReg(0x0004,0x0000);
MyLcd_WriteReg(0x0005,0x00ef);
MyLcd_WriteReg(0x0006,0x0000);
MyLcd_WriteReg(0x0007,0x0000);
MyLcd_WriteReg(0x0008,0x0001);
MyLcd_WriteReg(0x0009,0x008f);
MyLcd_WriteReg(0x0005,0x00ef);
MyLcd_WriteReg(0x0005,0x00ef);
MyLcd_WriteIndex(0x0202);
//MyLcd_Clear(YELLOW);
MyLcd_Clear(0xFFE0);
}
#define OS_TICKS_PER_SEC 100
void SysTickInit (void)
{
//嘀嗒时钟配置为10ms中断, 自动重装载,使能中断
//嘀嗒时钟源来自HCLK = 72MHz(为0则来自HCLK/8)
if (SysTick_Config(SystemCoreClock / OS_TICKS_PER_SEC))
{
/* Capture error */
while (1);
}
}
/*******************************************************************************
* Function Name : delay_us
* Description : 利用嘀嗒定时器实现的精确延时函数.
* Input : DelayTime延时微妙数,范围:范围:嘀嗒定时器中断时间即0-10000.
* Output : None
* Return : None
* Date : 30/06/2011
* Other : 原理:嘀嗒时钟为72MHz,所以1us计数值为72M/1000000,当需要延时DelayTime
时,计数个数为DelayTime*72
*******************************************************************************/
void delay_us(uint16_t DelayTime)
{
u32 start,total,diff = 0;
u32 count = 0;
u32 temp;
temp = SystemCoreClock / OS_TICKS_PER_SEC; //定时器最大脉冲数
start = SysTick->VAL; //定时器寄存器当前值记下
total = 1000000/OS_TICKS_PER_SEC; //延时最大微妙值
if(DelayTime > total) DelayTime = total; //输入超过最大值,则只执行最大值
total = DelayTime *(SystemCoreClock/1000000); //需要计算的脉冲个数
while(diff < total)
{
count = SysTick->VAL; //
if(start < count)
diff = temp - (count - start); //定时器溢出时
else
diff = start -count; //定时器未溢出时
}
}
//------------------------------------------------------------------
/*******************************************************************************
* Function Name : delay_ms
* Description : 利用嘀嗒定时器实现的精确延时函数.
* Input : DelayTime延时毫秒数.
* Output : None
* Return : None
* Date : 30/06/2011
* Other :
*******************************************************************************/
void delay_ms(uint16_t DelayTime)
{
uint16_t i;
for(i = 0; i < DelayTime; i++)
delay_us(1000);
}
////////////////////////////////////////////////////////////////////////////////
//往RAM中写入数据。RS=1,表示写数据,RS= 0表示写寄存器
void MyLcd_WriteRAM(u16 data)
{
*(volatile u16 *) (LCD_Data_Addr) = data;
}
//往某个地址的寄存器中写数据
void MyLcd_WriteReg(u16 index,u16 dat)
{
*(volatile u16 *) (LCD_Reg_Addr) = index;
*(volatile u16 *) (LCD_Data_Addr) = dat;
}
//往寄存器中写数据
void MyLcd_WriteIndex(u16 Index)
{
*(volatile u16 *) (LCD_Reg_Addr) = Index;
}
//设置某个点的颜色
void LCD_SetPixel(uint16_t x,uint16_t y,uint16_t color)
{
MyLcd_WriteReg(0x0003,x);
MyLcd_WriteReg(0x0007,y);
MyLcd_WriteIndex(0x0022);
MyLcd_WriteRAM(color);
}
void LCD_SetWindow(unsigned int x1,unsigned int y1,unsigned int x2,unsigned int y2)
{
MyLcd_WriteReg(0x0003,x1);
MyLcd_WriteReg(0x0006,y1>>8);
MyLcd_WriteReg(0x0007,y1);
MyLcd_WriteReg(0x0005,x2);
MyLcd_WriteReg(0x0008,y2>>8);
MyLcd_WriteReg(0x0008,y2);
MyLcd_WriteIndex(0x0022);
}
void MyLcd_Clear(u16 color)
{
u32 temp,end;;
LCD_SetWindow(0,0,LCD_XSIZE-1,LCD_YSIZE-1);
end = LCD_XSIZE * LCD_YSIZE;
for (temp = 0; temp < end; temp++)
{
MyLcd_WriteRAM(color);
}
}
求好心人稍微详细点解读下这个程序.....最好一步步对应来...拜托了.... |
|