正点原子学习小组
直播中

知之为知之zhl

4年用户 99经验值
擅长:可编程逻辑 电源/新能源
私信 关注

【正点原子STM32战舰V4开发板免费试用】使用外部 SRAM 存放显示缓存

800*480分辨率的屏幕需要的缓存较大,放在外部的SRAM里面更为方便

用cubemx配置FSMC驱动SRAM

先打开战舰V4的原理图查看开发板上外部SRAM的接口。

-

片选管脚连接到了FSMC的NE3端口,地址为19位,数据为16位,设置一下cubemx,时序配置为0;4;0

-

生成代码,我这里是用的Makefile

把显存放在SRAM中,代码如下

static uint16_t color_buf[480 * 800] __attribute__((section(".ext_sram")));  
//分配到外部1MB sram的最起始处

然后需要修改链接文件,在 STM32F103ZETx_FLASH.ld 文件中修改两处,在MEMORY中添加EXTSRAM和地址、大小信息;在下方 SECTIONS 中添加 ext_sram 节区。

MEMORY
{
RAM (xrw)      : ORIGIN = 0x20000000, LENGTH = 64K
EXTSRAM (xrw)  : ORIGIN = 0X68000000, LENGTH = 1024K
FLASH (rx)      : ORIGIN = 0x8000000, LENGTH = 512K
}
/* external sram data, do not initialize at startup  */
  .ext_sram(NOLOAD) :
  {
    . = ALIGN(4);
    _sext_sram = .;        /* create a global symbol at ext_sram start */
    *(.ext_sram)
    *(.ext_sram*)

    . = ALIGN(4);
    _eext_sram = .;        /* define a global symbol at ext_sram end */
  } >EXTSRAM AT> FLASH

SRAM 的测试代码如下

#include "sram.h"

#include <stdio.h>

/* SRAM基地址, 根据 SRAM_FSMC_NEX 的设置来决定基址地址
 * 我们一般使用FSMC的块1(BANK1)来驱动SRAM, 块1地址范围总大小为256MB,均分成4块:
 * 存储块1(FSMC_NE1)地址范围: 0X6000 0000 ~ 0X63FF FFFF
 * 存储块2(FSMC_NE2)地址范围: 0X6400 0000 ~ 0X67FF FFFF
 * 存储块3(FSMC_NE3)地址范围: 0X6800 0000 ~ 0X6BFF FFFF
 * 存储块4(FSMC_NE4)地址范围: 0X6C00 0000 ~ 0X6FFF FFFF
 */
#define EXT_SRAM_ADDR ((uint32_t)0x68000000)
#define EXT_SRAM_SIZE (1 * 1024 * 1024)

/*
*********************************************************************************************************
*	函 数 名: bsp_TestExtSRAM
*	功能说明: 扫描测试外部SRAM的全部单元。
*	形    参: 无
*	返 回 值: 0 表示测试通过; 大于0表示错误单元的个数。
*********************************************************************************************************
*/
uint32_t bsp_test_sram(void) {
    uint32_t i;
    uint32_t *pSRAM;
    uint8_t *pBytes;
    uint32_t err;
    const uint8_t ByteBuf[4] = {0x55, 0xA5, 0x5A, 0xAA};

    /* 写SRAM */
    pSRAM = (uint32_t *)EXT_SRAM_ADDR;
    for (i = 0; i < EXT_SRAM_SIZE / 4; i++) {
        *pSRAM++ = i;
    }

    /* 读SRAM */
    err = 0;
    pSRAM = (uint32_t *)EXT_SRAM_ADDR;
    for (i = 0; i < EXT_SRAM_SIZE / 4; i++) {
        if (*pSRAM++ != i) {
            err++;
        }
    }
    printf("SDRAM check round 1 error = %u\r\n", err);
    if (err > 0) {
        return (4 * err);
    }

#if 1
    /* 对SRAM 的数据求反并写入 */
    pSRAM = (uint32_t *)EXT_SRAM_ADDR;
    for (i = 0; i < EXT_SRAM_SIZE / 4; i++) {
        *pSRAM = ~*pSRAM;
        pSRAM++;
    }

    /* 再次比较SRAM的数据 */
    err = 0;
    pSRAM = (uint32_t *)EXT_SRAM_ADDR;
    for (i = 0; i < EXT_SRAM_SIZE / 4; i++) {
        if (*pSRAM++ != (~i)) {
            err++;
        }
    }

    printf("SDRAM check round 2 error = %u\r\n", err);
    if (err > 0) {
        return (4 * err);
    }
#endif

    /* 测试按字节方式访问, 目的是验证 FSMC_NBL0 、 FSMC_NBL1 口线 */
    pBytes = (uint8_t *)EXT_SRAM_ADDR;
    for (i = 0; i < sizeof(ByteBuf); i++) {
        *pBytes++ = ByteBuf[i];
    }

    /* 比较SRAM的数据 */
    err = 0;
    pBytes = (uint8_t *)EXT_SRAM_ADDR;
    for (i = 0; i < sizeof(ByteBuf); i++) {
        if (*pBytes++ != ByteBuf[i]) {
            err++;
        }
    }
    printf("SDRAM check round 3 error = %u\r\n", err);
    if (err > 0) {
        return err;
    }
    return 0;
}

测试通过

-

更多回帖

发帖
×
20
完善资料,
赚取积分