32F429IDISCOVERY - - LTDC [3] + FMC (SDRAM) + FatFS

前言

為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圖檔也附在壓縮檔裡