⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 S08系列单片机AW32的Flash擦写程序
💻 C
字号:
#include <hidef.h> /* for EnableInterrupts macro */
#include "derivative.h" /* include peripheral declarations */

byte a,n_Write=0x44,n_Erase=0x41; //擦除与写入子函数的长度
int i,j;
volatile byte flash @0x00009100;//定义flash擦除的位置
void FlashWrite(byte i_write);
void FlashErase(void);
void Delay_ms(int Time); //延迟函数,延迟Time毫秒
void Delay_us(int Time); //延迟函数,延迟Time微秒

//*****  Flash擦写地址的其他定义方式
//byte *flash;//用指针定义,灵活性好
//#define flash  (*(volatile byte*)(0xa000))
//byte flash @0x0000a000;
/*
typedef union {
  byte Byte;
  struct {
    byte flash0       :1;                                       
    byte flash1       :1;                                      
    byte flash2       :1;                                     
    byte flash3       :1;                                    
    byte flash4       :1;                                      
    byte flash5       :1;                                   
    byte flash6       :1;                                     
    byte flash7       :1;                                     
  } Bits;
} FLASH;
extern volatile FLASH _flash @0x0000a000;
#define flash         _flash.Byte
*/


 

byte (*pointE_fun)(),(*pointE_fun_temp)(),(*pointW_fun)(),(*pointW_fun_temp)();//函数指针
byte *pointE_add,*pointE_add_temp,*pointW_add,*pointW_add_temp;//将Flash中程序移动到Ram中
void main(void) {
  
  //word i,N=200;
   
  /* MCU_init(); */
  SOPT = 0x53;                                      
  /* SPMSC1: LVDF=0,LVDACK=0,LVDIE=0,LVDRE=1,LVDSE=1,LVDE=1 */
  SPMSC1 = 0x1C;                                      
  /* SPMSC2: LVWF=0,LVWACK=0,LVDV=0,LVWV=0,PPDF=0,PPDACK=0,PDC=0,PPDC=0 */
  SPMSC2 = 0x00;                                      
  /* ICGC1: RANGE=1,REFS=0,CLKS1=0,CLKS0=0,OSCSTEN=1 */
  ICGC1 = 0x44;                                      
  /* ICGC2: LOLRE=0,MFD2=0,MFD1=0,MFD0=0,LOCRE=0,RFD2=0,RFD1=0,RFD0=0 */
  ICGC2 = 0x00;                                      
  /* Common initialization of the write once registers */
  SRS = 0xFF;                          /* Clear WatchDog counter */

  SOPT = 0x00;
  DisableInterrupts;
  /* include your code here */
  PTADD=0xFF;	 /*A口方向寄存器,设置PTA为输出*/
  PTAD=0x00;
  Delay_ms(100);
  
  /*与FLASH相关的寄存器
  FCDIV;
  FOPT;
  NVOPT;
  FCNFG;
  FSTAT;
  FCMD;//0x05空白检测,0x20写一个字节,0x25写一个字节批量模式,0x40页擦除,0x41整体擦除
  */
  //flash=(byte*)0xa000; //定义擦写的flash地址
  PTBDD=0x00;  /*B口方向寄存器,设置PTB为输入,AD信号输入*/
  AD1CFG=0x00;//8位AD采集,使用系统时钟
  
  //PTAD=flash;
  Delay_ms(500);
  AD1SC2=0x00;
  APCTL1=0x00; //AD0-7作为模拟信号输入
  AD1SC1=0x21; //AD中断禁止,从通道1采集,连续采集
  PTAD=flash;  //读取Flash地址的值,并赋给发光二极管便于观察结果
  Delay_ms(500);
  PTAD=0x00;//所有灯灭,然后等待写入Flash地址新的值便于对比  
   
  while(AD1SC1_COCO==0){
  ;}//查询AD转换标志位,没有则等待

   a=AD1RL;//将AD采来的值赋给a
  
   
   
  // a=100;//仿真
   //Delay_us(100);
   pointE_fun=FlashErase;
   pointE_add=pointE_fun;
   pointE_add_temp=(byte*)0x0200;
   pointE_fun_temp=pointE_add_temp;  
   for(i=0;i<=n_Erase;i++)           //此处n_Erase的具体值得看后面的FlashErase子程序占有的程序空间
   {
    *(pointE_add_temp+i)=*(pointE_add+i);
   }//Flash中的程序复制到RAM中
   FCDIV = 0x13;
   (*pointE_fun_temp)();//在RAM中运行擦除子程序
   Delay_ms(200); 
   
   ///****  试图用汇编写复制程序到RAM中,后放弃
   //asm{
   //LDHX #flash
   //};
   //asm("jsr,X");
   //FCDIV = 0x13;
   //flash=(byte*)0xa000;
   //FlashErase();
   //asm{
   //LDHX #_FlashErase 
   // STHX a
   //}
            
  
  Delay_ms(200);
  pointW_fun=FlashWrite;
   pointW_add=pointW_fun;
   pointW_add_temp=(byte*)0x0250;
   pointW_fun_temp=pointW_add_temp;  
   for(i=0;i<=n_Write;i++)//此处n_Write的具体值得看后面的FlashWrite子程序占有的程序空间
   {
    *(pointW_add_temp+i)=*(pointW_add+i);
   }//Flash中的程序复制到RAM中   
   (*pointW_fun_temp)(a);//在RAM中运行写入子程序
   
   Delay_ms(200);  
   for(;;) {
    while(AD1SC1_COCO==0){
      ;
    }
    a=AD1RL;
   PTAD=a;
   __RESET_WATCHDOG(); /* feeds the dog */
  } /* loop forever */
  /* please make sure that you never leave this function */
}

