FMC驱动16位并口TFT

FMC驱动16位并口TFT

主控:STM32L476VET6
屏幕:16位并口 ILI9341 240*320
Stm32cube配置如下
1.FMC配置
在这里插入图片描述
extended mode(读写使用不同的时序)关闭
AddressSetupTime
此参数用于设置地址建立时间,单位FMC时钟周期个数,范围0 -15
DataSetupTime
此参数用于设置数据建立时间,单位FMC时钟周期个数,范围1 -255。
BusTurnAroundDuration
此参数用于设置总线TurnAround(总线周转阶段)持续时间,单位FMC时钟周期个数,范围0 -15。

2.屏幕电路
在这里插入图片描述
FSMC 读写GRAM函数
不同的地址线要计算地址偏移量

/* 当选择NE1 连接 LCD时, 地址范围: 0x60000000~0x63FFFFFF 
 * 当选用FSMC_A16地址线时
 * 16位数据时: 16bits => FSMC[24:0]== HADDR[25:1]
	 8位数据时 : 8bits  => FSMC[25:0]== HADDR[25:0]
 * register base address: 0x60000000
 * 16位数据时RAM base address: 0x60020000 = 0x60000000 + 2^16 * 2 = 0x60020000
 * 8 位数据时RAM base address: 0x60010000 = 0x60000000 + 2^16     = 0x60010000
 * 选用不同的地址线要重新计算偏移地址
 16位并口屏,A16地址线,所以数据地址起始为0x60020000
*/
#define Bank1_LCD_DATA 		((uint32_t)0x60020000)	/* display data address */
#define Bank1_LCD_REG		((uint32_t)0x60000000)	/* display register address */

/* LCD write data and register */
#define LCD_WR_DATA(value)	((*(__IO uint16_t*)(Bank1_LCD_DATA)) = ((uint16_t)(value)))
#define LCD_WR_REG(index)	((*(__IO uint16_t*)(Bank1_LCD_REG)) = ((uint16_t)index))

屏幕初始化

