首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

请教:两个指针相减,结果错错误

请教:两个指针相减,结果错错误


/*函数说明
*  1.void EarseFlash(unsigned int addr)               *
*    Flash擦除子程序                                  *
*  2.void WriteFlash(unsigned int addr)               *
*    Flash写入子程序                                  */


#include <hidef.h> /* for EnableInterrupts macro */
#include <MC68HC908MR32.h> /* include peripheral declarations */
#include <String.h>


//内存变量声明
unsigned int *PrgBeginAddr,*PrgEndAddr; //PrgBeginAddr 程序开始地址 PrgEndAddr 程序结束地址
unsigned int faddr;


unsigned char PrgOfRam[10];             //要移到内存种的程序 存放擦/写FLASH程序以便执行


// 疑问: 如果定义成写成PrgOfRam[],不定义数组大小,下面这两种写法都会报错
//
//        memcpy((void *)PrgOfRam[0],(void *)PrgBeginAddr,PrgEndAddr-PrgBeginAddr); 
//        memcpy((void *)PrgOfRam[],(void *)PrgBeginAddr,PrgEndAddr-PrgBeginAddr); 
//        而C语言中 是允许 不定义数组大小的 。


int PrgBytes;                         // 要移到内存中的程序字节数 , 调试用。


byte N ;


//内部调用函数声明


void DoEraseFlash(void);
void EraseFlashEnd(void);


/*EarseFlash:擦除指定flash的一页-----------------------*
*功  能:擦除以addr为首地址的flash一页                  *
*参  数:addr要擦除的首地址                             *
*返  回:无                                             *
*-----------------------------------------------------*/
void EarseFlash(unsigned int addr)
  {
   faddr=addr;                   //擦除flash的首地址   
 //将擦除程序从Flash区拷贝到RAM区PrgOfRam
    
// asm { ldhx DoEarseFlash };   //擦除程序的首地址->HX  汇编写法,可以调试通过
// asm { sthx PrgBeginAddr};    //HX->rgBegInAddr, 这种写法有限制,经测试,PrgBegInAddr 要分配
                                //在零页才能调试通过,所以 这两条我改用C 来写
  (void*)PrgBeginAddr=DoEraseFlash  ;
   // asm { ldhx EarseFlashEnd}; //读擦除程序的结束地址->HX
   // asm { sthx PrgEndAddr}   ; // 这两条语句也改成 C 语言的, 原因同上
  
  (void*)PrgEndAddr=EraseFlashEnd;
  PrgBytes=PrgEndAddr-PrgBeginAddr; // 计算要移动的程序字节数
                                    // 编译器 分配的地址 PrgBeginAddr :0x8104
                                    //                   PrgEndAddr   :0x813b
                                    //
                                    // 0x813b-0x8104 应该是 0x37  10进制 55
                                    // 可是实际的结果是     0x1b   10进制 27
                                    // 但步运行 汇编码,发现编译后的汇编码在做完减法后
                                    // 又执行了一段除法操作,所以结果才不对的。

/ memcpy((void *)PrgOfRam[0],(void *)PrgBeginAddr,PrgEndAddr-PrgBeginAddr);


// 上面的这条语句,运行时可能会出显?
//" Attempt to use unimplemented memroy" 错误,好像时访问到
// 没有数据的Flash 地址了,具体原因我还没有查清除

memcpy((void *)0x0060,(void *)0x8104,0x37);
// 这条语句可以正确执行,按理来说,这条语句和上面的那条语句
// 是等价的,不知道为什么上面的那条不行 。


// asm {ldhx PrgOfRam }; //这种写法,编译器通不过,不知道正确调用数组首地址应该该怎么写??
// 不知道CW里面 对数组是如何 如何定义的

// asm { jsr ,X }; //设想执行RAM区域的程序 ,可是这条也不能通过编译,不知道正确的写法是什么?


}




/*DoEarseFlash:擦除指定flash区-------------------------*
*功 能: 真正执行擦除addr指向的flash区的操作 *
*参 数:无 *
*返 回:无 *
*内部调用:延时函数delay1 *
*---------------------------------------------- -------*/
void delay1(void);

void DoEraseFlash(void)
{
unsigned char i;
FLCR=0b00000010; //①1->ERASE,0->MASS(页擦除)
i=FLBPR; //②读FLBPR
//③任意数->faddr,选中flash页
*((volatile unsigned char *)faddr)=0x00;
asm ("bsr delay1"); //④延时10us
FLCR=0b00001010; //⑤1->HVEN (加高压)
asm ("bsr delay1"); //延时时间必须>1.6ms
FLCR=0b00001000; //⑦0->Erase
asm ("bsr delay1"); //⑧10us
FLCR=0b00000000; //⑨0->HVEN(取消高压)
asm ("bsr delay1"); //⑩延时10us
}
void delay1(void) //测试用非精确延时程序
{ unsigned char j;
for (j=0;j<10;j++); }

void EraseFlashEnd(void) //擦除程序的末地址
{ }

// 主程序,测试用

void main()
{

CONFIG=0;

for(;;)
{
EarseFlash(0x8000);
}
}


一次发上来,论坛的程序报错, 只好分两次发上来了,

我的疑问都用注释标出来了,请熟悉 cw 的高手指点一下,谢谢!!!
如果只是一条指令,ASM后面可以不用大括号。
海纳百川  有容乃大
等了好几天,总算有人顶了一下! 不过问题的原因还是没有找到!

斑竹可以随便写个两个函数,用两个指针指向两个函数的名。 然后这个两个指针相减,看看结果对不对? 头都大了,就是找不到减法出错的原因。!! 已经晕了!

我已经试过好多次了,难道是我的CW 软件有问题吗?
memcpy函数的原型是(dest_addr, src_addr, size)
写成PrgOfRam[]等于是数组,肯定是出错的。
函数名直接就可以表示地址,不需要用指针去指向函数。
比如:
void DoEraseFlash(void)
{ ......}

void EraseFlashEnd(void)
{......}

这两个函数紧邻相连,那么DoEraseFlash函数的字节数目可以这样计算
unsigned int n;
n=(unsigned int)EraseFlashEnd-(unsigned int)DoEraseFlash;

这里unsigned int是16bit的数据长度


谢谢 seuafu2005 得回复!

问题得原因我找到了,viod 类型指针在ANSI-C 中是不允许做运算得。如果用GCC编译是允许 void 类型指针做运算。

希望有机会能和 seuafu2005 多交流!
返回列表