说明:
根据物理结构上的区别 , NandFlash主要分为如下两类:
1)•SLC (Single Level Cell): 单层式存储
2)•MLC (Multi Level Cell): 多层式存储
@:SLC在存储格上只存一位数据, 而MLC则存放两位数据。
1.nand.c
#define NFCONF (*(volatile unsigned long*)0x4E000000)
#define NFCONT (*(volatile unsigned long*)0x4E000004)
#define NFCMD (*(volatile unsigned char*)0x4E000008)
#define NFADDR (*(volatile unsigned char*)0x4E00000C)
#define NFDATA (*(volatile unsigned char*)0x4E000010)
#define NFSTAT (*(volatile unsigned char*)0x4E000020)
#define TACLS 1
#define TWRPH0 2
#define TWRPH1 1
void select_chip()
{
NFCONT &= ~(1<<1);
}
void deselect_chip()
{
NFCONT |= (1<<1);
}
void clear_RnB()
{
NFSTAT |= (1<<2);
}
void send_cmd(unsigned cmd)
{
NFCMD = cmd;
}
void send_addr(unsigned addr)
{
NFADDR = addr;
}
void wait_RnB()
{
while (!(NFSTAT&(1<<2)))
{
;
}
}
void nand_reset()
{
//选中flash
select_chip();
//清除RnB
clear_RnB();
//发送0xff命令
send_cmd(0xff);
//等待RnB
wait_RnB();
//取消选中flash
deselect_chip();
}
void nandflash_init()
{
//初始化NFCONF
NFCONF = (TACLS<<12) | (TWRPH0<<8) | (TWRPH1<<4);
//初始化NFCONT
NFCONT = (1<<0) | (1<<1);
//复位
nand_reset();
}
void NF_PageRead(unsigned long addr,unsigned char* buff)
{
int i;
//选中nandflash芯片
select_chip();
//清除RnB
clear_RnB();
//发送命令0x00
send_cmd(0x00);
//发送列地址
send_addr(0x00);
send_addr(0x00);
//发送行地址
send_addr(addr&0xff);
send_addr((addr>>8)&0xff);
send_addr((addr>>16)&0xff);
//发送命令0x30
send_cmd(0x30);
//等待RnB
wait_RnB();
//读取数据
for(i=0;i<2048;i++)
{
buff[i] = NFDATA;
}
//取消选中nandflash芯片
deselect_chip();
}
void nand_to_ram(unsigned long start_addr, unsigned char* sdram_addr, int size)
{
int i;
for( i=(start_addr >>11); size>0;)
{
NF_PageRead(i,sdram_addr);
size -= 2048;
sdram_addr += 2048;
i++;
}
}
int NF_Erase(unsigned long addr)
{
int ret;
//选中flash芯片
select_chip();
//清除RnB
clear_RnB();
//发送命令0x60
send_cmd(0x60);
//发送行地址
send_addr(addr&0xff);
send_addr((addr>>8)&0xff);
send_addr((addr>>16)&0xff);
//发送命令D0
send_cmd(0xD0);
//等待RnB
wait_RnB();
//发送命令0x70
send_cmd(0x70);
//读取擦除结果
ret = NFDATA;
//取消选中flash芯片
deselect_chip();
return ret;
}
int NF_WritePage(unsigned long addr,unsigned char *buff)
{
unsigned int i,ret = 0;
//选中nandflash
select_chip();
//清除RnB
clear_RnB();
//发送0x80命令
send_cmd(0x80);
//发送2个列地址
send_addr(0x00);
send_addr(0x00);
//发送3个行地址
send_addr(addr&0xff);
send_addr((addr>>8)&0xff);
send_addr((addr>>16)&0xff);
//发送数据
for(i=0;i<2048;i++)
{
NFDATA = buff[i];
}
//发送0x10命令
send_cmd(0x10);
//等待RnB
wait_RnB();
//发送0x70命令
send_cmd(0x70);
//读取写入结果
ret = NFDATA;
//关闭nandflash
deselect_chip();
return ret;
}
2.uart.c
#define GPHCON (*(volatile unsigned long*)0x56000070)
#define ULCON0 (*(volatile unsigned long*)0x50000000)
#define UCON0 (*(volatile unsigned long*)0x50000004)
#define UBRDIV0 (*(volatile unsigned long*)0x50000028)
#define UTRSTAT0 (*(volatile unsigned long*)0x50000010)
#define UTXH0 (*(volatile unsigned long*)0x50000020)
#define URXH0 (*(volatile unsigned long*)0x50000024)
#define PCLK 50000000
#define BAUD 115200
void uart_init()
{
//1.配置引脚功能
GPHCON &= ~(0xf<<4);
GPHCON |= (0xa<<4);
//2.1 设置数据格式
ULCON0 = 0b11;
//2.2 设置工作模式
UCON0 = 0b0101;
//3. 设置波特率
UBRDIV0 =(int)(PCLK/(BAUD*16)-1);
}
void putc(unsigned char ch)
{
while (!(UTRSTAT0 & (1<<1)));
UTXH0 = ch;
}
unsigned char getc(void)
{
unsigned char ret;
while (!(UTRSTAT0 & (1<<0)));
// 取数据
ret = URXH0;
if ( (ret == 0x0d) || (ret == 0x0a) )
{
putc(0x0d);
putc(0x0a);
}
else
putc(ret);
return ret;
}