/*
*FuncName:	ILI9341_Init
*Parameter:	void
*Function:	initialize LCD control chip ILI9341
*History:	Create by ShenLin, 2012/08/23
*/
void ILI9341_Init(void)
{
	//GPIO_SetBits(GPIOE, GPIO_Pin_1);
	HAL_GPIO_WritePin(LCD_RST_GPIO_Port, LCD_RST_Pin,GPIO_PIN_SET);
	delayms(1);
	//GPIO_ResetBits(GPIOE, GPIO_Pin_1);
	HAL_GPIO_WritePin(LCD_RST_GPIO_Port, LCD_RST_Pin,GPIO_PIN_RESET);
	delayms(10);	
  //GPIO_SetBits(GPIOE, GPIO_Pin_1);
	HAL_GPIO_WritePin(LCD_RST_GPIO_Port, LCD_RST_Pin,GPIO_PIN_SET);	
	delayms(100);	

	/* power control B */
	LCD_WR_REG(0xCF);	
	LCD_WR_DATA(0x00);
	LCD_WR_DATA(0x81);
	LCD_WR_DATA(0x30);

	/* power on sequence control */
	LCD_WR_REG(0xED);
	LCD_WR_DATA(0x64);
	LCD_WR_DATA(0x03);
	LCD_WR_DATA(0x12);
	LCD_WR_DATA(0x81);
	
	/* driver timing control A */
	LCD_WR_REG(0xE8);
	LCD_WR_DATA(0x85);
	LCD_WR_DATA(0x10);
	LCD_WR_DATA(0x78);
	
	/* power control A */
	LCD_WR_REG(0xCB);
	LCD_WR_DATA(0x39);
	LCD_WR_DATA(0x2C);
	LCD_WR_DATA(0x00);
	LCD_WR_DATA(0x34);
	LCD_WR_DATA(0x02);
	
	/* pump ratio control */
	LCD_WR_REG(0xF7);
	LCD_WR_DATA(0x20);
	
	/* driver timing control B */
	LCD_WR_REG(0xEA);
	LCD_WR_DATA(0x00);
	LCD_WR_DATA(0x00);
	
	/* frame rate control */
	LCD_WR_REG(0xB1);
	LCD_WR_DATA(0x00);
	LCD_WR_DATA(0x1B);
	
	/* display function control */
	LCD_WR_REG(0xB6);
	LCD_WR_DATA(0x0A);
	LCD_WR_DATA(0xA2);
	
	/* power control 1 */
	LCD_WR_REG(0xC0);
	LCD_WR_DATA(0x35);
	
	/* power control 2 */
	LCD_WR_REG(0xC1);
	LCD_WR_DATA(0x11);
	
	/* VCOM control 1 */
	LCD_WR_REG(0xC5);
	LCD_WR_DATA(0x45);
	LCD_WR_DATA(0x45);
	
	/* VCOM control 2 */
	LCD_WR_REG(0xC7);
	LCD_WR_DATA(0xA2);
	
	/* enable 3 gamma */
	LCD_WR_REG(0xF2);
	LCD_WR_DATA(0x00);
	
	/* gamma set */
	LCD_WR_REG(0x26);
	LCD_WR_DATA(0x01);
	
	/* positive gamma correction */
	LCD_WR_REG(0xE0);
	LCD_WR_DATA(0x0F);
	LCD_WR_DATA(0x26);
	LCD_WR_DATA(0x24);
	LCD_WR_DATA(0x0B);
	LCD_WR_DATA(0x0E);
	LCD_WR_DATA(0x09);
	LCD_WR_DATA(0x54);
	LCD_WR_DATA(0xA8);
	LCD_WR_DATA(0x46);
	LCD_WR_DATA(0x0C);
	LCD_WR_DATA(0x17);
	LCD_WR_DATA(0x09);
	LCD_WR_DATA(0x0F);
	LCD_WR_DATA(0x07);
	LCD_WR_DATA(0x00);
	
	/* negative gamma correction */
	LCD_WR_REG(0XE1); 
	LCD_WR_DATA(0x00);
	LCD_WR_DATA(0x19);
	LCD_WR_DATA(0x1B);
	LCD_WR_DATA(0x04);
	LCD_WR_DATA(0x10);
	LCD_WR_DATA(0x07);
	LCD_WR_DATA(0x2A);
	LCD_WR_DATA(0x47);
	LCD_WR_DATA(0x39);
	LCD_WR_DATA(0x03);
	LCD_WR_DATA(0x06);
	LCD_WR_DATA(0x06);
	LCD_WR_DATA(0x30);
	LCD_WR_DATA(0x38);
	LCD_WR_DATA(0x0F);

	/* memroy access control */ /* use with 0x2A and 0x2B to set LCD size and direction */
	LCD_WR_REG(0x36); 
	LCD_WR_DATA(0xC8); 

	/* coloum address set */
	LCD_WR_REG(0X2A); 
	LCD_WR_DATA(0x00);
	LCD_WR_DATA(0x00);
	LCD_WR_DATA(0x01);
	LCD_WR_DATA(0x3F);
	
	/* page address set */
	LCD_WR_REG(0X2B); 
	LCD_WR_DATA(0x00);
	LCD_WR_DATA(0x00);
	LCD_WR_DATA(0x00);
	LCD_WR_DATA(0xEF);

	/* COLMOD:pixel format set */
	LCD_WR_REG(0x3a); 
	LCD_WR_DATA(0x55);
	
	/* sleep out */
	LCD_WR_REG(0x11);
	delayms(10);
	
	/* display on */
	LCD_WR_REG(0x29); 
	
	/* memroy write */	
	LCD_WR_REG(0x2c); 
}

设置窗口范围

/*
*FuncName:	LCD_OpenWindow
*Parameter:	uint16_t x		window start x coordinate 
			uint16_t y		window start y coordinate 
			uint16_t width	window width
			uint16_t height	window height
*Function:	open window
*/
static void LCD_OpenWindow(uint16_t x, uint16_t y, uint16_t width, uint16_t height)
{
	/* coloum address set */
	LCD_WR_REG(0X2A); 
	/* coloum start */
	LCD_WR_DATA(x>>8);		/* high byte */
	LCD_WR_DATA(x&0x00FF);	/* low byte */
	/* coloum end */
	LCD_WR_DATA((x+width-1)>>8);		/* high byte */
	LCD_WR_DATA((x+width-1)&0x00FF);	/* low byte */
	
	/* page address set */
	LCD_WR_REG(0X2B); 
	/* pate start */
	LCD_WR_DATA(y>>8);			/* high byte */   
	LCD_WR_DATA(y&0x00FF);		/* low byte */
	/* pate end */
	LCD_WR_DATA((y+height-1)>>8);  	/* high byte */
	LCD_WR_DATA((y+height-1)&0x00FF);	/* low byte */
	
	/* memory write */
	LCD_WR_REG(0x2C); 
}

画图函数

