STM32学习之ILI9341控制显示屏输出(二)

上一篇中介绍了ILI9341的相关内容,这一章节主要是介绍初步配置程序:

代码清单(一):主要是配置相关应用接口和GPIO复用引脚:

//以下主要是配置LCD的相应管脚,可以根据上面的PCB信息得到连接的引脚:
void LCD_GPIO_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD|RCC_AHB1Periph_GPIOE|RCC_AHB1Periph_GPIOF
                            |RCC_AHB1Periph_GPIOG,ENABLE);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;  //配置引脚PF10
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
	GPIO_Init(GPIOF,&GPIO_InitStructure);
	
	//配置引脚PD0/PD1/PD4/PD5/PD8/PD9/PD10/PD14/PD15
	GPIO_InitStructure.GPIO_Pin = (3<<0)|(3<<4)|(7<<8)|(3<<14);
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
	GPIO_Init(GPIOD,&GPIO_InitStructure);
	
	//配置引脚PE7-PE15;
	GPIO_InitStructure.GPIO_Pin = (0x1FF<<7);
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
	GPIO_Init(GPIOE,&GPIO_InitStructure);
	
	//配置引脚PG2和PG12
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_12;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
	GPIO_Init(GPIOG,&GPIO_InitStructure);
	
	//配置引脚PD0/PD1/PD4/PD5/PD8/PD9/PD10/PD14/PD15
	GPIO_PinAFConfig(GPIOD,GPIO_PinSource0,GPIO_AF_FSMC);
	GPIO_PinAFConfig(GPIOD,GPIO_PinSource1,GPIO_AF_FSMC);
	GPIO_PinAFConfig(GPIOD,GPIO_PinSource4,GPIO_AF_FSMC);
	GPIO_PinAFConfig(GPIOD,GPIO_PinSource5,GPIO_AF_FSMC);
	GPIO_PinAFConfig(GPIOD,GPIO_PinSource8,GPIO_AF_FSMC);
	GPIO_PinAFConfig(GPIOD,GPIO_PinSource9,GPIO_AF_FSMC);
	GPIO_PinAFConfig(GPIOD,GPIO_PinSource10,GPIO_AF_FSMC);
	GPIO_PinAFConfig(GPIOD,GPIO_PinSource14,GPIO_AF_FSMC);
	GPIO_PinAFConfig(GPIOD,GPIO_PinSource15,GPIO_AF_FSMC);
	
	//配置引脚PE7-PE15
	GPIO_PinAFConfig(GPIOE,GPIO_PinSource7,GPIO_AF_FSMC);
	GPIO_PinAFConfig(GPIOE,GPIO_PinSource8,GPIO_AF_FSMC);
	GPIO_PinAFConfig(GPIOE,GPIO_PinSource9,GPIO_AF_FSMC);
	GPIO_PinAFConfig(GPIOE,GPIO_PinSource10,GPIO_AF_FSMC);
	GPIO_PinAFConfig(GPIOE,GPIO_PinSource11,GPIO_AF_FSMC);
	GPIO_PinAFConfig(GPIOE,GPIO_PinSource12,GPIO_AF_FSMC);
	GPIO_PinAFConfig(GPIOE,GPIO_PinSource13,GPIO_AF_FSMC);
	GPIO_PinAFConfig(GPIOE,GPIO_PinSource14,GPIO_AF_FSMC);
	GPIO_PinAFConfig(GPIOE,GPIO_PinSource15,GPIO_AF_FSMC);
	
	//配置复用引脚PG2和PG12;
	GPIO_PinAFConfig(GPIOG,GPIO_PinSource2,GPIO_AF_FSMC);
	GPIO_PinAFConfig(GPIOG,GPIO_PinSource12,GPIO_AF_FSMC);
	
} 

代码清单(二):主要是配置STM32单片机内部的FSMC:


