lcd.c
typedef struct _LCD_DRV{
uint32_t (*checkid)(void);
void (*init)(void);
void (*setpixel)(uint16_t color, uint16_t x, uint16_t y);
void (*fillrect)(uint16_t color, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1);
void (*bitmap)(uint16_t color[], uint16_t x0, uint16_t y0, uint16_t width, uint16_t height);
void (*clear)(uint16_t color);
int (*ioctrl)(uint32_t cmd, uint32_t param);
uint16_t (*getpixel)(uint16_t x, uint16_t y);
}lcd_drv_t;
const lcd_drv_t* lcd_module[] = {
&nt35510_module,
&st7789v_module,
/*any other lcd module*/
};
const lcd_drv_t *lcd_drv = 0;
void LCD_GPIO_Cfg(void)
{
/*由于FMC的GPIO已由CubeMx自动配置,所以这里只设置RESET引脚*/
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
void LCD_FMC_Cfg(void)
{
/*
由于STM32 CubeMx已自动生成相关FMC配置的代码,
所以这里就无需额外设置
*/
}
void LCD_Reset(void)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);
delay_ms(100);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET);
delay_ms(100);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);
delay_ms(100);
}
uint8_t LCD_CheckID(void)
{
uint32_t id;
int i;
for(i = 0; i < (sizeof(lcd_module) / sizeof(lcd_module[0])); i++)
{
id = lcd_module[i]->checkid();
if(0 != id)
{
printf("Found ID: %x\r\n", id);
lcd_drv = lcd_module[i];
return 1;
}
}
return 0;
}
void LCD_Init(void)
{
LCD_GPIO_Cfg();
LCD_FMC_Cfg();
LCD_Reset();
if(LCD_CheckID())
{
lcd_drv->init();
}
}
void LCD_DrawPixel(uint16_t color, uint16_t x, uint16_t y)
{
if(lcd_drv)
lcd_drv->setpixel(color, x, y);
}
void LCD_FillRect(uint16_t color, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1)
{
if(lcd_drv)
lcd_drv->fillrect(color, x0, y0, x1, y1);
}
void LCD_DrawBitmap(uint16_t color[], uint16_t x0, uint16_t y0, uint16_t width, uint16_t height)
{
if(lcd_drv)
lcd_drv->bitmap(color, x0, y0, width, height);
}
void LCD_Clear(uint16_t color)
{
if(lcd_drv)
lcd_drv->clear(color);
}
void NT35510_WriteReg(uint16_t LCD_Reg, uint16_t LCD_RegValue)
{
LCD_WR_REG(LCD_Reg);
LCD_WR_DATA(LCD_RegValue);
}
uint16_t NT35510_ReadReg(uint16_t LCD_Reg)
{
LCD_WR_REG(LCD_Reg); //写入要读的寄存器序号
delay_us(5);
return LCD_RD_DATA(); //返回读到的值
}
//开始写GRAM
void NT35510_WriteRAM_Prepare(void)
{
LCD_WR_REG(0X2C00);
}
void NT35510_DisplayOn(void)
{
LCD_WR_REG(0X2900); //开启显示
}
void NT35510_DisplayOff(void)
{
LCD_WR_REG(0X2800); //关闭显示
}
void NT35510_SetWindow(uint16_t x0,uint16_t y0,uint16_t x1,uint16_t y1)
{
NT35510_WriteReg(0x2A00, x0 >> 8);
NT35510_WriteReg(0x2A01, x0 & 0XFF);
NT35510_WriteReg(0x2A02, x1 >> 8);
NT35510_WriteReg(0x2A03, x1 & 0XFF);
NT35510_WriteReg(0x2B00, y0 >> 8);
NT35510_WriteReg(0x2B01, y0 & 0XFF);
NT35510_WriteReg(0x2B02, y1 >> 8);
NT35510_WriteReg(0x2B03, y1 & 0XFF);
}
void NT35510_DrawPixel(uint16_t color, uint16_t x, uint16_t y)
{
NT35510_SetWindow(x, y, x, y); //设置光标位置
NT35510_WriteRAM_Prepare(); //开始写入GRAM
LCD_WR_DATA(color);
}
//清屏函数
void NT35510_Clear(uint16_t color)
{
uint32_t i;
NT35510_SetWindow(0, 0, Width - 1, Height - 1);
NT35510_WriteRAM_Prepare();
for(i = 0; i < Width * Height; i++)
{
LCD_WR_DATA(color);
}
}
uint32_t NT35510_CheckID(void)
{
uint8_t id1, id2, id3;
id1 = NT35510_ReadReg(0XDA00); //should be 0x00
id2 = NT35510_ReadReg(0XDB00); //should be 0x80
id3 = NT35510_ReadReg(0XDC00); //should be 0x00
printf(" Read ID:%x, %x, %x\r\n", id1, id2, id3);
if((id1 == 0x00) && (id2 == 0x80) && (id3 == 0x00))
return 0x35510;
else
return 0;
}
void NT35510_Init(void)
{
delay_ms(50);
NT35510_WriteReg(0x0000,0x0001);
delay_ms(50);
NT35510_WriteReg(0xF000,0x55);
NT35510_WriteReg(0xF001,0xAA);
NT35510_WriteReg(0xF002,0x52);
NT35510_WriteReg(0xF003,0x08);
NT35510_WriteReg(0xF004,0x01);
......
}
void NT35510_FillRect(uint16_t color, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1)
{
uint32_t i;
uint16_t width, height;
width = x1-x0+1;
height = y1-y0+1;
NT35510_SetWindow(x0, y0, x1, y1);
NT35510_WriteRAM_Prepare();
for(i = 0; i < width * height; i++)
{
LCD_WR_DATA(color);
}
}
//位图显示函数,位图中每个像素大小为16bit,高字节在前低字节在后
void NT35510_DrawBitmap(uint16_t color[], uint16_t x0, uint16_t y0, uint16_t width, uint16_t height)
{
uint32_t i;
uint16_t x1, y1;
x1 = x0 + width - 1;
y1 = y0 + height - 1;
NT35510_SetWindow(x0, y0, x1, y1);
NT35510_WriteRAM_Prepare();
for(i = 0; i < width * height; i++)
{
LCD_WR_DATA(color[i]);
}
}
int NT35510_IOCtrl(uint32_t cmd, uint32_t param)
{
switch(cmd)
{
case LCD_CMD_SLEEP_IN:
break;
case LCD_CMD_SLEEP_OUT:
break;
case LCD_CMD_SET_DIR:
break;
default:
break;
}
return 0;
}
const lcd_drv_t nt35510_module = {
NT35510_CheckID,
NT35510_Init,
NT35510_DrawPixel,
NT35510_FillRect,
NT35510_DrawBitmap,
NT35510_Clear,
NT35510_IOCtrl
};
实验效果图片如下: