打印

18系列复位后变量的初值是多少? 谢谢,老叶和asspeed

[复制链接]
8852|34
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 Ryanhsiung 于 2011-11-25 18:22 编辑

18系列复位后RAM区的变量 初值为多少?  0 、 1 、还是未知??
我用的芯片是:18F4620

谢谢,老叶和asspeed 耐心解答!
  恩,本以来入了门,其实门槛都没摸到! 我还需要继续努力学习啊!!
谢谢
整理了一下老叶和asspeed ,放在一个WORD文档中了

PIC初始化一些疑惑解答.rar

4.84 KB

来自 2楼
asspeed| | 2011-11-25 10:58 | 只看该作者
大哥,你不知道如何使用也不要乱用呀。
你自己把原始的lkr文件复制一份单独用于你的项目,
然后你告诉编译器你要使用该lkr文件,如何告诉?将lkr定位文件夹指向你需使用的lkr所在的文件夹路径。
下面一步,我们要改lkr文件了,怎么改?
打开它,看到下面的东东吗?
// File: 18f4620_g.lkr
// Generic linker script for the PIC18F4620 processor

#DEFINE _CODEEND _DEBUGCODESTART - 1
#DEFINE _CEND _CODEEND + _DEBUGCODELEN
#DEFINE _DATAEND _DEBUGDATASTART - 1
#DEFINE _DEND _DATAEND + _DEBUGDATALEN

LIBPATH .

#IFDEF _CRUNTIME
  #IFDEF _EXTENDEDMODE
    FILES c018i_e.o
    FILES clib_e.lib
    FILES p18f4620_e.lib

  #ELSE
    FILES c018i.o
    FILES clib.lib
    FILES p18f4620.lib
  #FI

#FI

改两个地方:
   #IFDEF _EXTENDEDMODE
    FILES c018iz_e.o
    FILES clib_e.lib
    FILES p18f4620_e.lib

  #ELSE
    FILES c018iz.o
    FILES clib.lib
    FILES p18f4620.lib
  #FI


完了,编译,看结果。

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
Ryanhsiung + 1
板凳
Ryanhsiung|  楼主 | 2011-11-24 16:57 | 只看该作者
这个问题GOOGLE都不能!太。。。。。。。

使用特权

评论回复
地板
yewuyi| | 2011-11-24 17:03 | 只看该作者
和其它所有芯片的RAM都一样,都是未知,当然在绝大多数情况下,如果是掉电的话,则多数应该为0,但这并不是确定保证的。

所以这也就是为什么在使用C语言编写程序是,都会自动插入一段RAM初始化为0的代码,也就是常说的启动代码。

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
Ryanhsiung + 1
5
Ryanhsiung|  楼主 | 2011-11-24 17:05 | 只看该作者
本帖最后由 Ryanhsiung 于 2011-11-24 18:35 编辑

我这用的MCC18编译器
是这段吗?
copy_one_byte:
        tblrdpostinc
        movf TABLAT, 0, 0
        movwf POSTINC0, 0

        // decrement byte counter
        decf curr_byte, 1, 1
        bc -8 // copy_loop
        decf curr_byte + 1, 1, 1
        bra -7 // copy_one_byte

done_copying:

会将所有的RAM都清0吗?

使用特权

评论回复
6
Ryanhsiung|  楼主 | 2011-11-24 17:12 | 只看该作者
若以BOOTLOADER固件做为ISP烧录,在线烧录应用程序时这一段启动代码会被烧录进去吗,会被执行吗??

使用特权

评论回复
7
Ryanhsiung|  楼主 | 2011-11-24 18:36 | 只看该作者
如下,我对照MPLAB于烧录器,前段是有启动代码的!   莫非是片子出了问题?

1112334.jpg (248.7 KB )

1112334.jpg

使用特权

评论回复
8
yewuyi| | 2011-11-25 08:00 | 只看该作者
我这用的MCC18编译器
是这段吗?
copy_one_byte:
        tblrdpostinc
        movf TABLAT, 0, 0
        movwf POSTINC0, 0

        // decrement byte counter
        decf curr_byte, 1, 1
        bc -8 // copy_loop
        decf curr_byte + 1, 1, 1 ...
Ryanhsiung 发表于 2011-11-24 17:05



对PIC18的ASM指令不熟悉,但看上去似乎是,另外,大多数C编译器嵌入的启动代码并不会将所有的RAM都清除,只是把你用到的RAM区清除而已,用不到的空间可能就不处理了。

使用特权

评论回复
9
Ryanhsiung|  楼主 | 2011-11-25 08:00 | 只看该作者
和其它所有芯片的RAM都一样,都是未知,当然在绝大多数情况下,如果是掉电的话,则多数应该为0,但这并不是确定保证的。

所以这也就是为什么在使用C语言编写程序是,都会自动插入一段RAM初始化为0的代码,也就是常 ...
yewuyi 发表于 2011-11-24 17:03



今天DEBUG了一下,发现启动代码过后并没有将变量清0,变量还保持上一次的值!!!
启动代码是也看不太懂,望请教!!

使用特权

评论回复
10
Ryanhsiung|  楼主 | 2011-11-25 08:10 | 只看该作者
所有的变量都保持了复位前的值,貌似没有执行你说的“RAM初始化为0的代码,也就是常说的启动代码。”

使用特权

评论回复
11
yewuyi| | 2011-11-25 08:40 | 只看该作者
所有的变量都保持了复位前的值,貌似没有执行你说的“RAM初始化为0的代码,也就是常说的启动代码。”
Ryanhsiung 发表于 2011-11-25 08:10

我不知道你是怎么看?怎么设置编译器的?但各种类型的C编译器在这上面都大同小异,如果你没有关闭启动代码等操作的话,我以PIC16F1936举例如下。

如图,我定义了一个数组signed   char   MenuCase[menulength];
在WATCH窗口中添加该数组,你会看到这个数组中各个元素的数值。
通过这个窗口你可以看到这个数组中的各个元素在执行了启动代码后的前后数值变化对比。

Image00000.jpg (50.97 KB )

Image00000.jpg

使用特权

评论回复
12
Ryanhsiung|  楼主 | 2011-11-25 08:46 | 只看该作者
也不知道是不是设置问题 以下为红色为复位前的,我手动改的数值,另一张为复位后

前.jpg (44.29 KB )

前.jpg

后.jpg (40.77 KB )

后.jpg

使用特权

评论回复
13
Ryanhsiung|  楼主 | 2011-11-25 08:47 | 只看该作者
下面是初始代的启动代码中的一段,这段的做用是什么,是不是檫除所有的RAM,汇编我看不懂  
test:
    _asm
     bnz 3
    tstfsz curr_entry, 1
    bra 1
    _endasm
    goto done;
      /* Count down so we only have to look up the data in _cinit
       * once.
       *
       * At this point we know that TBLPTR points to the top of the current
       * entry in _cinit, so we can just start reading the from, to, and
       * size values.
       */
      _asm
        /* read the source address */
        tblrdpostinc
        movf TABLAT, 0, 0
        movwf prom, 1
        tblrdpostinc
        movf TABLAT, 0, 0
        movwf prom+1, 1
        tblrdpostinc
        movf TABLAT, 0, 0
        movwf prom+2, 1
        /* skip a byte since it's stored as a 32bit int */
        tblrdpostinc
        /* read the destination address directly into FSR0 */
        tblrdpostinc
        movf TABLAT, 0, 0
        movwf FSR0L, 0
        tblrdpostinc
        movf TABLAT, 0, 0
        movwf FSR0H, 0
        /* skip two bytes since it's stored as a 32bit int */
        tblrdpostinc
        tblrdpostinc
        /* read the destination address directly into FSR0 */
        tblrdpostinc
        movf TABLAT, 0, 0
        movwf curr_byte, 1
        tblrdpostinc
        movf TABLAT, 0, 0
        movwf curr_byte+1, 1
        /* skip two bytes since it's stored as a 32bit int */
        tblrdpostinc
        tblrdpostinc
      _endasm  
      //prom = data_ptr->from;
      //FSR0 = data_ptr->to;
      //curr_byte = (unsigned short) data_ptr->size;
      /* the table pointer now points to the next entry. Save it
       * off since we'll be using the table pointer to do the copying
       * for the entry.
       */
      data_ptr = TBLPTR;
      
      /* now assign the source address to the table pointer */
      TBLPTR = prom;

      /* do the copy loop */
      _asm
        // determine if we have any more bytes to copy
        movlb curr_byte
        movf curr_byte, 1, 1
copy_loop:
        bnz 2 // copy_one_byte
        movf curr_byte + 1, 1, 1
        bz 7 // done_copying

copy_one_byte:
        tblrdpostinc
        movf TABLAT, 0, 0
        movwf POSTINC0, 0

        // decrement byte counter
        decf curr_byte, 1, 1
        bc -8 // copy_loop
        decf curr_byte + 1, 1, 1
        bra -7 // copy_one_byte

done_copying:

      _endasm
      /* restore the table pointer for the next entry */
      TBLPTR = data_ptr;
      /* next entry... */
      curr_entry--;
      goto test;
done:

使用特权

评论回复
14
Ryanhsiung|  楼主 | 2011-11-25 08:53 | 只看该作者
本帖最后由 Ryanhsiung 于 2011-11-25 08:57 编辑
对PIC18的ASM指令不熟悉,但看上去似乎是,另外,大多数C编译器嵌入的启动代码并不会将所有的RAM都清除,只是把你用到的RAM区清除而已,用不到的空间可能就不处理了。 ...
yewuyi 发表于 2011-11-25 08:00

能否上传一下你启动代码,给我看一下
  还有说一下你作的编译器及版本

使用特权

评论回复
15
asspeed| | 2011-11-25 09:12 | 只看该作者
使用的启动代码模块不同,结果也不同,一般来说,如果(idata)变量定义时已经显性赋予初始数值的,其会被初始化。如使用的c018iz.o,其他的未显性赋初值的静态变量都会被清零。

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
Ryanhsiung + 1
16
Ryanhsiung|  楼主 | 2011-11-25 09:26 | 只看该作者
初始调用的是c018i.c,经测试
uint8 Old_LedStatus;         没有初始化
uint8 Old_LedStatus =0;          就被初始化为0了!


LS意思是若用c018iz.o则uint8 Old_LedStatus;也会清0!
我试一下

使用特权

评论回复
17
Ryanhsiung|  楼主 | 2011-11-25 09:35 | 只看该作者
本帖最后由 Ryanhsiung 于 2011-11-25 09:53 编辑
使用的启动代码模块不同,结果也不同,一般来说,如果(idata)变量定义时已经显性赋予初始数值的,其会被初始化。如使用的c018iz.o,其他的未显性赋初值的静态变量都会被清零。 ...
asspeed 发表于 2011-11-25 09:12

能不能讲一下各个c018 c018_e c018i c018i_e c018iz c018iz_e.o 各是什么意思??
若者给出相应文档的连接!谢谢
  现在都变更不了这个连接,怎么连接啊!!!

使用特权

评论回复
18
asspeed| | 2011-11-25 10:05 | 只看该作者
要修改linker 描述文件来选择调用哪种初始化模块。

使用特权

评论回复
19
asspeed| | 2011-11-25 10:09 | 只看该作者
能不能讲一下各个c018 c018_e c018i c018i_e c018iz c018iz_e.o 各是什么意思??
若者给出相应文档的连接!谢谢
  现在都变更不了这个连接,怎么连接啊!!! ...
Ryanhsiung 发表于 2011-11-25 09:35


有i的表示会初始化idata数据段,没有的反之。
有_e的表示工作为扩展模式,没有的反之。
有z的意思前文已经解释。

使用特权

评论回复
20
Ryanhsiung|  楼主 | 2011-11-25 10:13 | 只看该作者
要修改linker 描述文件来选择调用哪种初始化模块。
asspeed 发表于 2011-11-25 10:05

4620 不支持扩展指令,LKR也改了,编译不成功
Error - mixing extended and non-extended mode modules not allowed.
我配置改完后,出现以下提示
but the program that was loaded was not built using extended CPU instructions . ThereFore,your code may not work properly
还是认了,这还是我自己代码的问题,加个初始化就好了!
  
若想要编译器自己初始化的话,那就要自己修改启动代码C018I 或C018I_Z。
asspeed 我说的对不对??

使用特权

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

本版积分规则

认证:嵌入式技术专家
简介:道阻且长,行则将至!

64

主题

4654

帖子

14

粉丝