[求助] 飞思卡尔单片机读flash

zhangdaoyu   2012-12-19 21:35 楼主
飞思卡尔单片机怎么读flash 我仿真的时候,读出全是FF 也不知道读对不

读的过程 dat = *Addr  Addr是十六位的,dat是8位的

中间需要不需要加修饰符来表明指针是指向flash区的,高手们给指导一下吧,我就不用再摸索了

回复评论 (7)

我有,可惜在单位电脑里,周一给你
点赞  2012-12-22 17:52
#include /* for EnableInterrupts macro */
#include "derivative.h" /* include peripheral declarations */
#include "MC9S08DZ60.h"
#include "board.h"
#include "Flash.h"


uint8 EraseSector(byte* address){
  DisableInterrupts;
  FSTAT = 0x30; /*clear errors*/
  if ((uint16)address >= EEPROM_END_ADDRESS) return FAIL;
  if(FSTAT_FCBEF==1){
    *address = 0x00;//dummy;
    FCMD = FLASHCMD_ERASE;
    FSTAT = FLASHCMD_CBEF;
  _asm NOP; //Wait 4 cycles
  _asm NOP;
  _asm NOP;
  _asm NOP;
    if( (FSTAT_FACCERR!=0) || (FSTAT_FPVIOL!=0)){
      EnableInterrupts;
      return(FAIL);
    }
    while(FSTAT_FCCF!=1){
    }
    EnableInterrupts;
    return(PASS);
  } else{
    EnableInterrupts;
    return(FAIL);
  }
}

uint8 WriteByte(byte* address, byte data){
  DisableInterrupts;
  FSTAT = 0x30;
  if(FSTAT_FCBEF==1){
    *address = data;
    FCMD = FLASHCMD_PROG;
    FSTAT = FLASHCMD_CBEF;
  _asm NOP; //Wait 4 cycles
  _asm NOP;
  _asm NOP;
  _asm NOP;
    if( (FSTAT_FACCERR!=0) || (FSTAT_FPVIOL!=0)){
      EnableInterrupts;
      return(FAIL);
    }
    while(FSTAT_FCCF!=1){
    }
    EnableInterrupts;
    return(PASS);
  } else{
    EnableInterrupts;
    return(FAIL);
  }
}

uint8 WriteWord(byte* address,uint16 data) {
  if (WriteByte(address+1,(byte)data) == FAIL) return FAIL;
  if (WriteByte(address,(byte)(data>>8)) == FAIL) return FAIL;
  return PASS;
}
/***********************************switch eeprom********************************************/
#define SYSTEM_CONFIG_SIZE        sizeof(struct System_Config)
struct System_Config * System_Config_Current=(struct System_Config *)EEPROM_START_ADDRESS;  //系统当前设置
struct S_Channel_Setting * Channel_Setting_Array=(struct S_Channel_Setting *)EEPROM_CHANNELSETTING_STARTADDRESS;
//系统参数出厂设置
const struct System_Config System_Config_Default={
  EEPROM_VERIFICATION_CODE,       //unsigned int Verification_Code; //检验码
  EEPROM_FACTORY_VERIFICATION,0,0,
/***********************can总线设置*******************************/
  128,                    //uint16 Default_ID;                //默认11位标准ID值,扩展帧此数值在高11位即28~18
  0,0,0,0,0,0,0,//uint16 notused3;
//滤波器手动设置
  0x0000,               //uint16 Can_Identifier_Acceptance01;      //滤波值
  0x0000,               //uint16 Can_Identifier_Mask01;            //掩位
  0x0000,               //uint16 Can_Identifier_Acceptance23;      
  0x0000,               //uint16 Can_Identifier_Mask23;            
  0x0000,               //uint16 Can_Identifier_Acceptance45;      
  0x0000,               //uint16 Can_Identifier_Mask45;
  0x0000,               //uint16 Can_Identifier_Acceptance67;      
  0x0000,               //uint16 Can_Identifier_Mask67;
};    //系统参数默认值

