2011
10
闪存改写源代码 [单片机]
post by My_ovo / 2011-11-10 9:37 Thursday0 Comments »
/***********************************************************************/
/* */
/* FILE :R5F212L.c */
/* This file is generated by Renesas Project Generator (Ver.4.12). */
/* //对一个块中的数据写入时,必须对整个的块擦除 */
/***********************************************************************/
#include "sfr_r82l.h"
/* Definition of const data */
#define BLOCK_A ((unsigned char *)0x2400) /* BLOCK A first address */
#define BLOCK_A_END ((unsigned char *)0x27ff) /* BLOCK A last address */
#define BLOCK_B ((unsigned char *)0x2800) /* BLOCK B first address */
#define BLOCK_B_END ((unsigned char *)0x2Bff) /* BLOCK B last address */
#define RECORD_PER_BLOCK 1 /* Record number per 1 block */
#define RECORD_SIZE 1024 /* Record size */
#define BLOCK_A_SELECT 0 /* Use BLOCK A */
#define BLOCK_B_SELECT 1 /* Use BLOCK B */
#define COMPLETE 0x00 /* FLASH write/erase complete */
#define PROGRAM_ERR 0x01 /* FLASH data write error */
#define ERASE_ERR 0x02 /* FLASH erase error */
/* Definition of RAM area */
unsigned char *write_addr; /* Write address */
unsigned char block_select; /* Block select flag */
unsigned char *write_addr_temp1;
unsigned char *write_addr_temp2;
/* Declaration of function prototype */
void write_address_init(void);
unsigned char flash_write(unsigned char *data);
unsigned char block_erase(unsigned char *ers_addr);
unsigned char data_write(unsigned char *write_data);
void make_data(unsigned char *write_data);
void main(void)
{
static unsigned char write_data[RECORD_SIZE]; /* wirte data */
unsigned char result;
unsigned int i = 0;
/*-----------------------------------------------
-Change on-chip oscillator clock to Main clock -
-------------------------------------------------*/
prc0 = 1; /* Protect off */
cm13 = 1; /* Xin Xout */
cm15 = 1; /* XCIN-XCOUT drive capacity select bit : HIGH */
cm05 = 0; /* Xin on */
while( i <= 255 ) i++; /* This setting is an example of waiting time for the */
/* oscillation stabilization. Please evaluate the time */
/* for oscillation stabilization by a user. */
ocd2 = 0; /* Main clock change */
cm16 = 0; /* Main clock = No division mode */
cm17 = 0;
cm06 = 0; /* CM16 and CM17 enable */
prc0 = 0; /* Protect on */
/*-----------------------------------
- Initialize SFR -
-----------------------------------*/
prcr = 0x02;
pm1 = 0x01; /* Data block enable */
prcr = 0;
fmr4 = 0x00; /* Erase suspend mode disable */
write_address_init(); /* Write address pointer initialize */
make_data(write_data); /* Make write data */
/* Data write */
result = flash_write(write_data);
if( (result & PROGRAM_ERR) != 0 )
{
/* Program error */
}
if( (result & ERASE_ERR) != 0)
{
/* Erase error */
}
write_addr_temp1 = BLOCK_A;
write_addr_temp2 = BLOCK_A+10;
while(1)
{
}
}
/************************************************************************************
Name: make_data
Parameters: Record data pointer
Returns: None
Description: Make record data
************************************************************************************/
void make_data(unsigned char *data)
{
/* Make record data */
data[0]=40;
data[10]=50;
data[12]=60;
}
/************************************************************************************
Name: write_address_init
Parameters: None
Returns: None
Description: Write address initialize
************************************************************************************/
void write_address_init(void)
{
int i;
int j;
write_addr = BLOCK_A; /* first sarch address */
/* Brank record check */
while( write_addr <= BLOCK_B_END )
{
/* Record all ff check */
for(j = 0; j < RECORD_SIZE; j++)
{
if( write_addr[j] != 0xff )
{
break;
}
}
if (j == RECORD_SIZE)
{
break;
}
write_addr = write_addr + RECORD_SIZE; /* Check address renew */
}
if(write_addr >= BLOCK_B_END+1)
{
/* if BLOCK A and BLOCK B are full then BLOCK A erase */
block_erase(BLOCK_A);
write_addr = BLOCK_A;
block_select = BLOCK_A_SELECT;
}
else if(write_addr >= BLOCK_B)
{
/* Use BLOCK B */
block_select = BLOCK_B_SELECT;
}
else
{
/* Use BLOCK A */
block_select = BLOCK_A_SELECT;
}
}
/************************************************************************************
Name: flash_write
Parameters: Write record data
Returns: Result (Complete or program error or erase error)
Description: Initial setting of SFR registers
************************************************************************************/
unsigned char flash_write(unsigned char *data)
{
unsigned char result = COMPLETE;
if( data_write( data ) != COMPLETE )
{
/* Program error occurence */
result = result | PROGRAM_ERR; /* if program error */
}
/* Next write address update */
write_addr = write_addr + RECORD_SIZE;
if( (block_select == BLOCK_A_SELECT) && (write_addr > BLOCK_A_END) )
{
/* BLOCK A all write */
if( block_erase( BLOCK_B ) != COMPLETE )
{
/* Erase error occurence */
result = result | ERASE_ERR;
}
block_select = BLOCK_B_SELECT;
write_addr = BLOCK_B;
}
else if( (block_select == BLOCK_B_SELECT) && (write_addr > BLOCK_B_END) )
{
/* BLOCK B all write */
if( block_erase( BLOCK_A ) != COMPLETE )
{
/* Erase error occurence */
result = result | ERASE_ERR;
}
block_select = BLOCK_A_SELECT;
write_addr = BLOCK_A;
}
return result;
}
/************************************************************************************
Name: block_erase
Parameters: Erase block address
Returns: Erase result
Description: Block erase
************************************************************************************/
unsigned char block_erase(unsigned char *ers_addr){
unsigned char erase_result;
/* If use interrupt then clear i flag... */
/* asm("fclr i "); */
/* flash control register set */
fmr0 = 0x01;
asm(" "); /* Description for preventing the abbreviation by optimization */
fmr0 = 0x03; /* CPU rewrite enable */
fmr1 = 0x80;
asm(" "); /* Description for preventing the abbreviation by optimization */
fmr1 = 0x82; /* EW1 mode */
*ers_addr = 0x20; /* Block erase command write */
*ers_addr = 0xd0; /* Block erase command write */
while( fmr00 != 1 ); /* Ready check */
/* Erase status check */
if( fmr07 == 1 ){
*ers_addr = 0x50; /* Clear stutus register */
erase_result = ERASE_ERR;
}else{
erase_result = COMPLETE;
}
/* flash control register reset */
fmr0 = 0x01; /* CPU rewrite disable */
/* If use interrupt then set i flag... */
/* asm("fset i "); */
return erase_result;
}
/************************************************************************************
Name: data_write
Parameters: Record data address
Returns: Program result
Description: Record program
************************************************************************************/
unsigned char data_write( unsigned char *write_data )
{
unsigned char program_result = COMPLETE;
int i; /* loop counter */
/* If use interrupt then clear i flag... */
/* asm("fclr i "); */
/* flash control register set */
fmr0 = 0x01;
asm(" "); /* Description for preventing the abbreviation by optimization */
fmr0 = 0x03; /* CPU rewrite enable */
fmr1 = 0x80;
asm(" "); /* Description for preventing the abbreviation by optimization */
fmr1 = 0x82; /* EW1 mode */
for( i = 0; i < RECORD_SIZE; i++ )
{
write_addr = 0x40;
write_addr = write_data;
while( fmr00 != 1 ); /* Ready check */
/* Program status check */
if( fmr06 == 1 )
{
/* Program error */
*write_addr = 0x50; /* Clear stutus register */
program_result = PROGRAM_ERR;
break;
}
}
/* flash control register reset */
fmr0 = 0x01; /* CPU rewrite disable */
/* If use interrupt then set i flag... */
/* asm("fset i "); */
return program_result;
}
/* */
/* FILE :R5F212L.c */
/* This file is generated by Renesas Project Generator (Ver.4.12). */
/* //对一个块中的数据写入时,必须对整个的块擦除 */
/***********************************************************************/
#include "sfr_r82l.h"
/* Definition of const data */
#define BLOCK_A ((unsigned char *)0x2400) /* BLOCK A first address */
#define BLOCK_A_END ((unsigned char *)0x27ff) /* BLOCK A last address */
#define BLOCK_B ((unsigned char *)0x2800) /* BLOCK B first address */
#define BLOCK_B_END ((unsigned char *)0x2Bff) /* BLOCK B last address */
#define RECORD_PER_BLOCK 1 /* Record number per 1 block */
#define RECORD_SIZE 1024 /* Record size */
#define BLOCK_A_SELECT 0 /* Use BLOCK A */
#define BLOCK_B_SELECT 1 /* Use BLOCK B */
#define COMPLETE 0x00 /* FLASH write/erase complete */
#define PROGRAM_ERR 0x01 /* FLASH data write error */
#define ERASE_ERR 0x02 /* FLASH erase error */
/* Definition of RAM area */
unsigned char *write_addr; /* Write address */
unsigned char block_select; /* Block select flag */
unsigned char *write_addr_temp1;
unsigned char *write_addr_temp2;
/* Declaration of function prototype */
void write_address_init(void);
unsigned char flash_write(unsigned char *data);
unsigned char block_erase(unsigned char *ers_addr);
unsigned char data_write(unsigned char *write_data);
void make_data(unsigned char *write_data);
void main(void)
{
static unsigned char write_data[RECORD_SIZE]; /* wirte data */
unsigned char result;
unsigned int i = 0;
/*-----------------------------------------------
-Change on-chip oscillator clock to Main clock -
-------------------------------------------------*/
prc0 = 1; /* Protect off */
cm13 = 1; /* Xin Xout */
cm15 = 1; /* XCIN-XCOUT drive capacity select bit : HIGH */
cm05 = 0; /* Xin on */
while( i <= 255 ) i++; /* This setting is an example of waiting time for the */
/* oscillation stabilization. Please evaluate the time */
/* for oscillation stabilization by a user. */
ocd2 = 0; /* Main clock change */
cm16 = 0; /* Main clock = No division mode */
cm17 = 0;
cm06 = 0; /* CM16 and CM17 enable */
prc0 = 0; /* Protect on */
/*-----------------------------------
- Initialize SFR -
-----------------------------------*/
prcr = 0x02;
pm1 = 0x01; /* Data block enable */
prcr = 0;
fmr4 = 0x00; /* Erase suspend mode disable */
write_address_init(); /* Write address pointer initialize */
make_data(write_data); /* Make write data */
/* Data write */
result = flash_write(write_data);
if( (result & PROGRAM_ERR) != 0 )
{
/* Program error */
}
if( (result & ERASE_ERR) != 0)
{
/* Erase error */
}
write_addr_temp1 = BLOCK_A;
write_addr_temp2 = BLOCK_A+10;
while(1)
{
}
}
/************************************************************************************
Name: make_data
Parameters: Record data pointer
Returns: None
Description: Make record data
************************************************************************************/
void make_data(unsigned char *data)
{
/* Make record data */
data[0]=40;
data[10]=50;
data[12]=60;
}
/************************************************************************************
Name: write_address_init
Parameters: None
Returns: None
Description: Write address initialize
************************************************************************************/
void write_address_init(void)
{
int i;
int j;
write_addr = BLOCK_A; /* first sarch address */
/* Brank record check */
while( write_addr <= BLOCK_B_END )
{
/* Record all ff check */
for(j = 0; j < RECORD_SIZE; j++)
{
if( write_addr[j] != 0xff )
{
break;
}
}
if (j == RECORD_SIZE)
{
break;
}
write_addr = write_addr + RECORD_SIZE; /* Check address renew */
}
if(write_addr >= BLOCK_B_END+1)
{
/* if BLOCK A and BLOCK B are full then BLOCK A erase */
block_erase(BLOCK_A);
write_addr = BLOCK_A;
block_select = BLOCK_A_SELECT;
}
else if(write_addr >= BLOCK_B)
{
/* Use BLOCK B */
block_select = BLOCK_B_SELECT;
}
else
{
/* Use BLOCK A */
block_select = BLOCK_A_SELECT;
}
}
/************************************************************************************
Name: flash_write
Parameters: Write record data
Returns: Result (Complete or program error or erase error)
Description: Initial setting of SFR registers
************************************************************************************/
unsigned char flash_write(unsigned char *data)
{
unsigned char result = COMPLETE;
if( data_write( data ) != COMPLETE )
{
/* Program error occurence */
result = result | PROGRAM_ERR; /* if program error */
}
/* Next write address update */
write_addr = write_addr + RECORD_SIZE;
if( (block_select == BLOCK_A_SELECT) && (write_addr > BLOCK_A_END) )
{
/* BLOCK A all write */
if( block_erase( BLOCK_B ) != COMPLETE )
{
/* Erase error occurence */
result = result | ERASE_ERR;
}
block_select = BLOCK_B_SELECT;
write_addr = BLOCK_B;
}
else if( (block_select == BLOCK_B_SELECT) && (write_addr > BLOCK_B_END) )
{
/* BLOCK B all write */
if( block_erase( BLOCK_A ) != COMPLETE )
{
/* Erase error occurence */
result = result | ERASE_ERR;
}
block_select = BLOCK_A_SELECT;
write_addr = BLOCK_A;
}
return result;
}
/************************************************************************************
Name: block_erase
Parameters: Erase block address
Returns: Erase result
Description: Block erase
************************************************************************************/
unsigned char block_erase(unsigned char *ers_addr){
unsigned char erase_result;
/* If use interrupt then clear i flag... */
/* asm("fclr i "); */
/* flash control register set */
fmr0 = 0x01;
asm(" "); /* Description for preventing the abbreviation by optimization */
fmr0 = 0x03; /* CPU rewrite enable */
fmr1 = 0x80;
asm(" "); /* Description for preventing the abbreviation by optimization */
fmr1 = 0x82; /* EW1 mode */
*ers_addr = 0x20; /* Block erase command write */
*ers_addr = 0xd0; /* Block erase command write */
while( fmr00 != 1 ); /* Ready check */
/* Erase status check */
if( fmr07 == 1 ){
*ers_addr = 0x50; /* Clear stutus register */
erase_result = ERASE_ERR;
}else{
erase_result = COMPLETE;
}
/* flash control register reset */
fmr0 = 0x01; /* CPU rewrite disable */
/* If use interrupt then set i flag... */
/* asm("fset i "); */
return erase_result;
}
/************************************************************************************
Name: data_write
Parameters: Record data address
Returns: Program result
Description: Record program
************************************************************************************/
unsigned char data_write( unsigned char *write_data )
{
unsigned char program_result = COMPLETE;
int i; /* loop counter */
/* If use interrupt then clear i flag... */
/* asm("fclr i "); */
/* flash control register set */
fmr0 = 0x01;
asm(" "); /* Description for preventing the abbreviation by optimization */
fmr0 = 0x03; /* CPU rewrite enable */
fmr1 = 0x80;
asm(" "); /* Description for preventing the abbreviation by optimization */
fmr1 = 0x82; /* EW1 mode */
for( i = 0; i < RECORD_SIZE; i++ )
{
write_addr = 0x40;
write_addr = write_data;
while( fmr00 != 1 ); /* Ready check */
/* Program status check */
if( fmr06 == 1 )
{
/* Program error */
*write_addr = 0x50; /* Clear stutus register */
program_result = PROGRAM_ERR;
break;
}
}
/* flash control register reset */
fmr0 = 0x01; /* CPU rewrite disable */
/* If use interrupt then set i flag... */
/* asm("fset i "); */
return program_result;
}