void LCD_Config(void)
{
  FSMC_NORSRAMInitTypeDef FSMC_InitStructure;
	FSMC_NORSRAMTimingInitTypeDef readTiming;
	FSMC_NORSRAMTimingInitTypeDef writeTiming;
	RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FSMC,ENABLE);
	
	//配置时序:readTiming结构体
	readTiming.FSMC_AddressSetupTime = 0xF;//地址建立时间
	readTiming.FSMC_AddressHoldTime = 0x01;//地址保持时间
	readTiming.FSMC_DataSetupTime = 0x3C;  //数据建立时间
	readTiming.FSMC_BusTurnAroundDuration = 0x01;//总线转换时间
	readTiming.FSMC_CLKDivision = 0x00;   //时钟分频因子
	readTiming.FSMC_DataLatency = 0x00;//数据延迟时间
	readTiming.FSMC_AccessMode = FSMC_AccessMode_A;//设置存储器访问模式
	
	//配置写时序结构体:writeTiming结构体
	writeTiming.FSMC_AddressSetupTime = 0x08;
	writeTiming.FSMC_AddressHoldTime = 0x01;
	writeTiming.FSMC_DataSetupTime = 0x07;
	writeTiming.FSMC_BusTurnAroundDuration = 0x00;
	writeTiming.FSMC_CLKDivision = 0x00;
	writeTiming.FSMC_DataLatency = 0x00;
	writeTiming.FSMC_AccessMode = FSMC_AccessMode_A;
	
	//配置FSMC初始化结构体
	FSMC_InitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM1;//用于选择FSMC映射的存储区域
	FSMC_InitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;//设置地址总线与
                                                                         //数据总线是否复
                                                                         //用;
	FSMC_InitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM;//用于设置需要控制的存储器类
                                                              //型
	FSMC_InitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;//设置数据宽度
	FSMC_InitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;//设置是否使用
                                                                           //突发模式
	FSMC_InitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable;//设置是否使
                                                           //能数据同步传输时使用使能信号
	FSMC_InitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;//设置等待信
                                                           //号的有效极性
	FSMC_InitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;//设置是否支持把非对称AHB突发
                                                           //操作分割成两次线性操作
	FSMC_InitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;//
	FSMC_InitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;//
	FSMC_InitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable; //
	FSMC_InitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Enable;//
	FSMC_InitStructure.FSMC_ReadWriteTimingStruct = &readTiming;
	FSMC_InitStructure.FSMC_WriteTimingStruct = &writeTiming;
	FSMC_NORSRAMInit(&FSMC_InitStructure);
	FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM4,ENABLE);//ʹÄÜBank1£»
	delay_ms(50);
	
}

