标题: 请教:对GT16中FLASH操作的问题,谢谢! [打印本页]
作者: xiaoxiaoer 时间: 2006-2-15 16:55 标题: 请教:对GT16中FLASH操作的问题,谢谢!
各位高手请指教:谢谢!
我对GT16的FLASH进行擦除和写入数据,全部是用C 写的,擦除和写入程序已经放到在RAM中了。而且我也能看到PC指针指向了我放置的RAM地址0X0100,但接下来程序窗口就白屏了,程序飞掉了。请问:这是怎么回事?
我已经对以前的帖子都看了,现在对如何在RAM中执行擦除和写入程序不清楚,各位高手能不能说得更清楚一些?能否提供一例子?另外,在RAM中如果执行完了这两个子程序,接下来PC是应该指向FLASH中其它的程序地址吗?我能在CW调试环境中的MEMORY窗口直接看到我写入的数据吗?
多谢指教 !
作者: seuafu2005 时间: 2006-2-16 10:24
可能是你的PC指针没有正确返回flash中,另外可以看看flash的状态寄存器中Error位是否有出错的信息。
正常的把整个擦写程序放入RAM中执行以后,通过return(RTS)指令都是可以返回到flash中来的,你在copy程序过去以后,看看你存放擦写程序的那段RAM中是否有正确的返回指令(RTS).
如果程序执行正确,在擦写以后,可以在CW的memory环境中看到你所写入的数据。
作者: xiaoxiaoer 时间: 2006-2-16 12:02
谢谢楼上热心指教!我再试一试。
作者: xiaoxiaoer 时间: 2006-2-17 12:06
不好意思,我还是没有调出来。通过机器码,我确认了在RAM的程序段最后有返回指令,即81。现在的现象是: 在RAM中执行程序时,SOURCE窗口显示的是start08.c,运行完FLASH擦除程序后不返回而是飞了。
请高手继续指点,谢谢!
我还有问题:
1、在FLASH擦写程序中,时间延迟是做的子程序,这样子在RAM运行的话一样还是要跳转到FLASH中的。是不是在FLASH 擦写程序中不能调用子程序?
2、前面seuafu2005提到的FLASH 额状态寄存器在哪里?我没有发现有这么个寄存器。怎么知道出错信息呢?
3、用C实现取得函数起始地址怎么实现?
4、我在以前的帖子中看到这样的源代码:
void(*a)();
move(DoEaraseFlash,0x3d);
a=(byte *)0x0100;
(*a)();
我理解最后一句就是跳转到RAM中执行的,对吗?这个函数具体的内容是怎样的?
弄了一个星期了,还是没有实现FLASH的擦写,很头疼。我对这个过程不理解,
请高手们多指教!谢谢!
作者: nishui_2000 时间: 2006-2-17 13:12
我也准备开始调试把Flash的擦写拷贝到RAM中执行,不过手头还没硬件。也期待哪位大侠能给指点一下。
不过xiaoxiaoer 你可以把你的Flash擦写和拷贝那块,发到我信箱里一份,我看看跟我写的是否一样
我的信箱是: nishui_2000@163.com ,我的网站是: www.dyic.com.cn
作者: seuafu2005 时间: 2006-2-17 14:51
如果你会用CW中的Processor Expert,建议新建一个工程用其生成对flash操作的函数,你会比较了解如何在C中调用RAM中的程序。
在对flash操作时要注意这么几点:
1.通过FCDIV寄存器把clock设置在150-200kHz的范围
2.关闭中断
3.拷贝到RAM中运行
4.FSTAT状态寄存器中的FACCERR为零
5.是否有对flash某些块或者整个区域的保护(一般默认整个flash没有保护,均可以擦除)
6.要烧写的地址必须为空(0xFF),否则必须先擦除
7.GT16是字节的烧写
可用这个语句
*(volatile unsigned char *)flash_addr=(unsigned char) value;
flash_addr是16bit的address,如果不用强制类型转换,会烧写失败
8.烧写过程的调试不要用单步。看好datasheet,按步骤一步一步操作就可以,一共就3/4个步骤。要看结果,可以等烧写程序完成查看。
作者: nishui_2000 时间: 2006-2-17 16:26
seuafu2005:
我觉得你说的一个地方不对,
*(volatile unsigned char *)flash_addr=(unsigned char) value;
flash_addr是16bit的address,如果不用强制类型转换,会烧写失败
那你的意思就是把16位的地址强制转换成8位,那就是把高8位的地址信息扔掉。而地址都是16位的,你把他高8位扔掉了,能行么?
作者: xiaoxiaoer 时间: 2006-2-20 14:10
FLASH中的地址赋值应该是这样的:
*(volatile unsigned int *)flash_addr=(unsigned char) value;楼上说得对,不能是8位的。
现在主要感觉是PC跳到RAM中就没有返回!
感谢seuafu2005的热心指点,但您说的FCDIV和FSTAT是什么呢?
nishui_2000:我周末上不了网,一会儿给你发过去邮件,多交流。谢谢!
作者: strongchen 时间: 2006-2-20 14:41
HC08和S08对FLASH的操作不太一样,寄存器也不同。希望仔细看一下数据手册中相关部分的内容。
作者: nishui_2000 时间: 2006-2-21 10:08
HC08和S08的Flash操作的寄存器是不一样,但那是次要的,因为对寄存器的操作看手册就一目了然,现在关键是怎么把程序复制到RAM中然后正确的执行,这是通用的也是问题的关键
xiaoxiaoer 如果你的问题还没解决,就在给我发个邮件。我手头有问同事要的GP32的Flash操作,不过我没试验过,你正好可以试试用他的方法调试你的Flash那块
作者: seuafu2005 时间: 2006-2-21 15:24
明白了,你说的是908GT16,我说的是9S08GT16
怪不得你找不到我说的寄存器了。
[此贴子已经被作者于2006-2-21 15:24:21编辑过]
作者: xiaoxiaoer 时间: 2006-3-2 09:41
感谢大家的关注!
我已经调试出来了,关键在于RAM中运行及运行完了还需要返回FLASH中继续下面的工作。所以 ,在FLASH擦写程序最后需要有返回FLASH的操作才行。
不知道我说的对不对,现在我就是这样擦写成功了。
但还有点小问题向大家请教:
1、如果需要写入FLASH中的常量数据比较多,这些数据放在哪里呢?放在FLASH中应该不行的,在RAM中就有个容量的问题,这个怎么解决呢?
2、如果写入的数据是变化的全局变量,它们的位置通常放置在哪里?感觉数据手册中说得不清楚。这样的话,又该怎么办呢?
我想把FLASH的操作搞透彻一些,感谢高手指点!
作者: xiaoxiaoer 时间: 2006-3-2 09:45
非常感谢nishui_2000的热心帮助!
你能不能把GP32的FLASH程序发给我一份,我参照比较一下,应该有助于对FLASH操作的理解!
谢谢!
以后多交流!
作者: strongchen 时间: 2006-3-2 10:17
为什么你认为常量数据放在FLASH中是不行的?
作者: nishui_2000 时间: 2006-3-2 14:38
xiaoxiaoer :
我现在发现一个读写QG8的新的Flash程序,非常好用,不必象GP32那样,我在QG8单凭机调试过了没问题的,直接拷贝过来就可以用,真是简单,而且代码简洁!
#define Page_Erase PGM[21]=0x40; temp = ((unsigned char(*)(unsigned int))(PGM))
#define Program_Byte PGM[21]=0x20; temp = ((unsigned char(*)(unsigned int, unsigned char))(PGM))
//Array of opcode instructions of the Erase/Program function in the HCS08 family
volatile unsigned char PGM[59] = {
0x87,0xC6,0x18,0x25,0xA5,0x10,0x27,0x08,0xC6,0x18,0x25,0xAA,0x10,0xC7,0x18,0x25,
0x9E,0xE6,0x01,0xF7,0xA6,0x20,0xC7,0x18,0x26,0x45,0x18,0x25,0xF6,0xAA,0x80,0xF7,
0x9D,0x9D,0x9D,0x9D,0x45,0x18,0x25,0xF6,0xF7,0xF6,0xA5,0x30,0x27,0x04,0xA6,0xFF,
0x20,0x07,0xC6,0x18,0x25,0xA5,0x40,0x27,0xF9,0x8A,0x81};
void main(void) {
unsigned char temp,i;
MCU_init();
/* include your code here */
temp = Page_Erase(0xF000);
if(temp==0xFF){
PTAD=0;
}
for(i=0; i<= 255; i++) {
temp = Program_Byte(0xF000+i,i);
if(temp==0xFF){
PTAD=0;
}
}
for(;;) {
__RESET_WATCHDOG(); /* feeds the dog */
} /* loop forever */
作者: strongchen 时间: 2006-3-2 15:23
要注意QG8是S08的,与HC08的FLASH操作非常不同。
作者: xiaoxiaoer 时间: 2006-3-3 15:15
版主: 对FLASH擦写的程序要放到RAM中执行,如果在写入FLASH的程序中需要返回FLASH中取一些要写入的常量数据,这样就是在FLASH处于高编程电压的情况下对FLASH进行操作,会造成FLASH擦写失败。
我个人认为这是飞思卡尔片子的一个瑕疵,^_^
事实上,08系列的FLASH擦写是比较麻烦的。个人观点啊
作者: strongchen 时间: 2006-3-3 15:37
在对FLASH进行擦或写的操作时,MCU内部会对FLASH加一个较高的编程电压。此时CPU无法再去读取FLASH中的数据了。所有的单片机都是这样的。此时应当先将要写的数据也放入RAM中。
作者: lionheart 时间: 2006-3-6 14:27
看来9S08和908的FLASH编程很不一样
今天看了一下两种芯片手册
9S08里面没有提到要延时
908里面却着重指出了这点
xiaoxiaoer你的FLASH擦除程序能不能给我发一份看看呢?
我现在在研究HC908GZ16的FLASH擦写,呵呵 我的mail是zzh7807@163.com
作者: kbfz2008 时间: 2006-3-6 15:28
用C如何拷贝指定函数至RAM?
还请各位赐教~~
作者: xiaoxiaoer 时间: 2006-3-9 14:53
我上网不是很方便,以前的帖子中有类似的程序。搜索一下就可以看到。
要注意在RAM执行完FLASH的擦写程序后一定要有返回FLASH的程序指令才行。
我这样做的 :在FLASH擦写子程序的最后,调用后面操作的子程序。这样,PC执行完RAM后就跳转会FLASH执行后续的工作了。
大家多交流!
欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) |
Powered by Discuz! 7.0.0 |