搜索
bottom↓
回复: 4

CC430单片机诡异问题求助

[复制链接]

出0入0汤圆

发表于 2011-4-6 10:16:45 | 显示全部楼层 |阅读模式
最近用CC430F5137单片机做一个东西,使用的IAR的编译器,出现了很诡异的东西:
1.系统中有一个128*64的LCD,之前我想做一个cache也就是一个全局二维数组和这128*64个点阵一一对应,结果程序直接挂掉;当时没在意;
2.昨天程序定义了一个结构体,然后定义了一个全局的结构体数组,结果操作这个结构体数组,程序也直接挂掉:
  A、我看了map文档,看了这个结构体数组确实是落在RAM区域并且也没有溢出;
  B、打开List输出在list文件中看反汇编,看上去也是对的。
不知道哪位大虾有这样的解决经验?

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2011-4-6 12:09:22 | 显示全部楼层
没用过;
看到你的头像,就想到N年前你对我所提问题的解答,影象深刻, 顶一下.

出0入0汤圆

 楼主| 发表于 2011-4-6 18:38:41 | 显示全部楼层
本着对别人和自己负责的有始有终的原则,说说现在的更新或者状态:
    我发现只要把操作那个数组的语句mark掉,结果就不会死掉;仔细看最后生成的map文件,发现因为没有操作和使用,这个数组被优化掉了,于是我想到一个方法就是把这个数组的大小减小到1或者2,然后把别的文件中的数组也减小,最后居然发现不会死掉!
    我的第一反应就是这些数据和堆栈有冲突,于是转而去研究msp430的堆栈。msp430的堆栈老实说,资料说得不清楚,或者说具有二义性(有些地方看上去说是向下生长,有些地方看上去说是向上生长),我通过程序测试,发现是向下生长的,也就是说,最初把堆栈设在RAM的Top位置,这种设计其实比向上增长要好,不需要例外设置SP了,除了程序用到的RAM,其它都给了堆栈;但是程序员要自己保证堆栈不会盖到数据区。CC430F5137是有4K RAM的,我看了很明显是足够的,所以不是数据和堆栈引起的问题。
    然后我继续做测试,终于发现有些规律,也就是全局变量超过256个才会出问题,再看map文档,发现定义的全局变量分为三种:
    DATA16_N:不需要初始化的
    DATA16_I:初始化为非0的
    DATA16_Z: 初始化为0的(包括定义没有初始化,会自动初始化为0)
    如果不加修饰就会认为是需要初始化为0的,通过看IAR的帮助文档,可以用 no_init来修饰这些变量成为不要初始化的。现在我的解决方法是把一些用到的buffer定义成 no_init的,使得整个DATA16_Z 的size小于256.问题得以解决。

    个人猜想应该是IAR的启动程序限定了 DATA16_I 和 DATA16_Z 的大小,但我没有找到对应的地方,如果有哪位大虾知道,请指点一下。

出0入4汤圆

发表于 2011-5-4 02:54:33 | 显示全部楼层
IAR编译的方法,导致看门狗溢出了。 单片机上电的时候看门狗已经启动, 但是在进入main函数之前,软件会首先去初始化你用到的一些数据,比如数组之类的, 如果你的数组定义的比较大, 那么初始化的时间就会很长,当然在这过程中,看门狗的时间就到了,单片机复位,然后在启动,在初始化……,这样循环。

解决方法是,使用低级初始化函数, IAR编译的时候,会自动把低级初始化的函数放在程序的最开始处,这样你可以在低级初始化函数里面先把看门狗关掉, 等低级初始化函数执行完了,才会进行数据初始化的处理,在然后才执行main函数,
详细解决方法参考IAR的这篇文档:http://supp.iar.com/Support/?note=37778&from=search+result

按照IAR的这个方法,如果你觉得添加文件麻烦,实际上最简单的是,自己编写一个 __low_level_init 函数, 就行了, 这个函数不需要你在主函数里面调用, 这个函数会被编译器编译在程序的最开始部分。

下面是我写的一个简单的程序,测试通过,供参考:

#include "msp430f5438.h"
unsigned char buffer0[10240];
void main(void)
{
  
  unsigned int i;

  P5SEL |= 0x0C;                            // Port select XT2
  UCSCTL6 &= ~XT2OFF;                       // Enable XT2
  UCSCTL3 |= SELREF_2;                      // FLLref = REFO
                                            // Since LFXT1 is not used,
                                            // sourcing FLL with LFXT1 can cause
                                            // XT1OFFG flag to set
  UCSCTL4 |= SELA_2;                        // ACLK=REFO,SMCLK=DCO,MCLK=DCO

  // Loop until XT1,XT2 & DCO stabilizes
  do
  {
    UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + XT1HFOFFG + DCOFFG);
                                            // Clear XT2,XT1,DCO fault flags
    SFRIFG1 &= ~OFIFG;                      // Clear fault flags
  }while (SFRIFG1&OFIFG);                   // Test oscillator fault flag

  UCSCTL6 &= ~XT2DRIVE0;                    // Decrease XT2 Drive according to
                                            // expected frequency
  UCSCTL4 |= SELS_5 + SELM_5;               // SMCLK=MCLK=XT2

  P1DIR |= BIT0;                            // P1.0 output

  
  for(i=0;i<10240;i++)
  {
    buffer0 = i % 256;   
  }

  while(1)
  {
   
    for(i=0;i<10240;i++)
      P1OUT = buffer0;
   
  }
}


int __low_level_init(void)
{
  WDTCTL = WDTPW+WDTHOLD;                   // Stop WDT
  /* Insert your low-level initializations here */

  /*
   * Return value:
   *
   *  1 - Perform data segment initialization.
   *  0 - Skip data segment initialization.
   */

  return 1;
}


如上,如果没有 __low_level_init 这个函数,直接把关闭看门狗的语句写道主函数里面,单片机将永远进入不了main。

当然你也可以把所有的硬件初始化的语句写在这个函数里面,这样硬件将会在单片机复位后第一时间进行初始化。

出0入0汤圆

发表于 2011-5-4 10:04:59 | 显示全部楼层
CC430F5137  多少钱?
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-28 15:19

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表