msp430 问题及解决记录

-----------------------------

2015.4.28

问题:开发板串口显示的内容为乱码

解决:使用的是原先产品主板的15200的波特率设置,但看来或者是开发板不支持115200或者是设置不正确。

错误的波特率设置:

UCA3BR0 = 9; // 1MHz 115200 (see User's Guide)
UCA3BR1 = 0;

正确的波特率设置:

UCA3BR0 = 0x03 ; // 32kHz/9600=3.41
UCA3BR1 = 0x00

-----------------------------

2015.4.29

问题:程序跑飞

解决:越界访问局部变量导致的。

详情:

函数中声明了一个局部变量: char cpTempSensorValue[20];

然后使用sprintf语句给格式化cpTempSensorValue,但是操作的字符串的长度大于20,而程序中又没有进行越界检查,因此导致跑飞。

-----------------------------

2015.5.8

问题:8025 IIC 调试不通

描述:使用硬件IIC而不是IO模拟来实现,但并没有采用IIC中断。卡在以下程序(直接从 return 1 返回了):

// 等待UCTXIFG=1与UCTXSTT=0 同时变化等待一个标志位即可
while(!(UCB2IFG& UCTXIFG))
{
  if( UCB2IFG& UCNACKIFG ) // 若无应答 UCNACKIFG=1
  {
     return 1;
  }
}

解决:最后发现是从机地址的问题,从8025芯片手册上看到的地址为 0x64,但是MSP430在实际使用需要往地址寄存器中放入7位地址(即不包含读写位),因此需要使用右移1位的地址,即:0x64>>1

-----------------------------

2015.5.8

问题:8025 IIC 设置控制寄存器问题

描述:IIC 虽然调试通了,但是程序初始化时需要把8025的控制寄存器设置为24小时模式,因此需要写往0x0E寄存器中写入0x20;但是,每次写入完后发现rtc读出的秒都被重置为某个值。

解决:参考了其他程序,给IIC的UCB2TXBUF寄存器写入的控制寄存器地址应该左移4位。即:0x0E<<4

备注:虽然问题解决了,但依然没有搞清楚。

-----------------------------

2015.5.18

问题:fabs错误

描述:fabs的结果不正确,经检查发现编译时有fabs的警告,

解决:增加“#include <math.h>”

备注:估计还有其他地方也实现了fabs。

-----------------------------

2015.5.25

问题:debug时跳转不到main函数,发现一直在 data16_memzero函数中死循环。

解决:参考了网友的解决办法,详情如下:

一直在_data16_memzero里死循环可能是因为程序最开始初始化变量的时候有大数组需要初始化。导致看门狗不断复位。这个初始化的过程是在进入main之前,有2种方式你可以尝试:

1.对你的数组用 __no init_定义,上电编译器不产生特殊的附加函数去初始化RAM
2. B
修改IARCstartup.S43文件中__program_start子程序,增加一个关闭WDT的操作或者设置WDT时间长度超过32MS
C
Project--Options--Linker--Config中选择 Override default programe,并将Entry lib设置成__program_start

 

事实也确实如此,Cstartup.S43是MSP430的启动文件,里面默认是打开看门狗的,添加个宏定义把看门狗关闭就解决了问题。

 

具体操作如下:

在安装文件:C:……srclib430 中找到启动文件:cstartup.s43

拷一个cstartup.s43,然后将其只读属性去掉。用记事本等打开cstartup.s43文件,看到文件内有如下语句:


#ifdef DISABLE_WATCHDOG

        MOV     #WDTPW + WDTHOLD, &WDTCTL
#endif


说明文件内已经有关闭看门狗的条件编译语句,只要我们定义条件,这样启动代码中的该语句就生效了,我们在文件头添加一句:

#define DISABLE_WATCHDOG

保存,然后再工程中将cstartup.s43文件添加到我们的工程当中。

在Project->Options->Linker->Config页中选择Override default programe ,并将Entry symb 设置成__program_start。
把debugger->setup->Run to main销掉,这样我们就能够从启动代码开始一句一句的看了。 