/*
*FuncName:	LCD_DrawPoint
*Parameter:	uint16_t x		point x coordinate
			uint16_t y		point y coordinate
			uint16_t color	point color
*Function:	draw point on LCD
*/
void LCD_DrawPoint(uint16_t x, uint16_t y, uint16_t color)
{
	LCD_OpenWindow(x, y, 1, 1);
	LCD_WR_DATA(color);
}

/*
*FuncName:	LCD_DrawLine
*Parameter:	uint16_t start_x	start x coordinate
			uint16_t start_y	start y coordinate
			uint16_t end_x		end x coordinate
			uint16_t end_y		end y coordinate
			uint16_t color		line color
*Function:	draw line on LCD
*/
void LCD_DrawLine(uint16_t start_x, uint16_t start_y, uint16_t end_x, uint16_t end_y, uint16_t color)
{
	uint16_t x = 0, y = 0, k = 0;
	
	if((start_x == end_x) && (start_y == end_y))
	{
		LCD_DrawPoint(start_x, start_y, color);
	}
	else if(abs(end_y - start_y) > abs(end_x - start_x))
	{
		if(start_y > end_y)
		{
			k = start_y;
			start_y = end_y;
			end_y = k;
			
			k = start_x;
			start_x = end_x;
			end_x = k;
		}
		for(y = start_y; y < end_y; ++y)
		{
			x = (uint16_t)(y - start_y)*(end_x - start_x) / (end_y - start_y) + start_x;
			LCD_DrawPoint(x, y, color);
		}
	}
	else
	{
		if(start_x > end_x)
		{
			k = start_y;
			start_y = end_y;
			end_y = k;
			
			k = start_x;
			start_x = end_x;
			end_x = k;
		}
		for(x = start_x; x < end_x; ++x)
		{
			y = (uint16_t)(x - start_x)*(end_y - start_y)/ (end_x - start_x) + start_y;
			LCD_DrawPoint(x, y, color);
		}
	}
}

/*
*FuncName:	LCD_DrawRectangle
*Parameter:	uint16_t start_x	start x coordinate
			uint16_t start_y	start y coordinate
			uint16_t end_x		end x coordinate
			uint16_t end_y		end y coordinate
			uint16_t color		rectangle color
*Function:	draw rectangle on LCD
*/
void LCD_DrawRectangle(uint16_t start_x, uint16_t start_y, uint16_t end_x, uint16_t end_y, uint16_t color)
{
	/*
	top-left coordinate(start_x, start_y), bottom-right coordinate(end_x, end_y) 
	 '----------------'
	 '                '
	 '                '
	 '                '
	 '                '
	 '----------------'
	*/
	LCD_DrawLine(start_x, start_y, start_x, end_y, color);
	LCD_DrawLine(start_x, start_y, end_x, start_y, color);
	LCD_DrawLine(end_x, start_y, end_x, end_y, color);
	LCD_DrawLine(start_x, end_y, end_x, end_y, color);
}

/*
*FuncName:	LCD_DrawCircle
*Parameter:	uint16_t x		center x coordinate
			uint16_t y		center y coordinate
			uint16_t radius	circle radius
			uint16_t color	rectangle color
*Function:	draw circle on LCD
*/
void LCD_DrawCircle(uint16_t x, uint16_t y, uint16_t radius, uint16_t color)
{
	uint16_t a,b;
	int16_t di;
	a = 0;
	b = radius;          
	di = 3 - (radius << 1); 
	while(a <= b)
	{
		LCD_DrawPoint(x - b, y - a, color);             //3           
		LCD_DrawPoint(x + b, y - a, color);             //0           
		LCD_DrawPoint(x - a, y + b, color);             //1              
		LCD_DrawPoint(x - a, y - b, color);             //2             
		LCD_DrawPoint(x + b, y + a, color);             //4               
		LCD_DrawPoint(x + a, y - b, color);             //5
		LCD_DrawPoint(x + a, y + b, color);             //6 
		LCD_DrawPoint(x - b, y + a, color);             
		a++;
		/* Bresenham algorithm */ 
		if(di < 0)
		{
			di += 4*a + 6;   
		}			
		else
		{
			di += 10 + 4 * (a - b);   
			b--;
		} 
		LCD_DrawPoint(x + a, y + b, color);
	}
}

