OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 521|回复: 0

《M144Z-M3最小系统板使用指南——STM32F103版》第四十四章 外部SRAM实验

[复制链接]

1117

主题

1128

帖子

2

精华

超级版主

Rank: 8Rank: 8

积分
4667
金钱
4667
注册时间
2019-5-8
在线时间
1224 小时
发表于 2024-5-14 17:31:45 | 显示全部楼层 |阅读模式
本帖最后由 正点原子运营 于 2024-5-13 11:08 编辑

第四十四章 外部SRAM实验
1)实验平台:正点原子 M144Z-M3 STM32F103最小系统板

2) 章节摘自【正点原子】M144Z-M3最小系统板使用指南——STM32F103版

3)购买链接:https://detail.tmall.com/item.htm?&id=609293737870

4)全套实验源码+手册+视频下载地址:http://www.openedv.com/docs/boar ... _mini_sysboard.html

5)正点原子官方B站:https://space.bilibili.com/394620890

6)正点原子STM32技术交流QQ群:725095144

155537c2odj87vz1z9vj6l.jpg

155537nfqovl2gg9faaol9.png

本章将介绍使用STM32F103驱动SRAM进行SRAM的数据读写。通过本章的学习,读者将学习到EMMC中SMC的使用。
本章分为如下几个小节:
44.1 硬件设计
44.2 程序设计
44.3 下载验证

44.1 硬件设计
44.1.1 例程功能
1. 程序运行后,可通过按下KEY0和KEY_UP按键,分别进行SRAM的容量和数据测试,测试结果将在LCD上显示
2. 可通过USMART对外部SRAM进行数据读写的测试操作
3. LED0闪烁,指示程序正在运行

44.1.2 硬件资源
1. LED
       LED0 -PB5
2. 按键
       WKUP - PA0
       KEY0 - PE4
3. USART1(PA9、PA10连接至板载USB转串口芯片上)
4. 正点原子 2.8/3.5/4.3/7/10寸TFTLCD模块(仅限MCU屏,16位8080并口驱动)
5. 外部SRAM(FSMC驱动)

44.1.3 原理图
本章实验使用了一个板载的SRAM芯片,该SRAM芯片通过MCU的FSMC接口与MCU进行连接,该SRAM与MCU的连接原理图,如下图所示:         
1.png
图44.1.3.1 SRAM与MCU的连接原理图
44.2 程序设计
44.2.1 HAL库的FSMC驱动
本章实验通过FSMC驱动SRAM芯片,通过FSMC可以将外部SRAM芯片的数据访问映射成一段内存空间,通过访问这段内存空间,即可访问SRAM芯片中的数据,因此需要对FSMC做相应的配置,FSMC的配置方式,请读者查看第25.2.1小节中HAL库的FSMC驱动中相关的内容。