cstartup.s43在iar310a的路径如下$TOOLKIT_DIR$srcLIB

-----------------------------

2015.5.27

问题:变量类型转换的不正确使用

1、 ff = (float)g_iPicDataLength/(float)(CAMERA_PACKAGE_SIZE-6);

2、 ff = g_iPicDataLength/(CAMERA_PACKAGE_SIZE-6);

类型说明:ff为float;  g_iPicDataLength CAMERA_PACKAGE_SIZE为int

例如对于 17116÷506 正确的结果应该是33.8

如果采用1可以得到正确的结果,如果采用2则得到33.0

而我正好使用到了ceil函数:

int i = ceil(ff);

这样用时,1和2两种不同的方法计算的结果不同,1的结果为34,而2的结果为33

-----------------------------

2015.6.25

问题:收串口相机的图像数据时会稳定地丢数据

描述:串口相机的默认数据包长度为512,使用这个长度时没有任何问题。但是为了一次能传送更多的数据,我希望能增加数据包的长度,我修改为1024,但是发现无论如何会固定地丢失3个字节的数据(丢第510,511,512三个字节,注意计数从1开始)。

解决:各种尝试后找到问题。时钟中断触发的很频繁,并且430默认的不允许中断嵌套,这样会导致系统处理时钟中断的时候丢失掉串口收数据的中断。解决方法是在时钟中断中开中断。

-----------------------------

2015.6.26

问题:同样的程序在一个串口相机可以采集到数据,而在另外一个串口相机采集不到

解决:经分析后发现,这两个串口相机还是有略微的不同,软件版本应该有所差别。用串口助手对串口相机与其自带测试软件的通讯过程进行了监测之后,发现了问题。正常的串口相机在重新加电后,只要发送一两次同步命令就可以同步上,但是不正常的串口相机在重新加电后却要发送10多次同步指令才可以同步上。针对这个研究结果,做了针对性的处理:发送一次同步命令之后,过一定时间间隔[称为间隔1]如果收到了相机的回应就不再发同步指令,而是执行后续操作,而如果过一定时间间隔没有收到了相机的回应就重新发送一次同步指令,这样重复多次。

但是发现还有问题,经研究发现,问题出在:程序中有这样的处理(在串口发送数据的过程中,如果间隔[称为间隔2]一定时间没有发送数据了,就认为之前的数据是完整的一包数据,可以对其进行处理了),但是重复发送同步命令的间隔1小于间隔2,因此在重复发送同步命令时,同步回应还在路上呢,所以系统总是判断没有收到正确的同步回应。把间隔2调整使其小于间隔1后该问题解决。

处理之后,发现还有问题:即拍照命令总是失败。调试后发现,是因为调整了间隔2之后,拍照的回应只收到了6个字节后就处理了,而系统的处理是发现这6个字节不是想要的12个字节,因此就抛弃了这6个字节,所以虽然马上又过来了6个字节,但是系统也仍然认为是错误的拍照响应。处理的方法为:当响应数据不够12个字节时先缓存该收到的内容,等收到的内容大于等于12个字节后再处理。

之后再测试,在两个串口相机上,所有问题解决。

-----------------------------

2015.6.30

问题:从上位串口执行获取系统参数命令,但得到的结果中SensorEnable的值为(Null Pointer)

解决:设备使用了sprintf来格式化输出字符串,SensorEnable是字符串类型,因此使用了%s来格式化。以为是字符串本身的问题,但各种尝试后没找到问题原因。怀疑是sprintf中其他的格式化内容影响了SensorEnable,尝试后的确实是。Interval=%d格式化部分对应的变量是gs_stSetup.m_iReportInterval,而该变量原本是long long unsigned int型的,编译时系统有警告,但是我忽略掉了;查了资料,说是格式化时应该使用Interval=%llu,但iar系统似乎不能识别llu,这能识别lu。

最终,把gs_stSetup.m_iReportInterval的类型修改为long unsigned int,并把格式化内容修改为Interval=%lu后问题解决。

原文地址:https://www.cnblogs.com/gaotaozhaolei/p/4465015.html