打印

把张教主的FLASH写EEPROM的移到MC9S08QG8怎么不成,哪出错了?

[复制链接]
2497|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
FENG89|  楼主 | 2007-12-14 17:48 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
把张教主的FLASH写EEPROM的移到MC9S08QG8怎么不成,哪出错了?
//MC9S08QG8

#include <hidef.h> /* for EnableInterrupts macro */
#include "derivative.h" /* include peripheral declarations */


//自己定义一个汇编NOP指令的宏

#define NOP() asm(nop)
#define SIZE_FUNC_RAM 50    //擦写在RAM中的空间.

//函数类型声明

void WriteEE(byte*, byte*, byte);   //写一串数据字节到E2
void EraseEE(byte*);                //擦除E2数据页


//定义一些数据段
//==============================================================
// Following data are declared as EEPROM (Flash emulation)
// Refer to PRM file for address mapping
//==============================================================
//  PRM文件定义---是EEPROM定义.*/
//    ROM                      =  READ_ONLY    0XE000 TO 0XF5FF;
//    EPROM                    =  READ_ONLY    0xF600 TO 0xFDFF;
//    ROM1                     =  READ_ONLY    0xFE00 TO 0xFFCF;
//    END
//PLACEMENT /* Here all predefined and user segments are placed into the SEGMENTS defined above. */
//    EEPROM                              INTO  EPROM;





#pragma CONST_SEG EEPROM
const byte EE_Data[2048]; //保留一页Flash空间作为E2模拟
//#pragma CONST_SEG DEFALUT //default data segment
//==============================================================
// Following data are declared in the direct addressing area
// for fast access (address < 0x100)
//==============================================================
#pragma DATA_SEG SHORT MY_ZEROPAGE //direct addressing data segment
byte testData[8]={'1', '2', '3', '4', '5', '6', '7', '8'}; //测试时被写入E2的数据

//==============================================================
// Following data are declared in the common data area
// (address >= 0x100)
//==============================================================

#pragma DATA_SEG DEFALUT //default data segment


void MCU_init(void); //初始化MCU


//主程序入口

void main(void) {

MCU_init();

EnableInterrupts;
 EraseEE((byte*)EE_Data);
WriteEE((byte*)EE_Data, testData, 8);
for(;;) {
__RESET_WATCHDOG(); // feeds the dog

}

}


//MCU初始化子程序

void MCU_init(void)
{
// 配置时钟频率
 FCDIV = 0x27; //set FCLK base on 8MHz Fbus  200K
}


//下面这段代码是专门为启动Flash编程命令然后查询编程结束标志

//在执行之前必须被拷贝到RAM区(任意地址),然后从RAM中运行

//=============================================================================
byte ExecEePrgCmd(byte cmd)
{
FCMD = cmd;        //set command
FSTAT_FCBEF = 1;   //command launched and FCBEF cleared
NOP();             //wait at least 4 nop
NOP();
NOP();
NOP();
if (FSTAT_FPVIOL || FSTAT_FACCERR) {  //exit if encounter any error
return(0);                            //return with error flag
}
while(!FSTAT_FCCF) {                  //wait for FCCF=1
__RESET_WATCHDOG(); 
}
return(1);                            //return with success
}


//定义上面一段代码的长度,编译后不超过50字节
//写一串数据到模拟E2区,大部分代码是在Flash区内运行的,只是上面关键的一小段代码必须拷贝到RAM区才能运行

void WriteEE(byte* eeAddr, byte* datBuff, byte byteCount)
{
byte i;
byte *srcPtr;
byte codeBuff[SIZE_FUNC_RAM]; //buffer size is slightly bigger than the length of ExecEePrgCmd function

//这里示范的是将关键代码拷贝到局部变量(堆栈)区。用户可以将代码拷贝到静态数据区,一样使用

//Copy ExecEePrgCmd code into RAM
srcPtr = (byte*)ExecEePrgCmd;          //function entry in Flash
for (i=0;i<SIZE_FUNC_RAM;i++) {       //do byte copy
codeBuff = srcPtr;
}

FSTAT_FACCERR = 1;                   //clear any pending Flash error flag

while (byteCount) {
*eeAddr++ = *datBuff++;             //latch data byte and memory address
DisableInterrupts;                  //禁止任何中断,很重要!!!
((byte (*)(byte))codeBuff)(0x20);   //编程一个字节 在前面加 (void)就没有了报警 -C1420
EnableInterrupts;
byteCount--;
}
}


//擦除E2页面,原理基本同上//=============================================================================
// Erase a page of EEPROM (Flash emulated)
//=============================================================================
void EraseEE(byte* eeAddr)
{
byte i;
byte *srcPtr;
byte codeBuff[SIZE_FUNC_RAM]; //buffer size is slightly bigger than the length of ExecEePrgCmd function

//Copy ExecEePrgCmd code into RAM
srcPtr = (byte*)ExecEePrgCmd; //function entry in Flash
for (i=0;i<SIZE_FUNC_RAM;i++) { //do byte copy
codeBuff = srcPtr;
}

FSTAT_FACCERR = 1; //clear any pending Flash error flag

*eeAddr = 0;       //latch memory address
DisableInterrupts;
((byte (*)(byte))codeBuff)(0x40); //do page erase在前面加 (void)就没有了报警 -C1420
EnableInterrupts;
}

相关帖子

沙发
forthlab| | 2007-12-14 19:15 | 只看该作者

是否也是栈溢出了,放大些.

没有看你的程序
我也遇到过FLASH程序操作问题.是栈太小了.
你的程序是否也是栈溢出了,放大些.

使用特权

评论回复
板凳
feng89| | 2007-12-14 23:25 | 只看该作者

改大了也不行!

改大了也不行,看了好多例,大部份是用汇编的,操作流程也了解了,在汇编中,地址是放到H:X中的,但在C中,一点不了解,楼上兄弟,能否方便给你的程序我参考一下? 

使用特权

评论回复
地板
forthlab| | 2007-12-15 11:33 | 只看该作者

给个邮件,我把我的flash程序给你

使用特权

评论回复
5
feng89| | 2007-12-15 12:59 | 只看该作者

我的电子邮件

谢谢兄弟,
我的电子邮件:ttgp@21cn.com

使用特权

评论回复
6
forthlab| | 2007-12-15 15:41 | 只看该作者

邮件已经发了

建议参考这个帖子:
https://bbs.21ic.com/club/bbs/bbsView.asp?boardid=11

使用特权

评论回复
7
feng89| | 2007-12-15 16:44 | 只看该作者

谢谢,但少了一个函数

谢谢,但少了一个函数
memcpy(_pgm + 2, ROM_PGM, sizeof(ROM_PGM));这个少了,能给我补上来吗?

使用特权

评论回复
8
forthlab| | 2007-12-15 18:06 | 只看该作者

memcpy()是标准函数,lib库里面的

memcpy()是标准函数,lib库里面的

使用特权

评论回复
9
张明峰| | 2007-12-15 22:43 | 只看该作者

找了个QG8试了下

发现楼主的代码应该是完全可以正常工作的。但发现有一个问题:如果调试界面的memory观察窗口对准模拟EEPROM区域显示的话,程序运行后内容没有变化。难道是CW的问题?我用CW6.0版做的测试。

使用特权

评论回复
10
feng89| | 2007-12-16 14:05 | 只看该作者

原来是这样,我也是在CW6.0的,写一个显示程序看看!

原来是这样,我也是在CW6.0的,写一个显示程序看看!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

39

主题

159

帖子

1

粉丝