44.2.2 SRAM驱动
本章实验的SRAM驱动主要负责向应用层提供SRAM的初始化函数,因为SRAM在初始化后,SRAM将被映射为一段内存空间,对SRAM的访问操作就是访问这段内存空间。本章实验中,SRAM的驱动代码包括sram.c和sram.h两个文件。
由于SRAM需要使用大量的GPIO引脚,因此对于GPIO的相关定义,请读者自行查看sram.c和sram.h这两个文件。
SRAM驱动中,SRAM的初始化函数,如下所示:
  1. /**
  2. *@brief       初始化外部SRAM
  3. *@param       无
  4. *@retval      无
  5. */
  6. void sram_init(void)
  7. {
  8.    GPIO_InitTypeDef GPIO_Initure;
  9.    FSMC_NORSRAM_TimingTypeDef fsmc_readwritetim;
  10.    
  11.    SRAM_CS_GPIO_CLK_ENABLE();
  12.    SRAM_WR_GPIO_CLK_ENABLE();
  13.    SRAM_RD_GPIO_CLK_ENABLE();
  14.    __HAL_RCC_FSMC_CLK_ENABLE();
  15.    __HAL_RCC_GPIOD_CLK_ENABLE();
  16.    __HAL_RCC_GPIOE_CLK_ENABLE();
  17.    __HAL_RCC_GPIOF_CLK_ENABLE();
  18.    __HAL_RCC_GPIOG_CLK_ENABLE();
  19.    
  20.    GPIO_Initure.Pin =SRAM_CS_GPIO_PIN;
  21.    GPIO_Initure.Mode =GPIO_MODE_AF_PP;
  22.    GPIO_Initure.Pull = GPIO_PULLUP;
  23.    GPIO_Initure.Speed =GPIO_SPEED_FREQ_HIGH;
  24.    HAL_GPIO_Init(SRAM_CS_GPIO_PORT, &GPIO_Initure);
  25.    
  26.    GPIO_Initure.Pin =SRAM_WR_GPIO_PIN;
  27.    HAL_GPIO_Init(SRAM_WR_GPIO_PORT, &GPIO_Initure);
  28.    
  29.    GPIO_Initure.Pin =SRAM_RD_GPIO_PIN;
  30.    HAL_GPIO_Init(SRAM_RD_GPIO_PORT, &GPIO_Initure);
  31.    
  32.     /* PD0,1,4,5,8~15 */
  33.    GPIO_Initure.Pin =GPIO_PIN_0  |
  34.                        GPIO_PIN_1  |
  35.                        GPIO_PIN_8  |
  36.                        GPIO_PIN_9  |
  37.                        GPIO_PIN_10 |
  38.                        GPIO_PIN_11 |
  39.                        GPIO_PIN_12 |
  40.                        GPIO_PIN_13 |
  41.                        GPIO_PIN_14 |
  42.                        GPIO_PIN_15;
  43.    GPIO_Initure.Mode =GPIO_MODE_AF_PP;
  44.    GPIO_Initure.Pull = GPIO_PULLUP;
  45.    GPIO_Initure.Speed =GPIO_SPEED_FREQ_HIGH;
  46.    HAL_GPIO_Init(GPIOD, &GPIO_Initure);
  47.    
  48.     /* PE0,1,7~15 */
  49.    GPIO_Initure.Pin =GPIO_PIN_0  |
  50.                        GPIO_PIN_1  |
  51.                        GPIO_PIN_7  |
  52.                        GPIO_PIN_8  |
  53.                        GPIO_PIN_9  |
  54.                        GPIO_PIN_10 |
  55.                        GPIO_PIN_11 |
  56.                        GPIO_PIN_12 |
  57.                        GPIO_PIN_13 |
  58.                        GPIO_PIN_14 |
  59.                        GPIO_PIN_15;
  60.    HAL_GPIO_Init(GPIOE, &GPIO_Initure);
  61.    
  62.     /* PF0~5,12~15 */
  63.    GPIO_Initure.Pin =GPIO_PIN_0  |
  64.                        GPIO_PIN_1  |
  65.                        GPIO_PIN_2  |
  66.                        GPIO_PIN_3  |
  67.                        GPIO_PIN_4  |
  68.                        GPIO_PIN_5  |
  69.                        GPIO_PIN_12 |
  70.                        GPIO_PIN_13 |
  71.                        GPIO_PIN_14 |
  72.                        GPIO_PIN_15;
  73.    HAL_GPIO_Init(GPIOF, &GPIO_Initure);
  74.    
  75.     /* PG0~5,10 */
  76.    GPIO_Initure.Pin = GPIO_PIN_0 |
  77.                        GPIO_PIN_1 |
  78.                        GPIO_PIN_2 |
  79.                        GPIO_PIN_3 |
  80.                        GPIO_PIN_4 |
  81.                        GPIO_PIN_5;
  82.    HAL_GPIO_Init(GPIOG, &GPIO_Initure);
  83.    
  84.    g_sram_handler.Instance =FSMC_NORSRAM_DEVICE;
  85.    g_sram_handler.Extended =FSMC_NORSRAM_EXTENDED_DEVICE;
  86.    
  87.    g_sram_handler.Init.NSBank = (SRAM_FSMC_NEX == 1) ? FSMC_NORSRAM_BANK1 : \
  88.                                  (SRAM_FSMC_NEX == 2) ? FSMC_NORSRAM_BANK2 : \
  89.                                  (SRAM_FSMC_NEX == 3) ? FSMC_NORSRAM_BANK3 :
  90.                                                        FSMC_NORSRAM_BANK4;
  91.    g_sram_handler.Init.DataAddressMux=FSMC_DATA_ADDRESS_MUX_DISABLE;
  92.    g_sram_handler.Init.MemoryType =FSMC_MEMORY_TYPE_SRAM;
  93.    g_sram_handler.Init.MemoryDataWidth=FSMC_NORSRAM_MEM_BUS_WIDTH_16;
  94.    g_sram_handler.Init.BurstAccessMode=FSMC_BURST_ACCESS_MODE_DISABLE;
  95.    g_sram_handler.Init.WaitSignalPolarity=FSMC_WAIT_SIGNAL_POLARITY_LOW;
  96.    g_sram_handler.Init.WaitSignalActive=FSMC_WAIT_TIMING_BEFORE_WS;
  97.    g_sram_handler.Init.WriteOperation=FSMC_WRITE_OPERATION_ENABLE;
  98.    g_sram_handler.Init.WaitSignal =FSMC_WAIT_SIGNAL_DISABLE;
  99.    g_sram_handler.Init.ExtendedMode =FSMC_EXTENDED_MODE_DISABLE;
  100.    g_sram_handler.Init.AsynchronousWait=FSMC_ASYNCHRONOUS_WAIT_DISABLE;
  101.    g_sram_handler.Init.WriteBurst =FSMC_WRITE_BURST_DISABLE;
  102.     /* FMC读时序控制寄存器 */
  103.    fsmc_readwritetim.AddressSetupTime = 0x00;
  104.    fsmc_readwritetim.AddressHoldTime = 0x00;
  105.    fsmc_readwritetim.DataSetupTime = 0x01;
  106.    fsmc_readwritetim.BusTurnAroundDuration = 0X00;
  107.    fsmc_readwritetim.AccessMode = FSMC_ACCESS_MODE_A;
  108.    HAL_SRAM_Init(&g_sram_handler, &fsmc_readwritetim, &fsmc_readwritetim);
  109. }
