想法是这样的,利用norflash中未用的sector保存运行数据。
实验:
1、
芯片:s3c2440,norflash:en29lv160ab。裸机程序在ADS1.2中编译,完成读取ID,擦除,写,读。
2、将附件中的代码通过JLINK焼写进norfalsh,从norflash启动。
3、很长时间(十几分钟)才出现显示结果,结果正确。
请大家帮我看看。
-
-
en29lv160ab_norflash.rar
下载积分: 积分 -1 分
109.05 KB, 下载次数: 1, 下载积分: 积分 -1 分
// 功能描述: 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 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 ",id);
//擦除sector
tem = en29lv160ab_sector_erase(sector_5_base);
if(tem == 0)
{
Uart0Printf("sector_5 擦除失败! ");
}
else
{
Uart0Printf("sector_5 擦除成功! ");
//写操作
tem = en29lv160ab_program(sector_5_base+(1<<1),0xaa);
if(tem == 0)
{
Uart0Printf("地址 %x 写失败! ",sector_5_base+(1<<1));
}
else
{
//读
tem = en29lv160ab_read(sector_5_base+(1<<1));
Uart0Printf("%x ",tem);
}
}
while(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++)
{
;
}
}
}
一周热门 更多>