//通道参数默认值
const struct S_Channel_Setting Channel_Setting_Default[32]= {
//通道1报警下限//通道1提示下限 //通道1提示上限 //通道1报警上限
  {1000,1500,2000,2500},     
  {1000,1500,2000,2500},   
  {1000,1500,2000,2500},     
  {1000,1500,2000,2500},  
  {1000,1500,2000,2500},     
  {1000,1500,2000,2500},   
  {1000,1500,2000,2500},     
  {1000,1500,2000,2500},  
  {1000,1500,2000,2500},     
  {1000,1500,2000,2500},   
  {1000,1500,2000,2500},     
  {1000,1500,2000,2500},  
  {1000,1500,2000,2500},     
  {1000,1500,2000,2500},   
  {1000,1500,2000,2500},     
  {1000,1500,2000,2500},
  {1000,1500,2000,2500},     
  {1000,1500,2000,2500},   
  {1000,1500,2000,2500},     
  {1000,1500,2000,2500},  
  {1000,1500,2000,2500},     
  {1000,1500,2000,2500},   
  {1000,1500,2000,2500},     
  {1000,1500,2000,2500},  
  {1000,1500,2000,2500},     
  {1000,1500,2000,2500},   
  {1000,1500,2000,2500},     
  {1000,1500,2000,2500},  
  {1000,1500,2000,2500},     
  {1000,1500,2000,2500},   
  {1000,1500,2000,2500},     
  {1000,1500,2000,2500}   
};

uint8 EEPRom_Init(void) {
  if ((*System_Config_Current).Verification_Code != EEPROM_VERIFICATION_CODE) {
    //如果eeprom未初始化则使用rom中的出厂设置
    System_Config_Current = (struct System_Config *)(&System_Config_Default);
    Channel_Setting_Array = (struct S_Channel_Setting *)(&Channel_Setting_Default);
    if ((*System_Config_Current).Verification_Code != EEPROM_VERIFICATION_CODE)
      return FAIL;    //参数设置错误
    if ((*System_Config_Current).Factory_Setting_Verification_Code != EEPROM_FACTORY_VERIFICATION)
      return FAIL;
   
  }
  return PASS;   
}