下一节将会介绍如何在LCD中写英文和画点

  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STM32F4芯片上使用ILI9341显示汉字需要涉及到汉字的编码问题和字库的存储问题。以下是一个简单的代码示例,可以输出“张翼鹏”这三个汉字。 1. 字库存储 将汉字的字库存储到外部FLASH或SD卡中,然后通过读取字库数据进行汉字的显示。这里我们假设字库数据已经存储在外部FLASH中,首先需要将字库数据读取到内存中。 ```c #define FONT_SIZE 24 // 汉字字库大小 #define FONT_ADDR 0x08040000 // 外部FLASH中存储字库的地址 uint8_t font_buf[FONT_SIZE * 2]; // 存储读取到的字库数据 void read_font(uint16_t index) { uint32_t addr = FONT_ADDR + index * FONT_SIZE * 2; for (int i = 0; i < FONT_SIZE * 2; i += 2) { uint16_t data = *(volatile uint16_t *)addr; font_buf[i] = data & 0xFF; // 取低8位 font_buf[i + 1] = data >> 8; // 取高8位 addr += 2; } } ``` 2. 汉字编码 汉字编码采用Unicode编码,每个汉字用两个字节表示。在Unicode编码中,“张翼鹏”这三个汉字分别对应的编码为0x5f20、0x7ffc和0x9e1f。需要注意的是,在STM32F4芯片上使用的是小端模式,因此需要将高位字节放在前面,低位字节放在后面。 ```c uint16_t utf8_to_unicode(uint8_t *utf8_str) { uint16_t unicode = 0; if ((utf8_str[0] & 0x80) == 0x00) { // 单字节编码 unicode = utf8_str[0]; } else if ((utf8_str[0] & 0xE0) == 0xC0) { // 双字节编码 unicode = ((utf8_str[0] & 0x1F) << 6) | (utf8_str[1] & 0x3F); } else if ((utf8_str[0] & 0xF0) == 0xE0) { // 三字节编码 unicode = ((utf8_str[0] & 0x0F) << 12) | ((utf8_str[1] & 0x3F) << 6) | (utf8_str[2] & 0x3F); } return unicode; } uint16_t get_unicode(uint8_t *str) { uint16_t unicode = 0; if (str[0] == 0xE5 && str[1] == 0xBC && str[2] == 0xA0) { // 张 unicode = 0x5f20; } else if (str[0] == 0xE7 && str[1] == 0xBF && str[2] == 0xBC) { // 翼 unicode = 0x7ffc; } else if (str[0] == 0xE9 && str[1] == 0xB9 && str[2] == 0x9F { // 鹏 unicode = 0x9e1f; } return unicode; } ``` 3. 汉字绘制 使用ILI9341显示屏输出汉字需要将字库数据写入到ILI9341的GRAM中,然后设置GRAM中每个像素的颜色值,最后通过SPI接口将GRAM中的数据发送给ILI9341。以下是一个简单的代码示例,可以输出“张翼鹏”这三个汉字。 ```c #define LCD_WIDTH 240 // 显示屏宽度 #define LCD_HEIGHT 320 // 显示屏高度 #define LCD_CS_LOW() GPIO_ResetBits(GPIOA, GPIO_Pin_4) #define LCD_CS_HIGH() GPIO_SetBits(GPIOA, GPIO_Pin_4) #define LCD_DC_LOW() GPIO_ResetBits(GPIOA, GPIO_Pin_3) #define LCD_DC_HIGH() GPIO_SetBits(GPIOA, GPIO_Pin_3) void lcd_write_cmd(uint8_t cmd) { LCD_CS_LOW(); LCD_DC_LOW(); SPI_I2S_SendData(SPI1, cmd); while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET); LCD_CS_HIGH(); } void lcd_write_data(uint8_t data) { LCD_CS_LOW(); LCD_DC_HIGH(); SPI_I2S_SendData(SPI1, data); while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET); LCD_CS_HIGH(); } void lcd_set_pos(uint16_t x, uint16_t y) { lcd_write_cmd(0x2A); lcd_write_data(x >> 8); lcd_write_data(x & 0xFF); lcd_write_data((x + FONT_SIZE - 1) >> 8); lcd_write_data((x + FONT_SIZE - 1) & 0xFF); lcd_write_cmd(0x2B); lcd_write_data(y >> 8); lcd_write_data(y & 0xFF); lcd_write_data((y + FONT_SIZE - 1) >> 8); lcd_write_data((y + FONT_SIZE - 1) & 0xFF); lcd_write_cmd(0x2C); } void lcd_draw_char(uint16_t x, uint16_t y, uint8_t *str) { uint16_t unicode = utf8_to_unicode(str); uint16_t index = (unicode - 0x4E00) * FONT_SIZE; // 计算字库数据的偏移量 read_font(index); lcd_set_pos(x, y); for (int i = 0; i < FONT_SIZE; i++) { uint8_t data = font_buf[i]; for (int j = 0; j < 8; j++) { uint16_t color = (data & 0x80) ? 0xFFFF : 0x0000; // 根据字库数据设置颜色值 lcd_write_data(color >> 8); lcd_write_data(color & 0xFF); data <<= 1; } } } void lcd_draw_string(uint16_t x, uint16_t y, uint8_t *str) { while (*str) { uint16_t unicode = get_unicode(str); if (unicode) { lcd_draw_char(x, y, str); x += FONT_SIZE; } str += 3; } } int main(void) { // 初始化SPI和GPIO // ... lcd_write_cmd(0x36); lcd_write_data(0x48); // RGB旋转180度 lcd_write_cmd(0x3A); lcd_write_data(0x05); // 16位色深 lcd_write_cmd(0x29); // 开始显示 lcd_draw_string(0, 0, "张翼鹏"); while (1); } ``` 上述代码仅供参考,具体实现还需要根据具体情况进行调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值