注:以下内容学习于韦东山老师arm裸机第一期视频教程
001节辅线1硬件知识_内存接口概念
1、门电路:GPIO接口
2、协议类接口:UART、I2C…
CPU把某些值写给某些寄存器,然后由对应的控制器发出特定的波形
CPU怎么去选择不同的寄存器?
CPU由地址去选择不同的寄存器
由于CPU根据地址去选择不同的寄存器,所以我们需要有一个 控制单元(内存控制器)
这两种接口CPU发出的数据并不会输出到外部电路去,只是控制相对于的控制模块
CPU只是根据地址选择不同的寄存器,把数据发送到控制模块的寄存器(至于数据和地址起什么作用由不同模块的控制器决定)
内存控制器的作用:
3、内存接口:内存类设备(NOR、网卡、SDRAM)
CPU发出的地址可以直接发送
片选引脚概念:
只有使得某个片选引脚输出低电平的时候,对应的芯片才会开始工作,
内存控制器根据CPU发出的地址,设置不同的片选引脚,只有被选中的芯片才会工作
地址与片选引脚关系如下图:
每个片选信号选择的地址范围为:128M =2^27(0x0800,0000)(至少需要A0,A1…A26共27条地址线)
CPU是32位,怎么只用到27条地址线?
ldr r0, = addr
str r1,[r0]
ldr r1,[r0]
特殊的NAND Flash
对于GPIO、UART、I2C、SDRAM、DM9000、NOR都是CPU统一编制的,但是对于NAND原理图如下
上面并没有地址总线,所以不属于CPU统一编址
那么nand片选信号是由谁发出的呢?是由nand flash 控制器发出的
:
SDRMA、NOR、DM900网卡地址总线连接如图:
SDARM
addr2–>A0,
addr3->A1,
…
NOR
laddr -->A0,
laddr -->A1,
…
网卡:
LADDR2–>32
如何分辨是都还是写
第002节辅线1硬件知识_不同位宽设备的连接
J22440内存接口示例:
当使用一个8位的芯片时,CPU的A0接芯片的A0
当使用两个8位的芯片拼接(DATA0-7接一个芯片,DATA8-15接一个芯片,也就是组成了一个16位的芯片)的时候,CPU的A1接芯片的A0(CPU的A0用来判断高8位有效还是低8位有效)
当使用四个8位的芯片拼接(也就是组成了一个32位的芯片)的时候,CPU的A2接芯片的A0
假设CPU执行
MOV R0,#3
LDRB R1,[R0]
# 读地址3的一个字节
过程 | cpu发出地址 | ROM收到地址 | ROM返回数据 | 内存控制器转发数据给CPU |
---|---|---|---|---|
8bit | 000011 | 000011 | 编号3的存储单元中的8bit数据 | 返回数据 |
16bit | 000011 | 00001 | 编号1的存储单元中的16bit数据 | 根据”A0=1”,挑出编号为1的8bit数据 |
32bit | 000011 | 0000 | 编号0的存储单元中的32bit数据 | 跟根据“A0=1,A1=1”,挑出编号为3的8bit数据 |
MOV R0,#4
LDR R1,[R0]
# 去地址 4 去取 4,5,6,7 这4个字节
过程 | cpu发出地址 | 内存控制器转发给ROM | ROM返回数据 | 内存控制器,组装返回数据给CPU |
---|---|---|---|---|
8bitROM | 000100 | 000100—>ROM 000101—>ROM 000110—>ROM 000111—>ROM | 得到地址4上的1byte 得到地址5上的1byte 得到地址6上的1byte 得到地址7上的1byte | 组装4、5、6、7之后返回给CPU |
16bitROM | 000100 | 00010—>ROM 00011—>ROM | 得到第二个16bit数据 得到第三个16bit数据 | 组装第2、3 (16bit数据)返回数据给CPU |
32bitROM | 000100 | 0001 —>ROM | 得到第一个32bit数据 | 把第一个32bit数据返回CPU |
怎么确定芯片访问地址:
1、根据片选信号确定基地址
2、根据芯片所接地址线确定范围
NOR | NET | SDRAM | |
---|---|---|---|
基地址(base) | 0 | 0x2000,0000 | 0x3000.0000 |
片选 | 0 | 4 | 6 |
范围 | 用到A20,A19…A1,A0共21条线 2^21=2M空间 范围:base+0b0…0–>0b1…1= 0—>2^21 | 用到A2,A0 范围:base+0b000->0b101 = 0x2000,0000—>0x2000,0005 | 比较特殊以后补充 |
第003节辅线1硬件知识_时序图分析示例
以NOR Flash 为例:
NOR Flash 的原理图如下:
LADDRn:地址线
LDaTAn: 数据线
nGC0: 片选信号
nOE: 读信号
WE: 写信号
JZ2440 READ 时序图
先发出地址信号,经过Tacs时间发出片选信号(nGCS),然后经过Tcos时间发出读信号,过一会数据才有效,把数据读走,然后把读信号释放掉,把片选信号释放掉,然后才开始新的地址周期
Tacs ,Tcos,Tacc,Tacp...这些需要根据不同的芯片来进行设置
因为J2440可以接不同类型的内存类芯片,这些内存内芯片性能不同,所以所用的时间周期也不同。
NOR FLASH READ 操作 时序图
NOR Flash 时序要求图
- Taa —>发出addr后多长时间data才有效(最大70ns---->可以保证在芯片在接受到地址后 70ns之后肯定有数据给你访问,但是不保证70ns之内的数据正确性)
- Tce —>发出片选信号后多长时间data才有效
- Toh–>数据保持时间(0ns)
- Tdf -->当释放片选信号或者释放读信号之后,数据浮动的时长,在这段时间内不能访问其他芯片(一般不用管,因为我们Taa需要70ns比这里30ns长)
- Trc -->读周期时间(最小70ns)
结合J2440 读操作时序图和NOR 读操作时序图以及NOR时序要求对参数进行设定
- 为了简单让片选信号(CE#),读信号(OE#),地址信号(addr) 同时发出,这里因为上面已经说明只有Tacc时间>=70ns 我们才能拿到正确的数据
Tacc 对应的寄存器
说明:
- J2440 默认 :上电:HCLK 12MHZ Tacc = 111 (14clock) time = 1000/12*14 约等 1162ns
- 因为这里nor 使用片选0,所以我们要设置BANKCON0寄存器
- 设置 HCLK 100MHZ time = 1000/100=10ns 因为要大于70ns 所以 Tacc 需要大于 8 clocks
设置BWSON 寄存器中对应的bank 0
只需要设置 bit[2:1],bit[2:1]是只读的,表示外界NOR是多少位的,因此不需要设置
设置NOR Tacc 来提高性能
#include "s3c2440_soc.h"
#include "uart.h"
#include "setTacc.h"
#include "led.h"
int main(void)
{
unsigned char c;
int i;
uart_init();
puts("Enter the Tacc val: \n\r");
while(1)
{
c = getchar();
putchar(c);
if (c >= '0' && c <= '7')
{
setTacc(c-'0');
led_test();
}
else
puts("Error val,tacc should betwen 0-7\n\r");
}
return 0;
}
### setTacc.c
void setTacc(int tacc)
{
BANKCON0 = (tacc<<8);
}