实验功能描述:对nand flash的读。通过重加载可以把主函数 main.c编译之后main.o文件放到nand flash的4096开始之后的位置,其它的放到 地址 0 开始的位置。这样就可通过对nand flash 的读,把文件放到SDRAM中。
实验程序:
启动程序:
.text
.global _start
_start:
ldr sp,=1024*4 @设置堆栈,以下都是C函数
bl watch_dog
bl memery_init
bl nand_init
ldr r0,=0x30000000
mov r1,#4096
mov r2,#1024
bl nand_read
ldr sp,=0x30400000
ldr lr,=loop
ldr pc, =main
loop:
b loop
初始化程序:
#define WTCON (*(volatile unsigned long *)0x53000000)
#define MEMERY_BASE 0x48000000
void watch_dog()
{
WTCON = 0;
}
void memery_init()
{
volatile unsigned long *p = (unsigned long *)MEMERY_BASE;
p[0] = 0x22111110;
p[1] = 0x00000700;
p[2] = 0x00000700;
p[3] = 0x00000700;
p[4] = 0x00000700;
p[5] = 0x00000700;
p[6] = 0x00000700;
p[7] = 0x00018005;
p[8] = 0x00018005;
p[9] = 0x008E08A3;
p[10] = 0x000000b2;
p[11] = 0x00000030;
p[12] = 0x00000030;
}
对nand的读程序:
#define NFCONF (*(volatile unsigned long *)0x4E000000)
#define NFCMD (*(volatile unsigned long *)0x4E000004)
#define NFADDR (*(volatile unsigned long *)0x4E000008)
#define NFDATA (*(volatile unsigned long *)0x4E00000C)
#define NFSTAT (*(volatile unsigned long *)0x4E000010)
#define TACLS 0
#define TWRPH0 3
#define TWRPH1 0
#define SECTOR_SIZE 512
#define SECTOR_BLOCK (SECTOR_SIZE -1)
void nand_chip_select();
void nand_chip_disselect();
void nand_chip_reset();
void nand_chip_addr(unsigned long addr);
void nand_chip_cmd(unsigned long cmd);
void nand_chip_wait();
void nand_chip_write(unsigned long addr,unsigned char data);
unsigned char nand_chip_read();
void nand_read(unsigned char *buf,unsigned long start_addr,unsigned long size);
void nand_init()
{
NFCONF = (1<<15)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0);
nand_chip_reset();
}
void nand_chip_select()
{
//int i;
NFCONF &= ~(1<<11);
//for(i=0;i<10;i++);
}
void nand_chip_disselect()
{
NFCONF |= (1<<11);
}
void nand_chip_cmd(unsigned long cmd)
{
//int i;
//volatile unsigned long *p = &NFCMD;
//*p = cmd;
NFCMD = cmd;
//for(i=0;i<10;i++);
}
void nand_chip_wait()
{
int i;
while(!(NFSTAT & 1))
for(i=0;i<10;i++);
}
void nand_chip_reset()
{
nand_chip_select();
nand_chip_cmd(0xFF);
nand_chip_wait();
nand_chip_disselect();
}
void nand_chip_addr(unsigned long addr)
{
//int i;
//volatile unsigned long *p = &NFADDR;
//*p = addr & 0xFF;
NFADDR = addr & 0xFF;
//for(i=0;i<10;i++);
NFADDR = (addr >>9) & 0xFF;
//*p = (addr >> 9) & 0xFF;
//for(i=0;i<10;i++);
NFADDR = (addr >>17) & 0xFF;
//*p = (addr >> 17) & 0xFF;
//for(i=0;i<10;i++);
NFADDR = (addr>>25) & 0xFF;
//*p = (addr >>25) & 0xFF;
//for(i=0;i<10;i++);
}
unsigned char nand_chip_read()
{
volatile unsigned char *data = (volatile unsigned char *)& NFDATA ;
return *data;
}
void nand_read(unsigned char *buf,unsigned long start_addr,unsigned long size)//定义类型的时候注意哟
{
int i,j;
if((start_addr & SECTOR_BLOCK) || (size & SECTOR_BLOCK)) //地址或者长度不对齐,則返回,要求地址和长度都对齐
{
return ;
}
nand_chip_select();
for(i = start_addr; i< (start_addr + size); )
{
nand_chip_cmd(0);
nand_chip_addr(i);
nand_chip_wait();
for(j=0;j {
*buf = nand_chip_read();
buf++;
}
}
nand_chip_disselect();
return ;
}
main函数程序:
#define GPBCON (*(volatile unsigned long *)0x56000010)
#define GPBDAT (*(volatile unsigned long *)0x56000014)
#define GPFCON (*(volatile unsigned long *)0x56000050)
#define GPFDAT (*(volatile unsigned long *)0x56000054)
#define GPB0_out (1<<(0*2))
#define GPB1_out (1<<(1*2))
#define GPF0_in (0<<(0*2))
#define GPF1_in (0<<(1*2))
int main()
{
unsigned long key_data;
GPBCON |= (GPB0_out | GPB1_out);
GPFCON = GPF0_in & GPF1_in;
while(1)
{
key_data = GPFDAT;
if(key_data & 1)
GPBDAT |= 1;
else
GPBDAT &=~1;
if(key_data & (1<<1))
GPBDAT |= (1<<1);
else
GPBDAT &= ~(1<<1);
}
return 0;
}
在这次实验中:我出现的问题是,在nand_read的函数中,对于存储接收从nand读出来的数据,最开始定义成了 unsigned long型,后面在递增的时候,大家知道。long型++,是一次加4,所以就出现了错误。应该定义成unsigned char型,改了之后。结果就好了。所以在定义数据类型时,不要盲目的去定义,一定要仔细考虑考虑。还有就是启动程序调用主函数的时候,也要注意。
阅读(1093) | 评论(0) | 转发(0) |