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 };
实验效果图片如下:
STM32F429 Discovery FMC驱动原子4.3寸LCD
原文:http://blog.csdn.net/hexiaolong2009/article/details/45273035