//======================================================================
// 功能描述: EN29LV160AB操作
// 硬件连接:
//
// 维护记录: 2016.3.9
// 实验结果: 没反应,有时等待很长(数十分钟)时间可能显示结果(实验基本失败)
//======================================================================
#include "2440addr.h"
#include "def.h"
#include <string.h>
#include "uart.h"
#include "gpio.h"
#define _ISR_STARTADDRESS 0x33ffff00
#define flash_base 0x00000000
#define CMD_ADDR0 *( (volatile U16 *)((0x555<<1)+flash_base) )
#define CMD_ADDR1 *( (volatile U16 *)((0x2aa<<1)+flash_base) )
#define sector_5_base ( ((0x20000<<1)+flash_base) )
#define sector_5_size 32000
#define sector_33_base ( ((0xf0000<<1)+flash_base) )
#define sector_33_size 32000
U8 en29lv160ab_check_toggle(void);
U8 en29lv160ab_sector_erase(U32 section_addr);
U8 en29lv160ab_chip_erase(void);
U8 en29lv160ab_program(U32 addr,U16 dat);
U16 en29lv160ab_read(U32 addr);
void en29lv160ab_reset(void);
U32 en29lv160ab_id(void);
void delay_ms(int t);
//测试
int Main(void)
{
U16 while_i = 0;//循环次数
U32 i;
U32 id = 0;
U16 tem = 0;
Uart0_Init(115200);//串口初始化
Gpio_Init();
//读ID号
LED_ON;
id = en29lv160ab_id();
LED_OFF;
en29lv160ab_reset();
delay_ms(500);
Uart0Printf("EN29LV160AB的ID号为:%x\r\n",id);
while(1)
{
while_i++;
if(while_i > 1)
{
while_i = 1;
}
else
{
//擦除sector
tem = en29lv160ab_sector_erase(sector_33_base);
if(tem == 0)
{
Uart0Printf("sector_33 擦除失败!\r\n");
}
else
{
Uart0Printf("sector_33 擦除成功!\r\n");
for(i=0;i<32000;i++)
{
Uart0Printf("%x\r\n",en29lv160ab_read(sector_33_base+(i<<1)));
}
//写操作
for(i=0;i<32000;i++)
{
en29lv160ab_program(sector_33_base+(i<<1),i);
}
//读操作
for(i=0;i<32000;i++)
{
Uart0Printf("%x\r\n",en29lv160ab_read(sector_33_base+(i<<1)));
}
}
}
}
return 0;
}
//check_toggle
U8 en29lv160ab_check_toggle(void)
{
volatile U16 newtoggle;
volatile U16 oldtoggle;
while(1)
{
newtoggle = *( (volatile U16 *)0x0 );
if( (oldtoggle&0x40) == (newtoggle&0x40) ) //DQ6
break;
if(newtoggle & 0x20)//DQ5
{
oldtoggle = *((volatile U16 *)0x0);
newtoggle = *((volatile U16 *)0x0);
if( (oldtoggle & 0x40) == (newtoggle & 0x40) )
break;
else
return 0;//错误
}
oldtoggle = newtoggle;
}
return 1;//正确
}
//sector擦除
U8 en29lv160ab_sector_erase(U32 section_addr)
{
CMD_ADDR0 = 0xaa;
CMD_ADDR1 = 0x55;
CMD_ADDR0 = 0x80;
CMD_ADDR0 = 0xaa;
CMD_ADDR1 = 0x55;
*( (volatile U16 *)(section_addr) ) = 0x30;
return en29lv160ab_check_toggle();
}
//chip擦除
U8 en29lv160ab_chip_erase(void)
{
CMD_ADDR0 = 0xaa;
CMD_ADDR1 = 0x55;
CMD_ADDR0 = 0x80;
CMD_ADDR0 = 0xaa;
CMD_ADDR1 = 0x55;
CMD_ADDR0 = 0x10;
return en29lv160ab_check_toggle();
}
//写操作
U8 en29lv160ab_program(U32 addr,U16 dat)
{
CMD_ADDR0 = 0xaa;
CMD_ADDR1 = 0x55;
CMD_ADDR0 = 0xa0;
*( (volatile U16 *)(addr) ) = dat;
return en29lv160ab_check_toggle();
}
//读操作
U16 en29lv160ab_read(U32 addr)
{
return *( (volatile U16 *)(addr) );
}
//软件复位
void en29lv160ab_reset(void)
{
*( (volatile U16 *)0x0 ) = 0xf0;
}
//读取ID,高2个字节为设备ID,低两个字节为芯片ID
U32 en29lv160ab_id(void)
{
U32 temp = 0;
CMD_ADDR0 = 0xaa;
CMD_ADDR1 = 0x55;
CMD_ADDR0 = 0x90;
temp = (*( (volatile U16 *)(flash_base+(0x100<<1)) ))<<16;
CMD_ADDR0 = 0xaa;
CMD_ADDR1 = 0x55;
CMD_ADDR0 = 0x90;
temp += (*(volatile U16 *)(flash_base+(0x1<<1)));
return temp;
}
//延时
void delay_ms(int t)
{
int i,j;
for(i=0;i<t;i++)
{
for(j=0;j<1000;j++)
{
;
}
}
}
|