//                    延迟函数,延迟Time毫秒或微秒
//********************************************************************
void Delay_ms(int Time) //延迟函数,延迟Time毫秒
{

  int i_Delay_ms,j_Delay_ms;
  for(i_Delay_ms=0;i_Delay_ms<Time;i_Delay_ms++)  {
    for(j_Delay_ms=0;j_Delay_ms<1000;j_Delay_ms++) {
       ;  
    }
  }
}//end
//memcpy


void Delay_us(int Time) //延迟函数,延迟Time微秒
{
 int i_Delay_us;
 for(i_Delay_us=0;i_Delay_us<Time;i_Delay_us++){
  ;
 }
}//end
////********************************************************************

////             flash写入程序,向特定地址写入一个数  
////********************************************************************
void FlashWrite(byte i_write) { //flash写入

  //NVPROT_FPDIS=1;  //flash不进行保护
  while(FSTAT_FACCERR==1){  //清错误标志确保擦写操作可以进行
    FSTAT_FACCERR=0;         
    //while(FCDIV_DIVLD==0){
    //  FCDIV = 0x13;
    //}
  }
  //flash=i_white;   
  //FCNFG_KEYACC=0; 
  
  while(FSTAT_FCBEF==0){
    ;
  }//检查flash命令缓冲区空标志,等待直到可以接受新的命令
  
  flash=i_write;//向Flash地址写入数据
  
  FCMD=0x20;//写入命令字
      
  //FCMD=0x20;
  FSTAT_FCBEF=1;
  
  if(FSTAT_FPVIOL==1||FSTAT_FACCERR==1)  { //异常情况处理
    PTAD=0x00;
    Delay_ms(2000);
  } 
  while(FSTAT_FCCF==0){
    //PTAD=0x80;
  } //写入成功,结束
  
}

////********************************************************************


////             flash擦除程序,擦除特定地址的数据  
////********************************************************************
void FlashErase(){  //flash擦除
  //NVPROT_FPDIS=1;  //flash不进行保护
  while(FSTAT_FACCERR==1){  //清错误标志确保擦写操作可以进行
    FSTAT_FACCERR=0;         
    //while(FCDIV_DIVLD==0){
    //  FCDIV = 0x13;
    //}
  }
  //flash=0x00;   
  //FCNFG_KEYACC=0; 
  while(FSTAT_FCBEF==0){
    ;
  }//检查flash命令缓冲区空标志,等待直到可以接受新的命令
  
  flash=0x00;//向Flash地址写入数据
  FCMD=0x40; //写入命令字
      
  //FCMD=0x40;
  FSTAT_FCBEF=1;
  
  if(FSTAT_FPVIOL==1||FSTAT_FACCERR==1)  { //异常情况处理
    PTAD=0x00;
    Delay_ms(2000);
  } 
  while(FSTAT_FCCF==0){
    //PTAD=0x80;
  } //擦除成功,结束  
}

////********************************************************************

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -