STM32F405RGT6 最小系统板加一个2.0寸的液晶 因为没有FSMC所以用的是模拟8080的并口
#include "sys.h"
#include "ILI93xx.h"
#include "delay.h"
#include <stdio.h>
#include "font.h"
//#include <MM1_240.h>
//#include <MM3_240.h>
u16 POINT_COLOR=0x0000; //画笔颜 {MOD}
u16 BACK_COLOR=0xFFFF; //背景 {MOD}
//管理LCD重要参数
//默认为横屏
_lcd_dev lcddev;
void LCD_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC|RCC_AHB1Periph_GPIOB, ENABLE);//使能PORTA~E,PORTG时钟
//GPIO初始化设置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_4|GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 |GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化
LCD_RD_H; //不读
}
static void LCD_Rst(void)
{
LCD_RST_L;
delay_ms(10);
LCD_RST_H;
delay_ms(10);
}
void WriteComm(u16 CMD)
{
LCD_CS_L;
LCD_RS_L; //写地址
LCD_WR_L;
DATAOUT(CMD);
LCD_WR_H;
LCD_CS_H;
}
void WriteData(u16 tem_data)
{
LCD_CS_L;
LCD_RS_H; //写数据
LCD_WR_L;
DATAOUT(tem_data);
LCD_WR_H;
LCD_CS_H;
}
void Write_long_Comm(u16 CMD)
{
LCD_CS_L;
LCD_RS_L; //写地址
LCD_WR_L;
DATAOUT(CMD>>8);
LCD_WR_H;
LCD_WR_L;
DATAOUT(CMD);
LCD_WR_H;
LCD_CS_H;
}
void Write_long_Data(u16 tem_data)
{
LCD_CS_L;
LCD_RS_H; //写数据
LCD_WR_L;
DATAOUT(tem_data>>8);
LCD_WR_H;
LCD_WR_L;
DATAOUT(tem_data);
LCD_WR_H;
LCD_CS_H;
}
u16 Read_long_Data(void)
{
u16 tl,th;
GPIOC->MODER=(GPIOC->MODER&0Xffff0000); //PC0-7 上拉输入
GPIOC->ODR=(GPIOC->ODR&0Xff00); //全部输出0
LCD_CS_L;
LCD_RS_H;
LCD_RD_L;
th=DATAIN;
LCD_RD_H;
LCD_RD_L;
tl=DATAIN;
LCD_RD_H;
LCD_CS_H;
GPIOC->MODER=(GPIOC->MODER|0X00005555); //PC0-7 上拉输出
GPIOC->ODR=(GPIOC->ODR|0X00FF); //全部输出高
return (th<<8)|tl;
}
u16 ReadData(void)
{
u16 t;
GPIOC->MODER=(GPIOC->MODER&0Xffff0000); //PC0-7 上拉输入
GPIOC->ODR=(GPIOC->ODR&0Xff00); //全部输出0
LCD_CS_L;
LCD_RS_H;
LCD_RD_L;
t=DATAIN;
LCD_CS_H;
GPIOC->MODER=(GPIOC->MODER|0X00005555); //PC0-7 上拉输出
GPIOC->ODR=(GPIOC->ODR|0X00FF); //全部输出高
return t;
}
/**********************************************
Lcd初始化函数
***********************************************/
void Lcd_Initialize(void)
{
LCD_GPIO_Config();
LCD_Rst();
WriteComm(0x00);
lcddev.id=Read_long_Data(); //读器件ID测试用可以屏蔽
LCD_WR_REG(0x00,0x0001);
delay_ms(20);
LCD_WR_REG(0x00,0x0000);
//************* Start Initial Sequence **********//
if(lcddev.dir==0)
{
LCD_WR_REG(0x0001, 0x0000); // 横屏
}
else if(lcddev.dir==1)
{
LCD_WR_REG(0x0001, 0x0100); // 竖屏
}
LCD_WR_REG(0x0002, 0x0200); // set 1 line inversion
LCD_WR_REG(0x0003, 0x1028); // set GRAM write direction and BGR=1.
LCD_WR_REG(0x0008, 0x0202); // set the back porch and front porch
LCD_WR_REG(0x0009, 0x0000); // set non-display area refresh cycle ISC[3:0]
LCD_WR_REG(0x000A, 0x0000); // FMARK function
LCD_WR_REG(0x000C, 0x0000); // RGB interface setting
LCD_WR_REG(0x000D, 0x0000); // Frame marker Position
LCD_WR_REG(0x0060, 0x2700); // Gate Scan Line
LCD_WR_REG(0x0061, 0x0001); // NDL,VLE, REV
LCD_WR_REG(0x006A, 0x0000); // set scrolling line
delay_ms(10);
//*************Power On sequence ****************// // Dis-charge capacitor power voltage
LCD_WR_REG(0x0010, 0x1490); // SAP, BT[3:0], AP, DSTB, SLP, STB
LCD_WR_REG(0x0011, 0x0227); // DC1[2:0], DC0[2:0], VC[2:0]
delay_ms(80); // Delay 50ms
LCD_WR_REG(0x0012, 0x008C); // Internal reference voltage= Vci;
delay_ms(10); // Delay 50ms
LCD_WR_REG(0x0013, 0x1900); // Set VDV[4:0] for VCOM amplitude
LCD_WR_REG(0x0029, 0x0029); // Set VCM[5:0] for VCOMH
LCD_WR_REG(0x002B, 0x000D); // Set Frame Rate
delay_ms(10); // Delay 50ms
LCD_WR_REG(0x0020, 0x0000); // GRAM horizontal Address
LCD_WR_REG(0x0021, 0x0000); // GRAM Vertical Address
// ----------- Adjust the Gamma Curve ----------//
LCD_WR_REG(0x0030, 0x0000);
LCD_WR_REG(0x0031, 0x0303);
LCD_WR_REG(0x0032, 0x0102);
LCD_WR_REG(0x0035, 0x0101);
LCD_WR_REG(0x0036, 0x0008);
LCD_WR_REG(0x0037, 0x0506);
LCD_WR_REG(0x0038, 0x0404);
LCD_WR_REG(0x0039, 0x0707);
LCD_WR_REG(0x003C, 0x0101);
LCD_WR_REG(0x003D, 0x0804);
//------------------ Set GRAM area ---------------//
LCD_WR_REG(0x0050, 0x0000); // Horizontal GRAM Start Address
LCD_WR_REG(0x0051, 0x00EF); // Horizontal GRAM End Address
LCD_WR_REG(0x0052, 0x0000); // Vertical GRAM Start Address
LCD_WR_REG(0x0053, 0x013F); // Vertical GRAM Start Address
delay_ms(10);
LCD_WR_REG(0x0007, 0x0133); // 262K color and display ON
delay_ms(10);
LCD_BL=1;
Lcd_Clear(White);
}
/******************************************
函数名:Lcd写命令函数
功能:向Lcd指定位置写入应有命令或数据
入口参数:Index 要寻址的寄存器地址
ConfigTemp 写入的数据或命令值
******************************************/
void LCD_WR_REG(u16 Index,u16 CongfigTemp)
{
Write_long_Comm(Index);
Write_long_Data(CongfigTemp);
}
/************************************************
函数名:Lcd写开始函数
功能:控制Lcd控制引脚 执行写操作
************************************************/
void Lcd_WR_Start(void)
{
WriteComm(0x00);
WriteComm(0x22);
}
/*************************************************
函数名:Lcd光标起点定位函数
功能:指定320240液晶上的一点作为写数据的起始点
入口参数:x 坐标 0~239
y 坐标 0~319
返回值:无
*************************************************/
void Lcd_SetCursor(u16 x,u16 y)
{
//坐标调转
if(lcddev.dir==0)//横屏
{
LCD_WR_REG(0x20,y);//水平坐标
LCD_WR_REG(0x21,x);//垂直坐?
}
else if(lcddev.dir==1)//竖屏
{
LCD_WR_REG(0x20,x);//水平坐标
LCD_WR_REG(0x21,y);//垂直坐?
}
}
void Lcd_SetGRAM(u16 x,u16 y)
{
//坐标调转
if(lcddev.dir==0)//横屏
{
LCD_WR_REG(0x0050,y);//水平 GRAM起始位置
LCD_WR_REG(0x0052,x);//垂直GRAM起始位置
}
else if(lcddev.dir==1)//竖屏
{
LCD_WR_REG(0x0050,x);//水平 GRAM起始位置
LCD_WR_REG(0x0052,y);//垂直GRAM起始位置
}
}
//开始全屏写,设置地址
void Lcd_Start(void)
{
Lcd_SetCursor(0,0);
LCD_WR_REG(0x0050,0x00);//水平 GRAM起始位置
LCD_WR_REG(0x0051,239);//水平GRAM终止位置
LCD_WR_REG(0x0052,0x00);//垂直GRAM起始位置
LCD_WR_REG(0x0053,319);//垂直GRAM终止位置
Lcd_WR_Start();
}
/**********************************************
函数名:Lcd全屏擦除函数
功能:将Lcd整屏擦为指定颜 {MOD}
入口参数:color 指定Lcd全屏颜 {MOD} RGB(5-6-5)
返回值:无
***********************************************/
void Lcd_Clear(u16 Color)
{
u32 temp;
Lcd_Start();
for (temp = 0; temp < 76800; temp++)
{
Write_long_Data( Color);
}
}
/******************************************
函数名:Lcd图像填充100*100
功能:向Lcd指定位置填充图像
入口参数:Index 要寻址的寄存器地址
ConfigTemp 写入的数据或命令值
******************************************/
void LCD_Fill_Pic(u16 x, u16 y,u16 pic_H, u16 pic_V, const unsigned char* pic)
{
unsigned long i;
// WriteComm(0x36); //Set_address_mode
// WriteData(0x0a); //横屏,从左下角开始,从左到右,从下到上
Lcd_Start();
for (i = 0; i < pic_H*pic_V*2; i++)
{
// j=pic[i];
// j=j<<8;
// j=j+pic[i+1];
WriteData(pic[i]);
}
// WriteComm(0x36); //Set_address_mode
// WriteData(0xaa);
}
void LCD_Fast_DrawPoint(u16 x, u16 y, u16 Color)
{
Lcd_SetCursor(x,y);
Lcd_SetGRAM(x,y);
Lcd_WR_Start();
Write_long_Data(Color);
}
u16 LCD_ReadPoint(u16 x,u16 y)
{
if(x>=320||y>=240)return 0; //超过了范围,直接返回
if(lcddev.dir==0)//横屏
{
Lcd_SetCursor(x,y);
}
else if(lcddev.dir==1)//竖屏
{
Lcd_SetCursor(x,y);
}
Lcd_WR_Start();
return Read_long_Data();;
}
//在指定区域内填充单个颜 {MOD}
//(sx,sy),(ex,ey):填充矩形对角坐标,区域大小为
ex-sx+1)*(ey-sy+1)
//color:要填充的颜 {MOD}
void LCD_Fill(u16 sx,u16 sy,u16 ex,u16 ey,u16 color)
{
u16 i,j;
u16 xlen=0;
xlen=ex-sx+1;
for(i=sy;i<=ey;i++)
{
Lcd_SetCursor(sx,i); //设置光标位置
Lcd_SetGRAM(sx,i); //设置GRAM位置
Lcd_WR_Start(); //开始写
for(j=0;j<xlen;j++)Write_long_Data(color); //显示颜 {MOD}
}
}
//在指定位置显示一个字符
//x,y:起始坐标
//num:要显示的字符:" "--->"~"
//size:字体大小 12/16/24
//mode:叠加方式(1)还是非叠加方式(0)
void LCD_ShowChar(u16 x,u16 y,u8 num,u8 size,u8 mode)
{
u8 temp,t1,t;
u16 y0=y;
u8 csize=(size/8+((size%8)?1:0))*(size/2); //得到字体一个字符对应点阵集所占的字节数
num=num-' ';//得到偏移后的值(ASCII字库是从空格开始取模,所以-' '就是对应字符的字库)
for(t=0;t<csize;t++)
{
if(size==12)temp=asc2_1206[num][t]; //调用1206字体
else if(size==16)temp=asc2_1608[num][t]; //调用1608字体
else if(size==24)temp=asc2_2412[num][t]; //调用2412字体
else return; //没有的字库
for(t1=0;t1<8;t1++)
{
if(temp&0x80)LCD_Fast_DrawPoint(x,y,POINT_COLOR);
else if(mode==0)LCD_Fast_DrawPoint(x,y,BACK_COLOR);
temp<<=1;
y++;
if(y>=240)return; //超区域了
if((y-y0)==size)
{
y=y0;
x++;
if(x>=320)return; //超区域了
break;
}
}
}
}
//m^n函数
//返回值:m^n次方.
u32 LCD_Pow(u8 m,u8 n)
{
u32 result=1;
while(n--)result*=m;
return result;
}
//显示数字,高位为0,则不显示
//x,y :起点坐标
//len :数字的位数
//size:字体大小
//color:颜 {MOD}
//num:数值(0~4294967295);
void LCD_ShowNum(u16 x,u16 y,u32 num,u8 len,u8 size)
{
u8 t,temp;
u8 enshow=0;
for(t=0;t<len;t++)
{
temp=(num/LCD_Pow(10,len-t-1))%10;
if(enshow==0&&t<(len-1))
{
if(temp==0)
{
LCD_ShowChar(x+(size/2)*t,y,' ',size,0);
continue;
}else enshow=1;
}
LCD_ShowChar(x+(size/2)*t,y,temp+'0',size,0);
}
}
//显示数字,高位为0,还是显示
//x,y:起点坐标
//num:数值(0~999999999);
//len:长度(即要显示的位数)
//size:字体大小
//mode:
//[7]:0,不填充;1,填充0.
//[6:1]:保留
//[0]:0,非叠加显示;1,叠加显示.
void LCD_ShowxNum(u16 x,u16 y,u32 num,u8 len,u8 size,u8 mode)
{
u8 t,temp;
u8 enshow=0;
for(t=0;t<len;t++)
{
temp=(num/LCD_Pow(10,len-t-1))%10;
if(enshow==0&&t<(len-1))
{
if(temp==0)
{
if(mode&0X80)LCD_ShowChar(x+(size/2)*t,y,'0',size,mode&0X01);
else LCD_ShowChar(x+(size/2)*t,y,' ',size,mode&0X01);
continue;
}else enshow=1;
}
LCD_ShowChar(x+(size/2)*t,y,temp+'0',size,mode&0X01);
}
}
//显示字符串
//x,y:起点坐标
//width,height:区域大小
//size:字体大小
//*p:字符串起始地址
void LCD_ShowString(u16 x,u16 y,u16 width,u16 height,u8 size,u8 *p)
{
u8 x0=x;
width+=x;
height+=y;
while((*p<='~')&&(*p>=' '))//判断是不是非法字符!
{
if(x>=width){x=x0;y+=size;}
if(y>=height)break;//退出
LCD_ShowChar(x,y,*p,size,0);
x+=size/2;
p++;
}
}
#ifndef __ILI93xx_H
#define __ILI93xx_H
#include "sys.h"
//LCD重要参数集
typedef struct
{
u16 width; //LCD 宽度
u16 height; //LCD 高度
u16 id; //LCD ID
u8 dir; //横屏还是竖屏控制:0,竖屏;1,横屏。
}_lcd_dev;
extern _lcd_dev lcddev; //管理LCD重要参数
extern u16 POINT_COLOR;//默认红 {MOD}
extern u16 BACK_COLOR; //背景颜 {MOD}.默认为白 {MOD}
#define LCD_CS PBout(6)
#define LCD_RS PBout(7)
#define LCD_WR PBout(8)
#define LCD_RD PBout(9)
#define LCD_RST PBout(4)
#define LCD_BL PBout(5)
#define LCD_CS_L GPIOB->BSRRH = GPIO_Pin_6;
#define LCD_RS_L GPIOB->BSRRH = GPIO_Pin_7;
#define LCD_WR_L GPIOB->BSRRH = GPIO_Pin_8;
#define LCD_RD_L GPIOB->BSRRH = GPIO_Pin_9;
#define LCD_RST_L GPIOB->BSRRH = GPIO_Pin_4;
#define LCD_CS_H GPIOB->BSRRL = GPIO_Pin_6;
#define LCD_RS_H GPIOB->BSRRL= GPIO_Pin_7;
#define LCD_WR_H GPIOB->BSRRL = GPIO_Pin_8;
#define LCD_RD_H GPIOB->BSRRL = GPIO_Pin_9;
#define LCD_RST_H GPIOB->BSRRL = GPIO_Pin_4;
#define DATAOUT(LCD_DATA) GPIOC->ODR=( GPIOC->ODR&0xff00)|(LCD_DATA&0x00ff);
#define DATAIN GPIOC->IDR&0x00ff; //数据输入
//#define DATAOUTH(LCD_DATA) GPIOC->BSRRL=( GPIOC->BSRRL)|(LCD_DATA&0x00ff);
//#define DATAOUTL(LCD_DATA) GPIOC->BSRRH=( GPIOC->BSRRH)|(~(LCD_DATA&0x00ff));
//Lcd初始化及其低级控制函数
void LCD_GPIO_Config(void);
void Lcd_Configuration(void);
void DataToWrite(u16 data);
void Lcd_Initialize(void);
void LCD_WR_REG(u16 Index,u16 CongfigTemp);
void Lcd_WR_Start(void);
void Lcd_Clear(u16 Color);
void Lcd_SetCursor(u16 x,u16 y);
void Lcd_SetGRAM(u16 x,u16 y);
void Write_long_Data(u16 tem_data);
//Lcd高级控制函数
//void Lcd_ColorBox(u16 x,u16 y,u16 xLong,u16 yLong,u16 Color);
//u16 ssd1289_GetPoint(u16 x,u8 y);
void LCD_Fill_Pic(u16 x, u16 y,u16 pic_H, u16 pic_V, const unsigned char* pic);
//char Tiky_Button(char *filename,u16 x,u16 y);
void LCD_Fast_DrawPoint(u16 x, u16 y, u16 Color);
u16 LCD_ReadPoint(u16 x,u16 y);
void LCD_Fill(u16 sx,u16 sy,u16 ex,u16 ey,u16 color);
void LCD_ShowChar(u16 x,u16 y,u8 num,u8 size,u8 mode);
void LCD_ShowNum(u16 x,u16 y,u32 num,u8 len,u8 size);
void LCD_ShowxNum(u16 x,u16 y,u32 num,u8 len,u8 size,u8 mode);
void LCD_ShowString(u16 x,u16 y,u16 width,u16 height,u8 size,u8 *p);
#define White 0xFFFF
#define Black 0x0000
#define Blue 0x001F
#define Blue2 0x051F
#define Red 0xF800
#define Magenta 0xF81F
#define Green 0x07E0
#define Cyan 0x7FFF
#define Yellow 0xFFE0
#endif
一周热门 更多>