前言
為32F429DISCOVERY加入Fatst,讓我們可以從SD 卡中直接讀取BMP圖檔
MCU I/O配置
- SPI3:CS(PE2),SCK(PB3),MOSI(PC11),MISO(PC12)
- UART1:TX(PA9),RX(PA10)
- Timer:1ms
- RTC
操作步驟
1. 加入FatFS
參照此篇教學 STM32 + FatFs + SD card via SPI【一】移植FatFS
這邊列出跟教學因平台不同的地方
diskio.c
#include "diskio.h"
#include "ff.h" /* Obtains integer types */
#include "diskio.h" /* Declarations of disk functions */
#include "stm32f429i_discovery.h"
#define _BV(bit) (1<<(bit))
#define SPI_CH 1 /* SPI channel to use = 1: SPI1, 11: SPI1/remap, 2: SPI2 */
#define FCLK_SLOW() { SPI3->CR1 = (SPIx_CR1 & ~0x38) | SPI_BAUDRATEPRESCALER_128; } /* Set SCLK = PCLK / 128=281khz */
#define FCLK_FAST() { SPI3->CR1 = (SPIx_CR1 & ~0x38) | SPI_BAUDRATEPRESCALER_2; } /* Set SCLK = PCLK / 2 */
#if SPI_CH == 1 /* PA4:MMC_CS, PA5:MMC_SCLK, PA6:MMC_DO, PA7:MMC_DI, PC4:MMC_CD */
#define CS_HIGH() HAL_GPIO_WritePin(GPIOE,GPIO_PIN_2,GPIO_PIN_SET)//GPIOA_BSRR = _BV(4)
#define CS_LOW() HAL_GPIO_WritePin(GPIOE,GPIO_PIN_2,GPIO_PIN_RESET)//GPIOA_BSRR = _BV(4+16)
#define MMC_CD 1//!(GPIOC_IDR & _BV(4)) /* Card detect (yes:true, no:false, default:true) */
#define MMC_WP 0 /* Write protected (yes:true, no:false, default:false) */
#define SPIx_CR1 SPI3->CR1//SPI1_CR1
#define SPIx_SR SPI3->SR//SPI1_SR
#define SPIx_DR SPI3->DR//SPI1_DR
#define SPIxENABLE() {\
}
static BYTE xchg_spi (
BYTE dat /* Data to send */
)
{
// SPIx_DR = dat; /* Start an SPI transaction */
// while ((SPIx_SR & 0x83) != 0x03) ; /* Wait for end of the transaction */
// return (BYTE)SPIx_DR; /* Return received byte */
uint8_t tx[2] = {dat};
uint8_t rx[2] = {0};
extern SPI_HandleTypeDef hspi3;
HAL_SPI_TransmitReceive(&hspi3, tx, rx, 1, 0xFFFF);
return rx[0];
}
記得確認指令 di(初始SD卡) / fi(掛載系統) / fo(讀檔) / fd(輸出)都能正常使用
2.
把上一篇載入圖檔的函式刪除
int main(void)
{
SDRAM_Initialization_Sequence(&hsdram1, &command);
//HAL_SDRAM_Write_16b(&hsdram1, (uint32_t*)SDRAM_BANK_ADDR, ST_LOGO_1, (240*320));//刪除
}
3.
因為一般BMP圖檔都是RGB888(24bit),
所以把LTDC的Layer - Pixel Format改為RGB888
4.
在main()裡頭加入,按鍵切換圖片
BPM圖檔前54(0x36) bytes是檔案header,所以在讀檔時要跳過前header
CLI菜單因為是使用blocking的模式,記得刪除/取消
int main(void)
{
static uint8_t i3 = 0;
static uint32_t offset = 0;
for(;;)
{
if(HAL_GPIO_ReadPin(GPIOA,B1_Pin) == 1)
{
HAL_GPIO_TogglePin(LD3_GPIO_Port, LD3_Pin);
xprintf("rc=%d\n", (uint32_t)disk_initialize((uint8_t)0));//"di 0"
put_rc(f_mount(&FatFs, "", (BYTE)0));//"fi 0"
switch(i3)
{
case 0:
put_rc(f_open(&File[0], "st_logo1.bmp", (BYTE)1));
break;
case 1:
put_rc(f_open(&File[0], "st_logo2.bmp", (BYTE)1));
break;
case 2:
put_rc(f_open(&File[0], "st_logo3.bmp", (BYTE)1));
break;
case 3:
put_rc(f_open(&File[0], "st_logo4.bmp", (BYTE)1));
break;
default:
i3 = 0;
break;
}
i3++;
i3 = i3 % 4;
p1 = 240*320*3;
offset = 0;
cnt = 0x36;
res = f_read(&File[0], Buff, cnt, &cnt);// ignore BMP header
while (p1) {
if ((UINT)p1 >= 2400) { cnt = 2400; p1 -= 2400; }
else { cnt = p1; p1 = 0; }
res = f_read(&File[0], Buff, cnt, &cnt);
if (res != FR_OK) { put_rc(res); break; }
if (!cnt) break;
HAL_SDRAM_Write_8b(&hsdram1, (uint32_t*)(SDRAM_BANK_ADDR+offset), Buff, cnt);
offset += cnt;
}
put_rc(f_close(&File[0]));
osDelay(300);
}
// FileSystemCLI();//記得取消CLI菜單
}
/* USER CODE END 5 */
}
程式裡是依序讀取st_logo1.bmp到st_logo4.bmp
附上程式碼 F429I_LTDC_v03.7z
4個BMP圖檔也附在壓縮檔裡