1.背景
上次电赛需要使用到1024点的FFT计算,几万个数据把STM32F407内存吃掉了好多,赛后我想着要是以后用的情况更苛刻怎么办呢?最近STM32H743XIH6的板子到了,是野火的平台,野火的上面挂着两片SDRAM一共512M的内存,搞个几万个数据也完全没问题了。
插一句题外话,这是我的翻搞,下面是原稿,如果觉得不太舒服或是图片不清晰可以去原稿瞅瞅。
STM32H743 SDRAM操作 - 布局者的文章 - 知乎https://zhuanlan.zhihu.com/p/564636262
2.硬件平台
我用的是野火的STM32H743XIH6的核心板,首先我们看一下硬件
不过大家注意一点,CKE引脚
注意到了吗是SDCKE1不是0!!!!
也就是说这两片SDRAM是挂在SDRAM2上的
从这张图上可以看出来起始地址)0XD000 0000这点是与正点不同的,正点原子是SDRAM1也就是说起始位置是0XC000 0000。
更离谱的是地址和数据线是SDRAM1的(我也不知道咋描述这个)大家稍后写程序就知道有多坑爹了
不知道这是谁设计的硬件,这电路也是有点离谱(PCB不好布线?)
3.程序
3.1 端口以及FMC初始化
好了,硬件介绍完了,下面正式开始写程序
最开始是初始化时钟,初始化端口,开启FMC时钟。我比较懒,直接把GPIO的时钟全部打开,大家也可以选择性开启,省电。除此之外就是顺序的问题,网上以及正点原子的程序里以上的顺序,网上说不以这个顺序就无法启动,我反正没试过其他顺序。
我们先看SDCR寄存,大家可能会好奇为啥要这样写?我是用的第二片区域,第一片为啥还要用?
还记得上面我说的地址线是挂在第一片上吗,对头,这就是结果,所有地址线和数据线的设置要用第一设置,但是使能,使能读写要用第二个,尤其要注意以下几位
可以看到都有注解,你可以理解位SDCR2上没有这几位,哪怕是你的外部SDRAM挂满了,都是SDCR1来控制,所以一定要写SDCR1。所以你能看到我在程序里既有SDCR1也有SDCR2的操作。上面的程序里我也有注释,大家可以结合这数据手册,相信不难理解。
FMC里有好几处有这个情况,后面我还会特别写出来的。
在SDTR中注意的是TRC和TRP
注意看注释,同样的是SDTR2无效,所以程序上是SDTR1
除此之外SDTR的复位值是0xffff ffff
所以在写寄存器前记得把要操作的寄存器清空
3.2特别注意
再之后就是SDCMR
注意这里要特别写出来,正点原子的程序是错的,要用以上的程序来写
这是正点原子的程序。但是我们看一下数据手册上怎么写的
看一下注释1。对,要有一个储存器置1。
那有的童鞋说了,我这样不可以吗?那么我们来试一下。
可以看出来内存里都是??但是如果我们合成一句话
可以很明显看出来内存正常初始化了,所以我感觉数据手册里对这里的描述并不准确,应该是指令和内存区域要同时指定。至于正点原子的程序就更是离谱了,我是不知道是怎么写出来的。。。。
这里要特别说明一下,如果是用库的话,那么一般是不存在这个问题。我略微扒了一下库,一般来说如果操作库的话,库的处理方法是先赋值给一个变量,然后对寄存器一次性操作,也就是说一个寄存器一次性赋值,一句话完成全部操作。
不过的话,库操作的话会各种调用,宏定义,嵌套,搞得花里胡哨的。当然了库也有库的好处,大家取舍。
野火的例程里是纯库来操作的,一般是不存在这些问题的,但是如果用的是正点原子的寄存器操作的话大家还是稍稍注意一下。
3.3收尾程序
那么剩下的就是
关于SDCMR寄存器我都是一句话完成。
至此我们就完成了SDRAM的初始化,其结果就是
然后我们就可以用指针,指向内存区域,直接操作了
可以看到内存的第一个区域内8已经被我们放进去了
4.结束语
至此STM32H743使用FMC操作SDRAM基本方法已经完成,后续就是内存管理的问题了。大家如果还有什么问题的话可以去我知乎的文章看一下,里面的图片更清晰一点,如果还有什么问题大家可以留言在评论区,与君共勉。