在前面用TFT-LCD显示图片的实验中,由于图片资源过大,240 * 320 的图片大小为150K,而STM32F103ZET6的内部Flash才512K,最多能放三张图片,所以这次将图片放到外部Flash中,外部Flash芯片为W25Q64,有64Mbit,即8Mbyte,因为1M = 1024KB,所以8M = 8192K,8192K / 150K = 54,所以大概能放54张240 * 320的图片
使用之前写好的SPI_Flash.c源文件和SPI_Flash.h头文件,增加一个读取图片的函数
先在头文件中根据图片大小定好每张图片存放在Flash中的位置
//3张图片在外部Flash的地址,共占用150k * 3 = 450k
#define Pic_Size (uint32_t)153600
#define Flash_Pic1_Addr (uint32_t)0 //第一张图片的地址
#define Flash_Pic2_Addr (uint32_t)Flash_Pic1_Addr+Pic_Size //第二张图片的地址
#define Flash_Pic3_Addr (uint32_t)Flash_Pic2_Addr+Pic_Size //第三张图片的地址
在对Flash芯片操作中添加读取图片资源到TFT-LCD屏幕显示的函数
/**
* @name TranferPicturetoTFT_LCD
* @brief 读取外部Flash图片资源到TFT-LCD显示
* @param Pic_Num:图片序号
* @retval None
*/
static void TranferPicturetoTFT_LCD(uint8_t Pic_Num)
{
uint32_t uiDataLength = Pic_Size;
uint32_t uiPic_Addr = NULL;
uint16_t usPic_Data;
//判断是第几张图片,设置存放位置
switch (Pic_Num)
{
case 1: uiPic_Addr = Flash_Pic1_Addr; break;
case 2: uiPic_Addr = Flash_Pic2_Addr; break;
case 3: uiPic_Addr = Flash_Pic3_Addr; break;
default: uiPic_Addr = Flash_Pic1_Addr; break;
}
//选择Flash芯片:CS输出低电平
CLR_SPI_Flash_CS;
//发送命令,读取数据
SPI_Flash_WriteByte(W25X_ReadData);
//发送地址高字节
SPI_Flash_WriteByte((uiPic_Addr & 0xFF0000) >> 16);
//发送地址中字节
SPI_Flash_WriteByte((uiPic_Addr & 0xFF00) >> 8);
//发送地址低字节
SPI_Flash_WriteByte(uiPic_Addr & 0xFF);
//设置窗口大小
TFT_LCD.LCD_SetWindows(0,0,LCD_WIGHT,LCD_HIGHT);
//开始传输数据
while (uiDataLength)
{
//从Flash读取数据,组成十六位数据
usPic_Data = SPI_Flash_ReadByte();
usPic_Data <<= 8;
usPic_Data += SPI_Flash_ReadByte();
//将数据写入到TFT-LCD屏幕中
LCD_WRITE_DATA(usPic_Data);
uiDataLength-=2;
}
//禁用Flash芯片:CS引脚输出高电平
SET_SPI_Flash_CS;
}
图片数据
const unsigned char gImage_Picture1[153600] = { /* 0X10,0X10,0X00,0XF0,0X01,0X40,0X01,0X1B, */
0XA4,0X0C,0X93,0XCB,0XA4,0X2D,0XAC,0X8E,0XA4,0X0C,0XA4,0X0C,0XB4,0X8E,0XBC,0XAE,
0XAC,0X2D,0XBC,0XAE,0XC4,0XEF,0X8B,0X49,0X8B,0X48,0XAC,0X2C,0XC4,0XCE,0XC4,0XAE,
主函数中先将图片写入到外部Flash中,并在屏幕上显示写入过程,等待写入完成
/*
* @name Run
* @brief 系统运行
* @param Nonee
* @retval None
*/
static void Run()
{
/*************** 将内部Flash的图片保存到外部Flash芯片中 ************** */
uint32_t uiIndex;
const uint8_t * pucic = NULL;
//擦除整个扇区
TFT_LCD.LCD_ShowString(0,48,"Erase total flash chip...",Color_GRAY,Color_RED,ASCII_font_24);
SPI_Flash.SPI_Flash_ChipSector();
//写入第一张图片
TFT_LCD.LCD_ShowString(0,72,"Writing the first image...",Color_GRAY,Color_RED,ASCII_font_24);
pucic = gImage_Picture1;
//写入不定长数据
for(uiIndex = 0; uiIndex < Pic_Size; uiIndex++)
{
SPI_Flash.SPI_Flash_WriteUnfixed((uint8_t*)pucic,(Flash_Pic1_Addr+uiIndex),1);
pucic++;
}
//写入第二张图片
TFT_LCD.LCD_ShowString(0,100,"Writing the second image...",Color_GRAY,Color_RED,ASCII_font_24);
pucic = gImage_Picture2;
//写入不定长数据
for(uiIndex = 0; uiIndex < Pic_Size; uiIndex++)
{
SPI_Flash.SPI_Flash_WriteUnfixed((uint8_t*)pucic,(Flash_Pic2_Addr+uiIndex),1);
pucic++;
}
//写入第三张图片
TFT_LCD.LCD_ShowString(0,130,"Writing the third image...",Color_GRAY,Color_RED,ASCII_font_24);
pucic = gImage_Picture3;
//写入不定长数据
for(uiIndex = 0; uiIndex < Pic_Size; uiIndex++)
{
SPI_Flash.SPI_Flash_WriteUnfixed((uint8_t*)pucic,(Flash_Pic3_Addr+uiIndex),1);
pucic++;
}
//写入完成
TFT_LCD.LCD_ShowString(0,157,"Writing finish",Color_GRAY,Color_RED,ASCII_font_24);
while(1);
}
将主函数中写入图片的那部分去掉,调用前面写的TranferPicturetoTFT_LCD函数,读出图片,因为写入了三张,所以也读出三张
/*
* @name Run
* @brief 系统运行
* @param Nonee
* @retval None
*/
static void Run()
{
/*************** 从外部Flash中读取图片数据,并在TFT-LCD屏上显示 ************** */
SPI_Flash.TranferPicturetoTFT_LCD(1);
HAL_Delay(1000);
SPI_Flash.TranferPicturetoTFT_LCD(2);
HAL_Delay(1000);
SPI_Flash.TranferPicturetoTFT_LCD(3);
HAL_Delay(1000);
}
三张图片每隔1秒进行切换显示