/******************复制出厂默认值到eeprom**********************************/
uint8 Save_System_Config_Default(void) {
  uint8 i;
  for (i=0;i<(SYSTEM_CONFIG_SIZE/EEPROM_PAGE_SIZE+1);i++)
    if (EraseSector((byte*)(EEPROM_START_ADDRESS+i*EEPROM_PAGE_SIZE))==FAIL)
      return FAIL;
  if (WriteWord((byte *)(EEPROM_START_ADDRESS),EEPROM_VERIFICATION_CODE)==FAIL)
    return FAIL;
  for (i=2;i     if (WriteByte((byte *)(EEPROM_START_ADDRESS+i),*((unsigned char *)System_Config_Current+i))==FAIL)
      return FAIL;   
  System_Config_Current = (struct System_Config *)EEPROM_START_ADDRESS;
  //复制默认参数到eeprom
  for (i=0;i<32;i++)
    if (EraseSector((byte*)(EEPROM_CHANNELSETTING_STARTADDRESS+i*EEPROM_PAGE_SIZE))==FAIL)
      return FAIL;
  i=0;
  do {
    if (WriteByte((byte *)(EEPROM_CHANNELSETTING_STARTADDRESS+i),*((unsigned char *)Channel_Setting_Default+i))==FAIL)
      return FAIL;
  } while(++i);
  Channel_Setting_Array=(struct S_Channel_Setting *)EEPROM_CHANNELSETTING_STARTADDRESS;
  return PASS;
}

/*//保存参数*/
uint8 Save_System_Parameter(unsigned char offset,unsigned int val) {
  unsigned char i,buf[EEPROM_PAGE_SIZE];
  unsigned int address;
  offset*=sizeof(unsigned int);
  address=EEPROM_START_ADDRESS+(offset&~(EEPROM_PAGE_SIZE-1));  
  if (address>EEPROM_START_ADDRESS+SYSTEM_CONFIG_SIZE) return -1;
  if ((uint16)System_Config_Current != EEPROM_START_ADDRESS) { //eeprom未启用
    if (Save_System_Config_Default()) return -2;     
  }
  if ((*System_Config_Current).Verification_Code != EEPROM_VERIFICATION_CODE)
    return -3;   
  for (i=0;i     buf=*(unsigned char *)(address+i);
  buf[offset%EEPROM_PAGE_SIZE]=(byte)(val>>8);
  buf[offset%EEPROM_PAGE_SIZE+1]=(byte)val;   
  if (EraseSector((byte*)address)!=PASS)
      return -4;
  for (i=0;i     if(WriteByte((byte*)(address+i),buf)==FAIL) return -5;
  return 0;
}
/*保存通道设置,min在高,max在低,chx<0数据为alarm*/
uint8 Save_Channel_Setting(unsigned char chx,uint32 val) {
  uint16 address;
  uint8 ch;
  uint32 ala,war;
  if ((uint16)System_Config_Current != EEPROM_START_ADDRESS) { //eeprom未启用
    if (Save_System_Config_Default()) return -1;     
  }
  if ((*System_Config_Current).Verification_Code != EEPROM_VERIFICATION_CODE)
    return -3;  
  if (chx&0x80) {
    ch=~chx;
    ala=val;
    war=WARNING_VAL32(ch);
  } else {
    ch=chx;
    war=val;
    ala=ALARM_VAL32(ch);
  }  
  address=EEPROM_CHANNELSETTING_STARTADDRESS+ch*EEPROM_PAGE_SIZE;  
  if (address>=EEPROM_END_ADDRESS) return -2;
   
  if (EraseSector((byte*)address)!=PASS)
      return -4;
  if (WriteWord((unsigned char *)(address+0),(unsigned int)(ala>>16))) return -5;
  if (WriteWord((unsigned char *)(address+2),(unsigned int)(ala))) return -5;
  if (WriteWord((unsigned char *)(address+4),(unsigned int)(war>>16))) return -5;
  if (WriteWord((unsigned char *)(address+6),(unsigned int)(war))) return -5;
  return 0;
}
点赞  2012-12-24 09:58
/********************************************flash.h**********************************/
#define PASS  0
#define FAIL  1
#define FLASHCMD_ERASE   0x40
#define FLASHCMD_PROG    0x20
#define FLASHCMD_CBEF    0x80

#define EEPROM_VERIFICATION_CODE      0x5C5C
#define EEPROM_FACTORY_VERIFICATION   0xAA55
#define EEPROM_START_ADDRESS          0x1400
#define EEPROM_END_ADDRESS            0x1800
#define EEPROM_PAGE_SIZE              8

struct System_Config {
uint16 Verification_Code;                   //检验码1
uint16 Factory_Setting_Verification_Code;   //出厂设置校验码
uint16 notused1;
uint16 notused2;
/***********************can总线设置*******************************/
uint16 Default_ID;                //默认11位标准ID值,扩展帧此数值在高11位即28~18
uint16 notused4;
uint16 notused5;
uint16 notused6;
uint16 notused7;
uint16 notused8;
uint16 notused9;
uint16 notused10;
//滤波器
uint16 Can_Identifier_Acceptance01;      //滤波值
uint16 Can_Identifier_Mask01;            //掩位
uint16 Can_Identifier_Acceptance23;      
uint16 Can_Identifier_Mask23;            
uint16 Can_Identifier_Acceptance45;      
uint16 Can_Identifier_Mask45;
uint16 Can_Identifier_Acceptance67;      
uint16 Can_Identifier_Mask67;
};
/****************************通道参数设置,每个通道8字节****************************/
struct S_Channel_Setting {        //顺序影响写入。。。
uint16 Ch_Alarm_Min;              //通道1报警下限
uint16 Ch_Alarm_Max;              //通道1报警上限
uint16 Ch_Warning_Min;            //通道1提示下限
uint16 Ch_Warning_Max;            //通道1提示上限
};
//位于eeprom的通道设置起始地址
#define EEPROM_CHANNELSETTING_STARTADDRESS        (EEPROM_END_ADDRESS-32*16)
#define WARNING_VAL32(ch)     (((uint32)(Channel_Setting_Array[ch].Ch_Warning_Min)<<16)+(uint32)(Channel_Setting_Array[ch].Ch_Warning_Max))
#define ALARM_VAL32(ch)       (((uint32)(Channel_Setting_Array[ch].Ch_Alarm_Min)<<16)+(uint32)(Channel_Setting_Array[ch].Ch_Alarm_Max))
extern struct System_Config * System_Config_Current;  //系统当前设置
extern struct S_Channel_Setting * Channel_Setting_Array;
extern uint8 EEPRom_Init(void);
extern uint8 Save_System_Config_Default(void);
extern uint8 Save_System_Parameter(unsigned char offset,unsigned int val);
extern uint8 Save_Channel_Setting(unsigned char chx,unsigned long val);
点赞  2012-12-24 09:59
非常的感谢,读的时候直接指向物理地址可以访问
点赞  2012-12-28 21:39
是的,擦写都要用函数,一擦一页(eeprom是8字节),一写一字节必需擦过的,读随意
点赞  2012-12-31 13:57

回复 6楼 huo_hu 的帖子

写的时候单片机重启是怎么回事
点赞  2013-1-6 21:59

回复 7楼 zhangdaoyu 的帖子

调试看看,哪句引起的?参数?
点赞  2013-1-7 11:59
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复