复制代码
从原理图中可以看到,SRAM芯片的CE引脚连接到了PG10引脚(FSMC_NE3信号),因此在进行SRAM初始化后,SRAM映射的内存基地址为0x68000000,访问SRAM中存储的数据仅需访问0x68000000加上数据偏移后的地址即可。

44.2.3 实验应用代码
本章实验的应用代码,如下所示:
  1. /* 定义测试数组
  2. * 起始地址为SRAM_BASE_ADDR
  3. */
  4. uint32_t g_test_buffer[250000]__attribute__((at(SRAM_BASE_ADDR)));
  5. int main(void)
  6. {
  7.     uint8_t key;
  8.     uint8_t i = 0;
  9.     uint32_t ts = 0;
  10.    
  11.    HAL_Init();                         /* 初始化HAL库 */
  12.    sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
  13.    delay_init(72);                        /* 延时初始化 */
  14.    usart_init(115200);                   /* 串口初始化为115200 */
  15.    usmart_dev.init(72);                  /* 初始化USMART */
  16.    led_init();                             /* 初始化LED */
  17.    lcd_init();                             /* 初始化LCD */
  18.    key_init();                             /* 初始化按键 */
  19.    sram_init();                            /* SRAM初始化 */
  20.    
  21.    lcd_show_string(30,  50, 200, 16, 16, "STM32", RED);
  22.    lcd_show_string(30,  70, 200, 16, 16, "SRAM TEST", RED);
  23.    lcd_show_string(30,  90, 200, 16, 16, "ATOM@ALIENTEK", RED);
  24.    lcd_show_string(30, 110, 200, 16, 16, "KEY0:TestSram", RED);
  25.    lcd_show_string(30, 130, 200, 16, 16, "KEY_UP:TESTData", RED);
  26.    
  27.     for (ts = 0; ts < 250000; ts++)
  28.     {
  29.        g_test_buffer[ts] = ts;         /* 预存测试数据 */
  30.     }
  31.    
  32.     while (1)
  33.     {
  34.        key = key_scan(0);               /* 不支持连按 */
  35.       
  36.        if (key == KEY0_PRES)
  37.        {
  38.            fsmc_sram_test(30, 150);     /* 测试SRAM容量 */
  39.        }
  40.        else if (key == WKUP_PRES)      /* 打印预存测试数据 */
  41.        {
  42.            for (ts = 0; ts < 250000; ts++)
  43.            {
  44.                 lcd_show_xnum(30, 170, g_test_buffer[ts], 6, 16, 0, BLUE);
  45.            }
  46.        }
  47.        else
  48.        {
  49.            delay_ms(10);
  50.        }
  51.       
  52.        i++;
  53.       
  54.        if (i == 20)
  55.        {
  56.            i = 0;
  57.            LED0_TOGGLE();
  58.        }
  59.     }
  60. }
