arm 裸机 norflash

2019-07-16 08:34发布

想法是这样的,利用norflash中未用的sector保存运行数据。
实验:
1、芯片:s3c2440,norflash:en29lv160ab。裸机程序在ADS1.2中编译,完成读取ID,擦除,写,读。
2、将附件中的代码通过JLINK焼写进norfalsh,从norflash启动。
3、很长时间(十几分钟)才出现显示结果,结果正确。

请大家帮我看看。
en29lv160ab_norflash.rar 下载积分: 积分 -1 分
109.05 KB, 下载次数: 1, 下载积分: 积分 -1 分
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
1条回答
xishuidemian
1楼-- · 2019-07-16 09:40
//======================================================================
//        功能描述:        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++)
                {
                        ;
                }
        }
}












一周热门 更多>