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);
}
}