HCS08单片机改写FLASH参数之——下位机程序
0赞单片机端实现动态改写FLASH参数或更新程序要具备以下2个条件:
1、单片机支持在应用编程IAP。
2、有一种通信接口可以传递要改写的内容。
HCS08系列单片机是支持在应用编程IAP的,并且官方提供了操作代码,是汇编写的,提供了API接口的3个函数:
void FlashErase(const unsigned char * flash_destination);
void FlashProg(const unsigned char * flash_destination, unsigned char data);
unsigned char FlashProgBurst(const unsigned char * flash_destination, unsigned char * ram_source, unsigned char length);
我们通过调用上述函数即可实现FLASH擦除和写入。更多信息参见AN3942。
本例是通过串口实现内容传递,飞思卡尔官方提供了Freemaster来实现上、下位机之间传递变量和内存数据。还留了一条自定义命令方便用户扩展。我们就是用自定义命令实现写FLASH命令。
该示例是一个波形发生器,功能是:
1、2路数字波形输出
2、第一路波形的高电平时间和低电平时间可调
3、第二路波形的上升沿相对第一路的下降沿有一个延时,该延时可调。
上位机的界面是这样的:
为了实现上述功能,需在我们的程序之外加入下列文件:
main.c里有个myhandler函数是处理我们自定义协议的,加入以下代码:
FMSTR_APPCMD_RESULT myhandler(FMSTR_APPCMD_CODE nAppcmd, FMSTR_APPCMD_PDATA pData, FMSTR_SIZE nDataLen)
{
byte *datapointer;
volatile word target_address;
if(nAppcmd == 0x0a){
target_address = ((word)(pData[2])<<8) | pData[3];
switch(pData[0]){
case 1:{ // erase command
FlashErase((unsigned char *)(target_address));
break;
}
case 2:{ // program command
datapointer = pData + 4;
FlashProgBurst((unsigned char *)(target_address), datapointer, pData[1]);
break;
}
default:{
break;
}
}
}// the return value is used as the application command result code
return 0x10;
}
在main,c顶部定义3个全局变量,对应界面中的3个值:
#pragma CONST_SEG MY_DATA
volatile const unsigned long int hi_time = 100;//计到该值时变低
volatile const unsigned long int duty_time = 200;//计到该值时变高,并重新计
volatile const unsigned long int delay_time = 50;//计到该什是变高hi_time+delay_time时变低
#pragma CONST_SEG DEFAULT
红色代码是存储器定位用的,以便把变量放在我们希望的位置。
修改PRM文件,把需擦写的FLASH单独划分出来,下面的红色代码是新加的,绿色代码是有所改动的:
/* This is a linker parameter file for the mc9s08ac16 */
NAMES END /* CodeWarrior will pass all the needed files to the linker by command line. But here you may add your own files too. */
SEGMENTS /* Here all RAM/ROM areas of the device are listed. Used in PLACEMENT below. */
Z_RAM = READ_WRITE 0x0070 TO 0x00FF;
RAM = READ_WRITE 0x0100 TO 0x046F;
ROM = READ_ONLY 0xC000 TO 0xDFFF;
MY_ROM = READ_ONLY 0xE000 TO 0xFFAF;
ROM1 = READ_ONLY 0xFFC0 TO 0xFFC5;
/* INTVECTS = READ_ONLY 0xFFC6 TO 0xFFFF; Reserved for Interrupt Vectors */
END
PLACEMENT /* Here all predefined and user segments are placed into the SEGMENTS defined above. */
DEFAULT_RAM, /* non-zero page variables */
INTO RAM;
_PRESTART, /* startup code */
STARTUP, /* startup data structures */
ROM_VAR, /* constant variables */
STRINGS, /* string literals */
VIRTUAL_TABLE_SEGMENT, /* C++ virtual table segment */
DEFAULT_ROM,
COPY /* copy down information: how to initialize variables */
INTO ROM; /* ,ROM1: To use "ROM1" as well, pass the option -OnB=b to the compiler */
MY_DATA INTO MY_ROM;
_DATA_ZEROPAGE, /* zero page variables */
MY_ZEROPAGE INTO Z_RAM;
END
STACKSIZE 0x80
VECTOR 0 _Startup /* Reset vector: this is the default entry point for an application. */
上面介绍修改FLASH内容的方法。波形的形成是通过定时器实现的,下面是初始化的中断函数:
//=======================================================================================================
//函数名:Init_tpm2_counter
//作用:初始化TPM2,内部时钟工作于自时钟模式,总线频率4M;自由计数;溢出时间间隔=65536/(4000/64)近似1048ms
//========================================================================================================
void Init_tpm2_counter(void)
{
TPM2SC=0x48;//TPM2时钟源为总线时钟;分频系数为8;溢出中断允许
TPM2MOD = 2000;
TPM2CNTH=0;//任意时刻对TPM2CNTH或TPM2CNTL的写操作将计数寄存器的计数值复位(清零)
}
//==================计数器2溢出中断服务程序==========================
interrupt VectorNumber_Vtpm2ovf void TPM2_OVF_ISR(void)
{
static unsigned long int cnt = 0;
if((TPM2SC & 0x80)==0x80)
{
TPM2SC_TOF=0;
}
cnt++;
if(cnt >= duty_time)
{
cnt = 0;
OUT_1 = 1;
}
if(cnt == hi_time)
{
OUT_1 = 0;
}
if(cnt == delay_time)
{
OUT_2 = 1;
}
if(cnt == hi_time + delay_time)
{
OUT_2 = 0;
}
}
![(VLC]SYY7%4K5OTG_]_3]`P[4] (VLC]SYY7%4K5OTG_]_3]`P[4]](http://files.chinaaet.com/images/2012/02/27/10336423131104.jpg)