/*
*FuncName:	LCD_FillRectangle
*Parameter:	uint16_t x		start x coordinate
			uint16_t y		start y coordinate
			uint16_t len	fill rectangle length
			uint16_t wid	fill rectangle width
			uint16_t color	fill color
*Function:	fill rectangle on LCD
*/
void LCD_FillRectangle(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t color)
{
	uint32_t i = 0;
	LCD_OpenWindow(x, y, height, width);
	for(i = width*height; i >0 ; --i)
	{
		LCD_WR_DATA(color);
	}
/*
*FuncName:	LCD_FillScreen
*Parameter:	uint16_t color	fill color
*Function:	fill whole screen
*/
void LCD_FillScreen(uint16_t color)
{
	LCD_FillRectangle(0, 0, 320, 240, color);
}

/*
*FuncName:	LCD_DispASCIICharacter
*Parameter:	uint16_t x			x coordinate
			uint16_t y			y coordinate
			uint8_t character	character
			uint16_t fColor		front color
			uint16_t bColor		background color
			uint8_t font		the macro of font size
*Function:	display ASCII character on LCD
*/
void LCD_DispASCIICharacter(uint16_t x, uint16_t y, uint8_t character, uint16_t fColor, uint16_t bColor, uint8_t font)
{
	uint16_t width = 0, height = 0;
	uint32_t i = 0, j = 0, k = 0;
	
	height = GetFontWidth(font, ASCII_CHARACTER);
	width = GetFontHeight(font, ASCII_CHARACTER);
	
	LCD_OpenWindow(x, y, x + width - 1, y + height - 1);
	LCD_FillRectangle(x, y, width, height, bColor);
	
	switch(font)
	{
		case FONT_SIZE_24:
			for(k = 0; k < sizeof(codeASCII_24) / sizeof(codeASCII_24[0]); ++k) //搜索
			{
				if(codeASCII_24[k].Index == character)
				{
					for(i = 0; i < 48; ++i) 	// 点阵码数
					{
						uint8_t m = codeASCII_24[k].Msk[i];
						if(i%2)
						{
							for(j = 0; j < 4; ++j)	
							{
								if(m & 0x80)
								{
									LCD_WR_DATA(fColor);
								}
								else 
								{
									LCD_WR_DATA(bColor);
								}
								m <<= 1;
							}
						}
						else
						{
							for(j = 0; j< 8; ++j)
							{
								if(m & 0x80)
								{
									LCD_WR_DATA(fColor);
								}
								else
								{
									LCD_WR_DATA(bColor);
								}
								m <<= 1;
							}
						}
					}
				}
			}
			break;
		default:
			break;
	}
}

/*
*FuncName:	LCD_DispHZCharacter
*Parameter:	uint16_t x			x coordinate
			uint16_t y			y coordinate
			uint8_t index[2]	HZ character
			uint16_t fColor		front color
			uint16_t bColor		background color
			uint8_t font		the macro of font size
*Function:	display HZ character on LCD
*/
void LCD_DispHZCharacter(uint16_t x, uint16_t y, uint8_t index[2], uint16_t fColor, uint16_t bColor, uint8_t font)
{
	uint16_t width = 0, height = 0;
	uint32_t i = 0, j = 0, k = 0;
	
	width = GetFontWidth(font, HZ_CHARACTER);
	height = GetFontHeight(font, HZ_CHARACTER);
	LCD_OpenWindow(x, y, x + width - 1, y + height - 1);
	LCD_FillRectangle(x, y, width, height, bColor);
	
	switch(font)
	{
		case FONT_SIZE_24:
			for(k = 0; k < sizeof(codeHZ_24) / sizeof(codeHZ_24[0]); ++k)
			{
				if((codeHZ_24[k].Index[0] == index[0]) && (codeHZ_24[k].Index[1] == index[1]))
				{
					for(i = 0; i < 72; ++i)
					{
						uint8_t m = codeHZ_24[k].Msk[i];
						for(j = 0; j < 8; ++j)
						{
							if(m & 0x80)
							{
								LCD_WR_DATA(fColor);
							}
							else
							{
								LCD_WR_DATA(bColor);
							}
							m <<= 1;
						}
					}
					break;
				}
			}
			break;
		default:
			break;
	}
}

/*
*FuncName:	LCD_DispPicture1
*Parameter:	uint16_t x			x coordinate
			uint16_t y			y coordinate
			uint16_t width		the picture width
			uint16_t height		the picture height
			uint8_t* str		the pointer of data array
*Function:	display picture on LCD
*/
void LCD_DispPicture1(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint8_t* str)
{
	uint32_t i = 0, j = 0;
	
	LCD_OpenWindow(x, y, width - x , height -y);
	uint16_t tmp;
	j = (width - x)  * (height -y);
	for (i = 0;i < j; i++)
	{
		tmp = (str[i*2] | str[i*2+1]<<8);
		LCD_WR_DATA(tmp);
	}
}
  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值