求适配STM32F401RE的16位并行ILI9341 TFT驱动代码
适配STM32F401RE的16位并行ILI9341驱动方案
一、先判断ILI9341的16位并行接口类型(I型/II型)
两种接口的核心差异是数据总线与控制器寄存器的映射关系:
- I型:模块的D0D15直接对应ILI9341的DB0DB15
- II型:模块的D0D15对应ILI9341的DB1DB16(最低位悬空,数据位偏移1位)
验证方法:完成驱动初始化后,尝试填充纯色(如红色0xF800),若显示偏色或乱码,则切换接口映射方式重试。
二、无FSMC的GPIO模拟16位并行驱动思路
STM32F401RE无FSMC外设,需通过GPIO模拟ILI9341的并行时序,核心是模拟**WR(写使能)、DC(数据/命令选择)、CS(片选)**以及16位数据总线的读写逻辑。
三、HAL库驱动代码示例
1. 引脚定义(根据硬件接线修改)
// 控制引脚 #define TFT_CS_PIN GPIO_PIN_0 #define TFT_CS_PORT GPIOA #define TFT_DC_PIN GPIO_PIN_1 #define TFT_DC_PORT GPIOA #define TFT_WR_PIN GPIO_PIN_2 #define TFT_WR_PORT GPIOA // 16位数据总线(示例用GPIOB的PB0~PB15) #define TFT_DATA_PORT GPIOB
2. 基础时序函数
// 片选使能 static void TFT_CS_Enable(void) { HAL_GPIO_WritePin(TFT_CS_PORT, TFT_CS_PIN, GPIO_PIN_RESET); } // 片选禁用 static void TFT_CS_Disable(void) { HAL_GPIO_WritePin(TFT_CS_PORT, TFT_CS_PIN, GPIO_PIN_SET); } // 切换到命令模式 static void TFT_Set_Command_Mode(void) { HAL_GPIO_WritePin(TFT_DC_PORT, TFT_DC_PIN, GPIO_PIN_RESET); } // 切换到数据模式 static void TFT_Set_Data_Mode(void) { HAL_GPIO_WritePin(TFT_DC_PORT, TFT_DC_PIN, GPIO_PIN_SET); } // 模拟16位数据写时序 static void TFT_Write_Data16(uint16_t data) { // 直接操作GPIO寄存器提升速度 TFT_DATA_PORT->BRR = 0xFFFF; // 清零数据总线 TFT_DATA_PORT->BSRR = data; // 写入16位数据 // 触发WR写脉冲 HAL_GPIO_WritePin(TFT_WR_PORT, TFT_WR_PIN, GPIO_PIN_RESET); __NOP();__NOP();__NOP();__NOP(); // 短延时,根据硬件调整 HAL_GPIO_WritePin(TFT_WR_PORT, TFT_WR_PIN, GPIO_PIN_SET); } // 写入命令(默认按I型接口,异常则改为II型:cmd | 0x0100) static void TFT_Write_Command(uint8_t cmd) { TFT_Set_Command_Mode(); TFT_CS_Enable(); TFT_Write_Data16((uint16_t)cmd); // I型接口 // TFT_Write_Data16((uint16_t)(cmd | 0x0100)); // II型接口,异常时启用 TFT_CS_Disable(); } // 写入16位数据 static void TFT_Write_Data(uint16_t data) { TFT_Set_Data_Mode(); TFT_CS_Enable(); TFT_Write_Data16(data); TFT_CS_Disable(); }
3. ILI9341初始化函数
void ILI9341_Init(void) { // 若硬件有RST引脚,添加复位逻辑(拉低→延时→拉高→延时) // 发送ILI9341标准初始化命令序列 TFT_Write_Command(0x01); // 软件复位 HAL_Delay(100); TFT_Write_Command(0xCF); TFT_Write_Data(0x00); TFT_Write_Data(0x83); TFT_Write_Data(0X30); TFT_Write_Command(0xED); TFT_Write_Data(0x64); TFT_Write_Data(0x03); TFT_Write_Data(0X12); TFT_Write_Data(0X81); TFT_Write_Command(0xE8); TFT_Write_Data(0x85); TFT_Write_Data(0x01); TFT_Write_Data(0x79); TFT_Write_Command(0xCB); TFT_Write_Data(0x39); TFT_Write_Data(0x2C); TFT_Write_Data(0x00); TFT_Write_Data(0x34); TFT_Write_Data(0x02); TFT_Write_Command(0xF7); TFT_Write_Data(0x20); TFT_Write_Command(0xEA); TFT_Write_Data(0x00); TFT_Write_Data(0x00); TFT_Write_Command(0xC0); // 电源控制 TFT_Write_Data(0x26); TFT_Write_Command(0xC1); // 电源控制 TFT_Write_Data(0x11); TFT_Write_Command(0xC5); // VCOM控制 TFT_Write_Data(0x35); TFT_Write_Data(0x3E); TFT_Write_Command(0xC7); // VCOM控制 TFT_Write_Data(0xBE); TFT_Write_Command(0x36); // 内存访问控制(0x48为默认竖屏,可根据需求调整) TFT_Write_Data(0x48); TFT_Write_Command(0x3A); // 像素格式设置(16位) TFT_Write_Data(0x55); TFT_Write_Command(0xB1); // 帧率控制 TFT_Write_Data(0x00); TFT_Write_Data(0x1B); TFT_Write_Command(0xF2); // 禁用3G模式 TFT_Write_Data(0x00); TFT_Write_Command(0x26); // Gamma设置 TFT_Write_Data(0x01); // 正Gamma校正 TFT_Write_Command(0xE0); TFT_Write_Data(0x0F);TFT_Write_Data(0x22);TFT_Write_Data(0x1C);TFT_Write_Data(0x1B); TFT_Write_Data(0x08);TFT_Write_Data(0x0F);TFT_Write_Data(0x48);TFT_Write_Data(0xB8); TFT_Write_Data(0x34);TFT_Write_Data(0x05);TFT_Write_Data(0x0C);TFT_Write_Data(0x09); TFT_Write_Data(0x0F);TFT_Write_Data(0x07);TFT_Write_Data(0x00); // 负Gamma校正 TFT_Write_Command(0xE1); TFT_Write_Data(0x00);TFT_Write_Data(0x23);TFT_Write_Data(0x24);TFT_Write_Data(0x07); TFT_Write_Data(0x10);TFT_Write_Data(0x07);TFT_Write_Data(0x38);TFT_Write_Data(0x47); TFT_Write_Data(0x4B);TFT_Write_Data(0x0A);TFT_Write_Data(0x13);TFT_Write_Data(0x06); TFT_Write_Data(0x30);TFT_Write_Data(0x38);TFT_Write_Data(0x0F); TFT_Write_Command(0x29); // 开启显示 }
4. 全屏填充示例函数
void ILI9341_Fill_Screen(uint16_t color) { uint32_t pixel_count = 320 * 240; // 设置列地址(0~319) TFT_Write_Command(0x2A); TFT_Write_Data(0x00);TFT_Write_Data(0x00); TFT_Write_Data(0x01);TFT_Write_Data(0x3F); // 设置页地址(0~239) TFT_Write_Command(0x2B); TFT_Write_Data(0x00);TFT_Write_Data(0x00); TFT_Write_Data(0x00);TFT_Write_Data(0xEF); // 连续写入像素数据 TFT_Write_Command(0x2C); TFT_Set_Data_Mode(); TFT_CS_Enable(); for(uint32_t i=0; i<pixel_count; i++) { TFT_Write_Data16(color); } TFT_CS_Disable(); }
四、关键注意事项
- 所有GPIO引脚需提前配置为推挽输出模式,速度等级设为高速(High Speed)。
- 若显示异常,切换
TFT_Write_Command()中的命令写入方式(I型/II型)。 - 若追求更高帧率,可替换
HAL_GPIO函数为直接操作GPIO寄存器(如BSRR/BRR),减少函数调用开销。
内容的提问来源于stack exchange,提问作者JOAQUÍN PIÑEIRO
相关产品推荐
相关产品推荐

