#include "lcd.h"
#include "stdlib.h"
#include "font.h"
#include "usart.h"
#include "delay.h"
//LCD的画笔颜和背景
u16 POINT_COLOR=0x0000; //画笔颜
u16 BACK_COLOR=0xFFFF; //背景
//管理LCD重要参数
//默认为竖屏
_lcd_dev lcddev;
/
/写寄存器函数
//data:寄存器值
void LCD_WR_REG(u16 data)
{
LCD_RS_CLR;//写地址
// delay_ms(10);
LCD_CS_CLR;
// delay_ms(10);
DATAOUT(data);
LCD_WR_CLR;
// delay_ms(10);
LCD_WR_SET;
// delay_ms(10);write的返回值
LCD_CS_SET;
}
//写数据函数
//可以替代LCD_WR_DATAX宏,拿时间换空间.
//data:寄存器值
void LCD_WR_DATAX(u16 data)
{
LCD_RS_SET;
// delay_ms(10);
LCD_CS_CLR;
// delay_ms(10);
DATAOUT(data);
LCD_WR_CLR;
// delay_ms(10);
LCD_WR_SET;
// delay_ms(10);
LCD_CS_SET;
}
//读LCD数据
//返回值:读到的值
u16 LCD_RD_DATA(void)
{
u16 t;
GPIOB->CRL=0X88888888; //PB0-7 上拉输入
GPIOB->CRH=0X88888888; //PB8-15 上拉输入
GPIOB->ODR=0X0000; //全部输出0
LCD_RS_SET;
// delay_ms(10);
LCD_CS_CLR;
// delay_ms(10);
//读取数据(读寄存器时,并不需要读2次)
LCD_RD_CLR;
t=DATAIN;
LCD_RD_SET;
// delay_ms(100);
LCD_CS_SET;
GPIOB->CRL=0X33333333; //PB0-7 上拉输出
GPIOB->CRH=0X33333333; //PB8-15 上拉输出
GPIOB->ODR=0XFFFF; //全部输出高
return t;
}
//写寄存器
/
/LCD_Reg:寄存器编号
//LCD_RegValue:要写入的值
void LCD_WriteReg(u16 LCD_Reg,u16 LCD_RegValue)
{
LCD_WR_REG(LCD_Reg);
LCD_WR_DATA(LCD_RegValue);
}
//读寄存器
//LCD_Reg:寄存器编号
//返回值:读到的值
u16 LCD_ReadReg(u16 LCD_Reg)
{
LCD_WR_REG(LCD_Reg); //写入要读的寄存器号
return LCD_RD_DATA();
}
//开始写GRAM
void LCD_WriteRAM_Prepare(void)
{
LCD_WR_REG(lcddev.wramcmd);
}
//LCD写GRAM
//RGB_Code:颜值
void LCD_WriteRAM(u16 RGB_Code)
{
LCD_WR_DATA(RGB_Code);//写十六位GRAM
}
//LCD开启显示
void LCD_DisplayOn(void)
{
LCD_WR_REG(0X29); //开启显示
}
//LCD关闭显示
void LCD_DisplayOff(void)
{
LCD_WR_REG(0X28); //关闭显示
}
//设置光标位置
//Xpos:横坐标
//Ypos:纵坐标
void
LCD_SetCursor(u16 Xpos, u16 Ypos)
{
LCD_WR_REG(lcddev.setxcmd);
LCD_WR_DATA(Xpos>>8);
LCD_WR_DATA(Xpos&0XFF);
LCD_WR_REG(lcddev.setycmd);
LCD_WR_DATA(Ypos>>8);
LCD_WR_DATA(Ypos&0XFF);
}
//设置LCD的自动扫描方向
//注意:其他函数可能会受到此函数设置的影响(尤其是9341/6804这两个奇葩),
//所以,一般设置为L2R_U2D即可,如果设置为其他扫描方式,可能导致显示不正常.
//dir:0~7,代表8个方向(具体定义见lcd.h)
//9320/9325/9328/4531/4535/1505/b505/8989/5408/9341/5310/5510等IC已经实际测试
void LCD_Scan_Dir(u8 dir)
{
u16 regval=0;
u16 dirreg=0;
u16 temp;
switch(dir)
{
case L2R_U2D://从左到右,从上到下
regval|=(0<<7)|(0<<6)|(0<<5);
break;
case L2R_D2U://从左到右,从下到上
regval|=(1<<7)|(0<<6)|(0<<5);
break;
case R2L_U2D://从右到左,从上到下
regval|=(0<<7)|(1<<6)|(0<<5);
break;
case R2L_D2U://从右到左,从下到上
regval|=(1<<7)|(1<<6)|(0<<5);
break;
case U2D_L2R://从上到下,从左到右
regval|=(0<<7)|(0<<6)|(1<<5);
break;
case U2D_R2L://从上到下,从右到左
regval|=(0<<7)|(1<<6)|(1<<5);
break;
case D2U_L2R://从下到上,从左到右
regval|=(1<<7)|(0<<6)|(1<<5);
break;
case D2U_R2L://从下到上,从右到左
regval|=(1<<7)|(1<<6)|(1<<5);
break;
}
LCD_WriteReg(dirreg,regval);
}
/
/画点
//x,y:坐标
//POINT_COLOR:此点的颜
void LCD_DrawPoint(u16 x,u16 y)
{
LCD_SetCursor(x,y); //设置光标位置
LCD_WriteRAM_Prepare(); //开始写入GRAM
LCD_WR_DATA(POINT_COLOR);
}
//快速画点
//x,y:坐标
/
/color:颜
void LCD_Fast_DrawPoint(u16 x,u16 y,u16 color)
{
LCD_WR_REG(lcddev.setxcmd);
LCD_WR_DATA(x>>8);
LCD_WR_DATA(x&0XFF);
LCD_WR_REG(lcddev.setycmd);
LCD_WR_DATA(y>>8);
LCD_WR_DATA(y&0XFF);
LCD_RS_CLR;
LCD_CS_CLR;
DATAOUT
(lcddev.wramcmd);//写指令
LCD_WR_CLR;
LCD_WR_SET;
LCD_CS_SET;
LCD_WR_DATA(color); //写数据
}
//设置LCD显示方向
//dir:0,竖屏;1,横屏
void LCD_Display_Dir(u8 dir)
{
if(dir==0) //竖屏
{
lcddev.dir=0; //竖屏
lcddev.width=320;
lcddev.height=480;
lcddev.wramcmd=0X2C;
lcddev.setxcmd=0X2A;
lcddev.setycmd=0X2B;
}else //横屏
{
lcddev.dir=1; //横屏
lcddev.width=320;
lcddev.height=480;
lcddev.wramcmd=0X2C;
lcddev.setxcmd=0X2A;
lcddev.setycmd=0X2B;
}
LCD_Scan_Dir(DFT_SCAN_DIR); //默认扫描方向
}
//设置窗口,并自动设置画点坐标到窗口左上角(sx,sy).
//sx,sy:窗口起始坐标(左上角)
//width,height:窗口宽度和高度,必须大于0!!
/
/窗体大小:width*height.
//68042,横屏时不支持窗口设置!!
void LCD_Set_Window(u16 sx,u16 sy,u16 width,u16 height)
{
u8 hsareg,heareg,vsareg,veareg;
u16 hsaval,heaval,vsaval,veaval;
width=sx+width-1;
height=sy+height-1;
LCD_WR_REG(lcddev.setxcmd);
LCD_WR_DATA(sx>>8);
LCD_WR_DATA(sx&0XFF);
LCD_WR_DATA(width>>8);
LCD_WR_DATA(width&0XFF);
LCD_WR_REG(lcddev.setycmd);
LCD_WR_DATA(sy>>8);
LCD_WR_DATA(sy&0XFF);
LCD_WR_DATA(height>>8);
LCD_WR_DATA(height&0XFF);
if(lcddev.dir==1)//横屏
{
//窗口值
hsaval=sy;
heaval=height;
vsaval=lcddev.width-width-1;
veaval=lcddev.width-sx-1;
}else
{
hsaval=sx;
heaval=width;
vsaval=sy;
veaval=height;
}
hsareg=0X50;heareg=0X51;//水平方向窗口寄存器
vsareg=0X52;veareg=0X53;//垂直方向窗口寄存器
//设置寄存器值
LCD_WriteReg(hsareg,hsaval);
LCD_WriteReg(heareg,heaval);
LCD_WriteReg(vsareg,vsaval);
LCD_WriteReg(veareg,veaval);
LCD_SetCursor(sx,sy); //设置光标位置
}
//初始化lcd
//该初始化函数可以初始化各种ALIENTEK出品的LCD液晶屏
//本函数占用较大flash,用户可以根据自己的实际情况,删掉未用到的LCD初始化代码.以节
省空间.
void LCD_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE); //使能PORTB,C时钟和AFIO时钟
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable , ENABLE);//开启SWD,失能JTAG
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_9|GPIO_Pin_8|GPIO_Pin_7|GPIO_Pin_6; ///PORTC6~10复用推挽输出
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure); //GPIOC
GPIO_SetBits(GPIOC,GPIO_Pin_10|GPIO_Pin_9|GPIO_Pin_8|GPIO_Pin_7|GPIO_Pin_6);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All; // PORTB推挽输出
GPIO_Init(GPIOB, &GPIO_InitStructure); //GPIOB
GPIO_SetBits(GPIOB,GPIO_Pin_All);
delay_ms(500); // delay 50 ms
LCD_WriteReg(0x0000,0x0001);
delay_ms(500); // delay 50 ms
lcddev.id = LCD_ReadReg(0x0000);
LCD_WR_REG(0XDB);
LCD_RD_DATA(); //读到0X00
lcddev.id|=LCD_RD_DATA(); //读取41
if(lcddev.id!=0X9341) //9341初始化
{
LCD_WR_REG(0xB0);//{setc, [107], W,0x0B0}
LCD_WR_DATAX(0x00);//{setp, [104], W,0x000}
LCD_WR_REG(0xB3);
LCD_WR_DATAX(0x02);
LCD_WR_DATAX(0x00);
LCD_WR_DATAX(0x00);
LCD_WR_DATAX(0x00);
LCD_WR_REG(0xB4);
LCD_WR_DATAX(0x00);
LCD_WR_REG(0xC0);
LCD_WR_DATAX(0x13);//
LCD_WR_DATAX(0x3B);//480
LCD_WR_DATAX(0x00);
LCD_WR_DATAX(0x03);//02
LCD_WR_DATAX(0x00);
LCD_WR_DATAX(0x01);
LCD_WR_DATAX(0x00);
LCD_WR_DATAX(0x43);
LCD_WR_REG(0xC1);
LCD_WR_DATAX(0x08);
LCD_WR_DATAX(0x12);//CLOCK
LCD_WR_DATAX(0x08);
LCD_WR_DATAX(0x08);
LCD_WR_REG(0xC4);
LCD_WR_DATAX(0x11);
LCD_WR_DATAX(0x07);
LCD_WR_DATAX(0x03);
LCD_WR_DATAX(0x03);
LCD_WR_REG(0xC8);//GAMMA
LCD_WR_DATAX(0x04);
LCD_WR_DATAX(0x09);
LCD_WR_DATAX(0x16);
LCD_WR_DATAX(0x5A);
LCD_WR_DATAX(0x02);
LCD_WR_DATAX(0x0A);
LCD_WR_DATAX(0x16);
LCD_WR_DATAX(0x05);
LCD_WR_DATAX(0x00);
LCD_WR_DATAX(0x32);
LCD_WR_DATAX(0x05);
LCD_WR_DATAX(0x16);
LCD_WR_DATAX(0x0A);
LCD_WR_DATAX(0x53);//43/55
LCD_WR_DATAX(0x08);
LCD_WR_DATAX(0x16);
LCD_WR_DATAX(0x09);
LCD_WR_DATAX(0x04);
LCD_WR_DATAX(0x32);
LCD_WR_DATAX(0x00);
LCD_WR_REG(0x2A);
LCD_WR_DATAX(0x00)
;
LCD_WR_DATAX(0x00);
LCD_WR_DATAX(0x01);
LCD_WR_DATAX(0x3F);//320
LCD_WR_REG(0x2B);
LCD_WR_DATAX(0x00);
LCD_WR_DATAX(0x00);
LCD_WR_DATAX(0x01);
LCD_WR_DATAX(0xDF);//480
LCD_WR_REG(0x35);
LCD_WR_DATAX(0x00);
LCD_WR_REG(0x3A);
LCD_WR_DATAX(0x55);
LCD_WR_REG(0x44);
LCD_WR_DATAX(0x00);
LCD_WR_DATAX(0x01);
LCD_WR_REG(0x2C);
LCD_WR_REG(0x11);
delay_ms(150);
LCD_WR_REG(0xD0);
LCD_WR_DATAX(0x07);
LCD_WR_DATAX(0x07);
LCD_WR_DATAX(0x1E);
LCD_WR_DATAX(0x0703);
LCD_WR_REG(0xD1);
LCD_WR_DATAX(0x03);
LCD_WR_DATAX(0x52);//VCM
LCD_WR_DATAX(0x10);//VDV
LCD_WR_REG(0xD2);
LCD_WR_DATAX(0x03);
LCD_WR_DATAX(0x24);
LCD_WR_REG(0xB0);//{setc, [107], W,0x0B0}
LCD_WR_DATAX(0x00);//{setp, [104], W,0x000}
LCD_WR_REG(0x11); //Exit Sleep
delay_ms(120);
LCD_WR_REG(0x29); //display on
delay_ms(10);
LCD_Display_Dir(0); //默认为竖屏
}
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论