复制代码
可以看到,应用代码中定义了一个起始地址为SRAM_BASE_ADDR的数组,SRAM_BASE_ADDR是在sram.h文件中的一个宏定义,该宏定义用于表示SRAM进行映射后的内存起始地址,因此访问数组g_test_buffer就能访问SRAM中的数据。
在完成SRAM初始化后,便往SRAM中填充数据,随后便不断地检测按键输入,若检测到KEY_UP按键被按下,则将SRAM中的数据逐一地读出,然后在LCD上进行显示,这实际是测试了SRAM的读操作,若检测到KEY0按键被按下,则调用函数smc_sram_test()对SRAM进行读写测试,该函数如下所示:
  1. /**
  2. *@brief       外部内存测试(最大支持1M字节内存测试)
  3. *@param       无
  4. *@retval      无
  5. */
  6. voidfsmc_sram_test(uint16_t x, uint16_t y)
  7. {
  8.     uint32_t i = 0;
  9.     uint8_t temp = 0;
  10.     uint8_t sval = 0; /* 在地址0读到的数据 */
  11.    
  12.    lcd_show_string(x, y, 239, y + 16, 16, "Ex Memory Test:  0KB", BLUE);
  13.    
  14.     /* 每隔4K字节,写入一个数据,总共写入256个数据,刚好是1M字节 */
  15.     for (i = 0; i < 1024 * 1024; i += 4096)
  16.     {
  17.        sram_write(&temp, i, 1);
  18.        temp++;
  19.     }
  20.    
  21.     /* 依次读出之前写入的数据,进行校验 */
  22.     for (i = 0; i < 1024 * 1024; i += 4096)
  23.     {
  24.        sram_read(&temp, i, 1);
  25.       
  26.        if (i == 0)
  27.        {
  28.            sval = temp;
  29.        }
  30.        else if (temp <= sval)
  31.        {
  32.            break; /* 后面读出的数据一定要比第一次读到的数据大 */
  33.        }
  34.        /* 显示内存容量 */
  35.        lcd_show_xnum(x+15*8, y, (uint16_t)(temp - sval + 1) * 4, 4, 16, 0, BLUE);
  36.     }
  37. }
复制代码
可以看到,函数smc_sram_test()就是往SRAM中写入数据,然后再读出校验,一次来进行SRAM的读写测试。

44.3 下载验证
在完成编译和烧录操作后,可以看到LCD上显示了本实验的实验信息,此时按下KEY_0按键对SRAM进行读写测试,便可以看到LCD上提示了测试外部SRAM的容量结果,如果一切正常,将提示“Ex MemoryTest:1024KB”,其中1024KB也就是开发板板载SRAM的实际容量(1M字节),接着按下KEY_UP按键对SRAM进行读测试,可以看到LCD上不断地刷新显示一串数字,这便是从SRAM中读出的在SRAM初始化后被写入SRAM的250000个数据(0~249999)。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-22 19:13

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表