主题 : s3c2440  裸机 norflash 复制链接 | 浏览器收藏 | 打印
级别: 新手上路
UID: 119626
精华: 0
发帖: 0
金钱: 5 两
威望: 1 点
贡献值: 0 点
综合积分: 0 分
注册时间: 2015-10-11
最后登录: 2016-03-22
楼主  发表于: 2016-03-09 16:44

 s3c2440  裸机 norflash


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

请大家帮我看看是什么问题。


#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\r\n",id);
    
    //擦除sector
    tem = en29lv160ab_sector_erase(sector_5_base);
    if(tem == 0)
    {
        Uart0Printf("sector_5 擦除失败!\r\n");
    }
    else
    {
        Uart0Printf("sector_5 擦除成功!\r\n");
        //写操作
        tem = en29lv160ab_program(sector_5_base+(1<<1),0xaa);
        if(tem == 0)
        {
            Uart0Printf("地址 %x 写失败!\r\n",sector_5_base+(1<<1));
        }
        else
        {
            //读
            tem = en29lv160ab_read(sector_5_base+(1<<1));
        
            Uart0Printf("%x\r\n",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++)
        {
            ;
        }
    }
}












附件: en29lv160ab_norflash.rar (110 K) 下载次数:7