所需源文件:crt0.s(启动文件)、sdram_led_c.c(包含main函数和sdram初始化函数、时钟初始化函数)、sdram.lds(连接依赖文件,代码重定位连接定义)、makefile(一键编译)
启动从头文件开始,
首先是硬件配置,通知外设地址,设置外设大小
之后将看门狗关闭
之后bl进入clock_int,初始化时钟,HCLK=133MHZ
首先设置变频锁定时间,设置时钟模式为异步模式,等待异步模式设置成功
设置时钟线的分频系数,根据你需要的外设来,从晶振一直到最终的时钟输出,这里面只用到了HCLK所以只设置了DIV_ARM,DIV_HCLKX2,DIV_HCLK,DIV_PCLK.
设置锁相环的输出频率
是能锁相环,程序跳回。
具体配置如下:
首先是时钟图:
ARM时钟、AXI/AHB/APB时钟
去哪不用管,没用到
首先设置锁频时间
拉满,所谓锁频时间,即系统时钟不输出,等待输出时钟达到设定值的一段时间,如下图红框即为锁频时间:
没啥特殊情况就,拉满
第二步设置同步模式并选择时钟源
就给这个寄存器赋值[7:6]一个是同步模式一个是时钟源
设置之后查询该寄存器[11:8]看是否设置成功,成功了进行下一步设置锁相环PLL
(锁频的寄存器地址也在这)
APLL和MPLL的寄存器一样,主要是设置几个DIV参数,会计算出不同的输出频率,公式如下图:
并贴心的给了常用参考:
Epll也基本一样不过他是特殊外设时钟,慢一点并且输出频率更加细分,所以参数多了点
多了个KDIV,看公式你就懂了
有个指数的倒数,可以除的很小很小,同样,常用频率配置如下
把这些都设置完,就可以使能你的PLL了
前面的与本实验无关,后三位选择器的输入选择为PLL,这样时钟线的频率就是PLL倍频后的了。
如果你需要其他外设时钟就在时钟图里找到它,把他途经的寄存区找到并设置,再配置好PLL的频率,再在时钟源处选择,就可以啦。
接下来要初始化sdram,此时程序还在内存里面跑,所以堆栈设置为4*1024(8k内存就是8*)
接下来bl进sdram_init
DRAM控制器初始化流程:
(1)以‘3’b100’执行memc_cmd,使得DRAM 控制器输入‘配置’状态。
(2)写存储器时间参数,芯片配置和ID 配置寄存器。
(3)等待200μs 来使SDRAM 电源和时钟稳定。当CPU 开始工作时,电源和时钟已经被稳定下来。
(4)执行存储器DDR初始化顺序。
(5)以‘3’b000’执行memc_cmd,使得DRAM 控制器输入‘准备’状态。
(6)在memc_stat 中检查存储器状态域,直到存储器状态变为‘2’b01’,即‘准备’。
DDR 初始化流程:
(1)在direct_cmd,以‘2’b10’执行mem_cmd,使得DRAM 控制器产生‘NOP’存储器命令。
(2)在direct_cmd,以‘2’b00’执行mem_cmd,使得DRAM 控制器产生‘Prechargeall’存储器命令。
(3)在direct_cmd,以‘2’b11’执行mem_cmd,使得DRAM 控制器产生‘Autorefresh’存储器命令。
(4)在direct_cmd,以‘2’b10’执行mem_cmd,使得DRAM 控制器产生‘MRS’存储器命令。EMRS 块地址必须被设置。
(5)在direct_cmd,以‘2’b10’执行mem_cmd,使得DRAM 控制器产生‘MRS’存储器命令。MRS 块地址必须被设置。
(6)在direct_cmd,以‘2’b11’执行mem_cmd,使得DRAM 控制器产生‘Autorefresh’存储器命令。
(7)在direct_cmd,以‘2’b11’执行mem_cmd,使得DRAM 控制器产生‘Autorefresh’存储器命令。
(8)在direct_cmd,以‘2’b11’执行mem_cmd,使得DRAM 控制器产生‘Prechargeall’存储器命令。
具体配置如下:
向MEMCCMD写0x4将DRAM控制器状态改为配置模式
再设置DDR刷新周期7.8us,(7800/( 1000000000/HCLK)+1)写入P1REFRESH HCLK为133MHZ
设置DDR时序参数,P1CASLAT写入0110,设置预充电时间
设置DQS的时钟周期,写0x1,0.75 - 1.25时钟周期
设置模式寄存器命令时间,写入2,最小为2个周期
设置RAS预充电的延时,45us
选择与激活BANK页的时钟x延时,68us
设置RAS的最小充电延时,设置模式是5:3为2:0减3,这里设置为22.5us
命令自动刷新时间,80us,高5位为第5位减3
预充电实现为RAS延时,22.5us
选择与激活BANK页的时钟y延时,15us
写延时,15us
写入后的读取延时,0x7
退出电源关闭的命令时间,0X2
设置自刷新命令时间和退出自刷新令令时间,120us
设置MEMCFG,[2:0]列地址010,10位[5:3]行地址010,13位,AP位设置为0,10位[17:15] 设置Burst大小,010,4
设置MEMCFG2,[3:0]设置为0101,与时钟设置有关,ACLK高于MCLK后两位为10,一样则为01,第三、四位为重启之后的dqm、cke输出级别。
[7:6]设置位宽01=32位
[10:8]设置SDRAM类型011=Mobile DDR SDRAM
[12:11]设置延迟是周期,01=延迟1周期
选择AXI的解码方式,1=bank-row-colum
开始DDR初始化
// NOP空操作 // precharge预充电 // auto refresh自刷新 ;// auto refresh // EMRS // MRS 具体内容根据DRAM的datasheet
将Xm1DATA设置为DMC1的数据线,根据原理图决定
P1MEMCCMD写0x00,使DRAM控制器进入“准备状态”
读取P1MEMSTAT是否已经为准备状态,完成DDR初始化。