搜档网
当前位置:搜档网 › MSP430常见问题汇总(新)

MSP430常见问题汇总(新)

利尔达科技有限公司

技术一部

LSD SCIENCE &TECHNOLOGY CO.,LTD.

MSP430相关Q&A

Question &answer

版本号:V1.0

提交人:MSP430项目组

整理时间:2009年02

第一章:开发工具类

第二章:指令系统

第三章:代码编程类

第四章:工作模式及功耗类

第五章:复位系统类

第六章:看门狗及定时器类

第七章:系统时钟类

第八章:LCD 显示驱动类

第九章:通信类

第十章:IO 端口类

第十一章:FLASH 存储类

第十二章:AD 转换类

第十三章:电源类声明:所有问题均来自网络,部分答案也同样来自网路,答案仅供参考,并不能完全解决在使用中碰到的问题。所以客户在使用MSP430单片机时还是以实际情况来决定。

如有任何疑问欢迎与我们联系:haoqiang@https://www.sodocs.net/doc/f216539873.html, 、gufeng@https://www.sodocs.net/doc/f216539873.html, 、

chenbing@https://www.sodocs.net/doc/f216539873.html,

第一章:开发工具类

Q1:我自己做了一块MSP430F149的试验板,以前用下载线进行调试没有出现过问题,但是,最近我每次make 后用下载线调试时,总是弹出一个窗口,给我提示:Could not find target status.然后就死到那儿了,请问这是什么问题呢?

A1:检查Jtag口线是否连接正常,如果JTAG口线连接正常,可能是供电不足,目标板加电再测试。

Q2:我用的430f22x学习套件,请问在IAR Embedded Workbench中仿真时如何看程序运行时间.

A2:只有软件模拟下可以看,VIEW-REGISTER-CYCLECOUNT

Q3:请问各位msp430仿真器和编程器有什么区别啊?是不是我开发的时候这两个东西都得有?我目前用的是msp430cg461x系列或msp430fg461x系列,是不是很多仿真器和编程器都不支持?

A3:一般来讲,仿真器是在先期调试程序时使用的,他不会烧断单片机熔丝,能把程序下载到单片机中,能够单步,跟踪,快速调试。编程器就没有这些调试功能,就是单纯把你做好的程序的编译后文件写到单片机中去,就和51的编程器一样,有加密熔丝烧断等功能,是在你产品成型后,生产时使用的MSP430的仿真器是使用JTAG接口的,分别有四线制的JTAG、带TEST脚的四线JTAG和两线制的SBWJTAG三种接口,UIF上三种都支持,并支持烧熔丝,UIF就是USB接口的仿真;PIF不能支持SBWJTAG 接口,也不能烧熔丝,PIF是并口的仿真器。任何一种JTAG接口的仿真器在烧断熔丝后都不能再仿真和写入,而BSL可以通过密码访问FLASH空间,读出写入均可,BSL是串口实现的,但BSL不能仿真,注意部分器件不支持BSL,如F20XX系列就不能用BSL,烧掉了熔丝就变板砖。

MSP430任何系列的仿真器只要接口方式一致都是兼容的,比如FG461X,可以使用标准的带TEST的四线JTAG,而F22X4也可以使用带TEST的四线JTAG,当然F22X4还可以选择使用SBWJTAG,它支持两种JTAG接口。如果不是TI标准的430系列用JTAG仿真器那就不行了,应该是不兼容的,不是什么“很多仿真器和编程器都不支持”,而是专用。

Q4:初次使用430单片机,F149。高速晶振8M,低速32K,下载程序时出现security fuse**own字样,无法烧录。请各位高人指点,应该是哪里有问题。

A4:手工复下位应该基本可以解决,除非芯片熔丝真被烧掉了。如果熔丝断了,可以用BSL方式写入程序.

Q5:运行到断点时程序不能自动结束,必须自己按break。我这是程序跑飞了么?

A5:是你断点设置的多了吧。你在程序中,只设置这一个断点试试

Q6:当在RAM中对其中一变量开辟的尺寸是512字节时,程序总占用3.5K RAM空间,可以正常烧到芯片中,也可以正常运行;

当对同一变量开辟的尺寸是1024字节,而其它均未改变时,程序总占用4.0K左右RAM空间,可以正常烧到芯片中,却无法运行!!!!

A6:方法一将一些变量定义成no init类型

方法二修改IAR的cstartup.s43程序,具体方法如下:(iar310a为例)

1将cstartup.s43程序加载到用户自己的项目中,cstartup.s43在iar310a的路径如下$TOOLKIT_DIR$\src\LIB\ 2修改cstartup.s43中的__program_start子程序,加入关闭看门狗的命令MOV#0x5A80,&0x0120

3在Project->Options->Linker->Config页中选择Override default programe,并将Entry lib设置成__program_start

A7:打开IAR编译器后就可以直接打开了;另外,记事本也可以打开

Q8:怎么设置才能使2274内部dco产生稳定的16M的时钟信号,还有就是2274是不是提供FLL+功能!A8:2XXX没有FLL+,但是TI在出厂芯片的时候已经做过出厂测试,你只要选择它头文件里的那个16M即可

Q9:程序编译时提示:Warning[Pe001]:last line of file ends without a newline,这是怎么回事啊,应该怎么改呢?

A9:敲个回车就可以了

Q10:过去用435/436等因为仿真的几要线和端口都没有复用.所以很轻松就搞定.现在1232的仿真口和P1口是公用的,仿真时我把第一脚TEST接VCC,这样可以下载仿真了,可是发现这复用的几个P1口就不能执行其正确的动作了,请教

A10:做仿真口的复用管脚在仿真时,被作为仿真功能管脚使。

Q11:USB仿真器下载汇编程序时没有问题,但是下载C语言程序时,出报警信息

如下:

The stack plug-in failed to set a breakpoint on"main".The stack window will not be able to display stack contents. (You can change this setting in the Tools>Options dialog box.

在调试信息窗口出现operation error.

A11:调试c程序时

在Tools>Options dialog box中stack要选中指向main函数处。

汇编和c要建不同的工程下调试。

Q12:装了MSP-FET430UIF仿真器,但是在AQ430的Options中,无法找到该仿真器,正常应该有LPT1/LPT2/LPT3/TIUSB四个选项,为什么看不到TIUSB?

A12:先看看硬件管理器中有没有那个硬件,有则先用IAR试试.

Q13:EZ430-RF2500中的USB debugging可以调试msp430其他支持Spy-Bi-Wire系列的芯片吗?

A13:可以。

Q14:用TI的USB仿真器,采用的是二线法。用SD_16采集数据,发现连接仿真器输出的数据正确,而把仿真器拔去,输出的数据就错了。这是为什么?

A14:怎么理解这个数据正确和错误?你怎么下的判断?我认为是你接仿真器的时候目标板是从仿真器上取电的,拔掉仿真器是外部电源供电的,电源电压不同,将导致基准源改变,采样出来的值变化会很大。

Q15:sd-fet430uif仿真器不能外供电吗?

A15:可以,驱动电流较小,内部是光MOS管,要注意负载

Q16:430FET下载出现问题时检查的一般思路

A16:在完全确定无虚焊、短路的情况下,一般注意以下事项:

2、复位脚的RC电路

3、是否是SBW模式

4、JTAG复用引脚时注意外部电路的影响

5、外部有功率较大的器件,当下载时造成外部电路的功耗较大

6、JTAG线不能太长,一般在20CM以内比较合适

7、如果是USB的仿真器还要注意USB线不能太长,使用笔记本的还要注意USB上不能连接太多的负载

Q17:LSD-FET430UIF仿真器,运用IAR410软件,器件是F1121A,无法下载程序也无法仿真,直接将接口线换在原来的FETP430IF上,把FET设置换成并口后就可以,请问下,是什么原因造成的?

A17:检查一下驱动安装对吧,另外再检查下USB提供的电源和USB线的信号,USB提供电源不足或USB 线的信号受到了比较强的干扰都会影响下载。

Q18:430加密用的密码是中断向量的简单组合呢?还是中断向量的加密组合?还是用的中断服务程序入口地址的简单组合?还是用的中断服务程序入口地址的加密组合?

A18:是入口地址的组合(存放在中断向量处的数据),以前是简单组合,新的5XX就有些复杂了,用户自己还可以定义密码。

Q19:我的程序编译后,DEBUG调试显示已成功DOWN到芯片里了,连着EZ430仿真器也能工作,但只要把EZ430脱开,PCB重新上电,芯片怎么也不工作.不知是什么原因?

A19:2013的RST脚接1个上拉电阻就解决问题了。

Q20:通过标准的BSL方式是不需要编写单片机程序的?如果是的话,那自定义串口下载的优点和缺点又是什么?

A20:用BSL不需要自己编写单片机程序,但需要另加入两根或4根编程线。自己写升级程序直接使用串口,但需要自己写自编程程序,此方式使用方便,还可以在线大批量升级,缺点是要占用FLASH空间,如果通讯协议严谨,再加上密码保护之类的算法,消耗2K的FLASH资源还是比较正常的,所以小FLASH容量的就不推荐使用了。

Q21:在编译程序时,总是出现这样的错误信息,该怎么样解决呀?

Error[e46]:Undefined external"main"referred in?cstart(D:\Program Files\iar\430\LIB\CLIB\cl430f.r43)

程序没有错误,是不是编译器本身有什么问题?

A21:是汇编程序时,把OPTIONS里的ASSEM××ER ONLY……选上。

Q22:UIF连接不到F2274,RST信号的电容已去掉,用并口能连接上,不稳定,这是为什么?

A22:F22X4支持两种JTAG接口,如果是UIF的话,个人建议使用SBW的,如果用4线制的话,会占用数个复用端口,你说连不上是不是就是因为复用端口上连有外围设备造成JTAG无法正常工作了呢。检查一下。

Q23:故障现象:有时windows能识别,多数不能识别;提示“未知usb设备”;挑机器-换台机器可能好使;升级失败;这是什么原因?

A23:1.使用IAR自动更新功能,只能通过JTAG口重新写入f1612程序。

2.EZ430板上TUSB3410的复位脚C9电容小,增加到2uF。最好增加旁路滤波电容,以提高电源质量。

Q24:使用430内置的info flash来存放一些配置信息。在用fet硬件仿真的时候,希望直接手动修改memory 窗口中的的info flash的内容,但是老是弹出窗口说这些地址是不可访问等提示,请问有什么办法可以在硬件仿真的时候,直接修改info中的内容么?

A24:flash不能直接修改。这个得用编程器,仿真器或者软件编程修改FLASH,你这样就能修改FLASH那也太……嘿嘿……

Q25:IAR如何查看生成的代码的大小?

A25:编译后在信息窗口就是就可以提示,如果没有提示,请在Tool/Options/Meassages/show build message:选为All就行了。

Q26:程序下不进去,用的仿真器是一头并口,一头14脚的jtag,烧的时候总说找不到设备?

A26:RST连上,去掉上面的电容。

Q27:给MSP430F149仿真的JTAG能给MSP430F2002仿真吗?

我把腿都对应上了,但程序下不进去,说是找不到器件................

以前用同样的方法成功的给449仿真过!!!难道2002用的是不同的JTAG

A27:并口仿真器支持2002,不过只能使用四线JTAG方式,RST引脚必须连接,而且不要有复位电容。

Q28:430如何将程序成功烧入?1.烧片子的具体的顺序?

A28:首先option里得选择正确的芯片型号,还要在Debugger选项卡里的driver选择FET_Debugger,在按工具栏内的下载按钮(快捷键ctrl+D)

Q29:MSP430F22X学习板SBW用访真器不能进行调试?

A29:原因可能两点

两线制是不能用并口访真器进行调试的,必须USB访真器

两线制RST并联的电容建议不接,否则造成程序无法正常下载

Q30:在研制带处理器的电子产品时,如何提高抗干扰能力和电磁兼容性?

A30:一、下面的一些系统要特别注意抗电磁干扰:

1、微控制器时钟频率特别高,总线周期特别快的系统。

2、系统含有大功率,大电流驱动电路,如产生火花的继电器,大电流开关等。

3、含微弱模拟信号电路以及高精度A/D变换电路的系统。

二、为增加系统的抗电磁干扰能力采取如下措施:

1、选用频率低的微控制器:

选用外时钟频率低的微控制器可以有效降低噪声和提高系统的抗干扰能力。同样频率的方波和正弦波,方波中的高频成份比正弦波多得多。虽然方波的高频成份的波的幅度,比基波小,但频率越高越容易发射出成为噪声源,微控制器产生的最有影响的高频噪声大约是时钟频率的3倍。

2、减小信号传输中的畸变

a、微控制器主要采用高速CMOS技术制造。信号输入端静态输入电流在1mA左右,输入电容10PF左右,输入阻抗相当高,高速CMOS电路的输出端都有相当的带载能力,即相当大的输出值,将一个门的输出端通

>Tr时,就成了一个传输线问题,必须考虑信号反射,阻抗匹配等问题。

b、信号在印制板上的延迟时间与引线的特性阻抗有关,即与印制线路板材料的介电常数有关。可以粗略地认为,信号在印制板引线的传输速度,约为光速的1/3到1/2之间。微控制器构成的系统中常用逻辑电话元件的Tr(标准延迟时间)为3到×××s之间。

c、在印制线路板上,信号通过一个7W的电阻和一段25cm长的引线,线上延迟时间大致在4~20ns之间。也就是说,信号在印刷线路上的引线越短越好,最长不宜超过25cm。而且过孔数目也应尽量少,最好不多于2个。

d、当信号的上升时间快于信号延迟时间,就要按照快电子学处理。此时要考虑传输线的阻抗匹配,对于一块印刷线路板上的集成块之间的信号传输,要避免出现Td>Trd的情况,印刷线路板越大系统的速度就越不能太快。

e、用以下结论归纳印刷线路板设计的一个规则:

f、信号在印刷板上传输,其延迟时间不应大于所用器件的标称延迟时间。

3、减小信号线间的交叉干扰:

a、A点一个上升时间为Tr的阶跃信号通过引线AB传向B端。信号在AB线上的延迟时间是Td。在D点,由于A点信号的向前传输,到达B点后的信号反射和AB线的延迟,Td时间以后会感应出一个宽度为Tr的页脉冲信号。在C点,由于AB上信号的传输与反射,会感应出一个宽度为信号在AB线上的延迟时间的两倍,即2Td的正脉冲信号。这就是信号间的交叉干扰。干扰信号的强度与C点信号的di/at有关,与线间距离有关。当两信号线不是很长时,AB上看到的实际是两个脉冲的迭加。

b、CMOS工艺制造的微控制由输入阻抗高,噪声高,噪声容限也很高,数字电路是迭加100~200mv噪声并不影响其工作。若图中AB线是一模拟信号,这种干扰就变为不能容忍。如印刷线路板为四层板,其中有一层是大面积的地,或双面板,信号线的反面是大面积的地时,这种信号间的交叉干扰就会变小。原因是,大面积的地减小了信号线的特性阻抗,信号在D端的反射大为减小。特性阻抗与信号线到地间的介质的介电常数的平方成反比,与介质厚度的自然对数成正比。若AB线为一模拟信号,要避免数字电路信号线CD对AB 的干扰,AB线下方要有大面积的地,AB线到CD线的距离要大于AB线与地距离的2~3倍。可用局部屏蔽地,在有引结的一面引线左右两侧布以地线。

4、减小来自电源的噪声

电源在向系统提供能源的同时,也将其噪声加到所供电的电源上。电路中微控制器的复位线,中断线,以及其它一些控制线最容易受外界噪声的干扰。电网上的强干扰通过电源进入电路,即使电池供电的系统,电池本身也有高频噪声。模拟电路中的模拟信号更经受不住来自电源的干扰。

5、注意印刷线板与元器件的高频特性

a、在高频情况下,印刷线路板上的引线,过孔,电阻、电容、接插件的分布电感与电容等不可忽略。电容的分布电感不可忽略,电感的分布电容不可忽略。电阻产生对高频信号的反射,引线的分布电容会起作用,当长度大于噪声频率相应波长的1/20时,就产生天线效应,噪声通过引线向外发射。

b、印刷线路板的过孔大约引起0.6pf的电容。

c、一个集成电路本身的封装材料引入2~6pf电容。

d、一个线路板上的接插件,有520nH的分布电感。一个双列直扦的24引脚集成电路扦座,引入4~×××H 的分布电感。

e、这些小的分布参数对于这行较低频率下的微控制器系统中是可以忽略不计的;而对于高速系统必须予以特别注意。

6、元件布置要合理分区

元件在印刷线路板上排列的位置要充分考虑抗电磁干扰问题,原则之一是各部件之间的引线要尽量短。在布局上,要把模拟信号部分,高速数字电路部分,噪声源部分(如继电器,大电流开关等)这三部分合理地分开,使相互间的信号耦合为最小。

7、处理好接地线

a 、印刷电路板上,电源线和地线最重要。克服电磁干扰,最主要的手段就是接地。

b 、对于双面板,地线布置特别讲究,通过采用单点接地法,电源和地是从电源的两端接到印刷线路板上来的,电源一个接点,地一个接点。印刷线路板上,要有多个返回地线,这些都会聚到回电源的那个接点上,就是所谓单点接地。所谓模拟地、数字地、大功率器件地开分,是指布线分开,而最后都汇集到这个接地点上来。与印刷线路板以外的信号相连时,通常采用屏蔽电缆。对于高频和数字信号,屏蔽电缆两端都接地。低频模拟信号用的屏蔽电缆,一端接地为好。

c 、对噪声和干扰非常敏感的电路或高频噪声特别严重的电路应该用金属罩屏蔽起来。

8、用好去耦电容。

a 、好的高频去耦电容可以去除高到1GHZ 的高频成份。陶瓷片电容或多层陶瓷电容的高频特性较好。设计印刷线路板时,每个集成电路的电源,地之间都要加一个去耦电容。去耦电容有两个作用:一方面是本集成电路的蓄能电容,提供和吸收该集成电路开门关门瞬间的充放电能;另一方面旁路掉该器件的高频噪声。数字电路中典型的去耦电容为0.1uf 的去耦电容有5nH 分布电感,它的并行共振频率大约在7MHz 左右,也就是说对于10MHz 以下的噪声有较好的去耦作用,对40MHz 以上的噪声几乎不起作用。

b 、1uf ,10uf 电容,并行共振频率在20MHz 以上,去除高频率噪声的效果要好一些。在电源进入印刷板的地方和一个1uf 或10uf 的去高频电容往往是有利的,即使是用电池供电的系统也需要这种电容。

c 、每10片左右的集成电路要加一片充放电电容,或称为蓄放电容,电容大小可选10uf 。最好不用电解电容,电解电容是两层溥膜卷起来的,这种卷起来的结构在高频时表现为电感,最好使用胆电容或聚碳酸酝电容。

d 、去耦电容值的选取并不严格,可按C=1/f 计算;即10MHz 取0.1uf ,对微控制器构成的系统,取0.1~0.01uf 之间都可以。

三、降低噪声与电磁干扰的一些经验。1、能用低速芯片就不用高速的,高速芯片用在关键地方。

2、用串一个电阻的办法,降低控制电路上下沿跳变速率。

3、尽量为继电器等提供某种形式的阻尼。

4、使用满足系统要求的最低频率时钟。

5、时钟产生器尽量靠近到用该时钟的器件。石英晶体振荡器外壳要接地。

6、用地线将时钟区圈起来,时钟线尽量短。

7、I/O 驱动电路尽量靠近印刷板边,让其尽快离开印刷板。对进入印制板的信号要加滤波,从高噪声区来的信号也要加滤波,同时用串终端电阻的办法,减小信号反射。

8、MCD 无用端要接高,或接地,或定义成输出端,集成电路上该接电源地的端都要接,不要悬空。

9、闲置不用的门电路输入端不要悬空,闲置不用的运放正输入端接地,负输入端接输出端。(10)印制板尽量使用45折线而不用90折线布线以减小高频信号对外的发射与耦合。

10、印制板按频率和电流开关特性分区,噪声元件与非噪声元件要距离再远一些

源,地的容生电感。

12、时钟、总线、片选信号要远离I/O线和接插件。

模拟电压输入线、参考电压端要尽量远离数字电路信号线,特别是时钟。

13、对A/D类器件,数字部分与模拟部分宁可统一下也不要交叉。

14、时钟线垂直于I/O线比平行I/O线干扰小,时钟元件引脚远离I/O电缆。

15、元件引脚尽量短,去耦电容引脚尽量短。

16、关键的线要尽量粗,并在两边加上保护地。高速线要短要直。

17、对噪声敏感的线不要与大电流,高速开关线平行。

18、石英晶体下面以及对噪声敏感的器件下面不要走线。

19、弱信号电路,低频电路周围不要形成电流环路。

20、任何信号都不要形成环路,如不可避免,让环路区尽量小。

21、每个集成电路一个去耦电容。每个电解电容边上都要加一个小的高频旁路电容。

22、用大容量的钽电容或聚酷电容而不用电解电容作电路充放电储能电容。使用管状电容时,外壳要接地

Q31:有关仿真器及编程器的问题:

A31:对于51系统来说,很容易理解编程器与仿真器的区别。

通俗的说,仿真器是用来仿真调试的,编程器是用来批量生产时对MCU进行烧写目标代码的。

对于MSP430来说,无论仿真还是烧写程序一般可以通过:JTAG/SBW/BSL接口进行,这些概念仅是接口,并不代表哪个型号的编程器和仿真器,一般JTAG/SBW接口用于仿真接口,BSL不能用于仿真,只能用于编程。编程器则三种接口都支持。所以并不能说JTAG只支持仿真,不支持编程,这是概念错误,JTAG仅仅是一种接口协议而已。

下面简单描述一下三种接口的区别:

1、JTAG是边界扫描技术,其在430内部有逻辑接口给JTAG使用,内部有若干个寄存器连接到430内部的总线上,所以JTAG可以访问到430的内部所有资源,包括对FLASH的读写操作。可以用于编程和仿真接口。主要连接线有TMS/TCK/TDI/TDO/RST/TEST等。

2、SBW是SPY-BI-WIRE的简称。通常称为两线制JTAG,主要用SBWTCK与SBWTDIO,该接口主要用于小于28脚的430单片机及5系列的单片机。因为28脚以内的单片机JTAG接口与通用IO口复用,为了给用户预留更多的IO,才推出SBW接口。同样SBW接口可以用于仿真器与编程器。

3、BSL是TI在MSP430出厂时预先固化到MCU内部的一段代码,有点类似与DSP的bootloader,但与bootloader有明显的区别,BSL只能用于对MCU内部的FLASH访问,不能对访问其他资源。所以只能用作编程器接口。BSL通过UART协议与编程器连接通信。编程器可以发送不同的通信命令来对MCU的存储器做不同的操作。BLS的启动有些特殊,一般430复位启动时PC指针指向FFFE复位向量,但可以通过特殊的启动方式可以使PC指向BSL内部固化的程序。启动方式一般由RST与TEST(或TCK)引脚做一个稍复杂的启动逻辑后产生。

4、一般的MCU都有加密功能,430如何实现加密的呢?外部对430内部的代码读写只能通过上述的三种方式,所以引入熔丝位,熔丝位只存在与JTAG/SBW接口逻辑内。BSL没有熔丝。当熔丝烧断时(物理破坏,且不可恢复)JTAG/SBW的访问将被禁止,此时只有BSL可以访问。而通过BSL对MCU的访问是需要32字节的密码,密码就是用户代码的中断向量表。

5、一般的仿真器型号有:UIF(USB接口,支持JTAG/SBW)、PIF(并口,只支持JTAG)、EZ430(USB接口,只支持SBW模式)。专业的编程器有GANG430(串口,一拖8个目标板,支持JTAG/SBW及烧断熔丝功能);多功能编程器(JTAG/SBW/BSL及烧断熔丝功能)。这些编程器都可以支持离线烧写,即脱离计算机来对目标板烧写。当然也可以通过特殊的软件用仿真器来烧写,这类软件有MSPFET、FET-PRO430等。

Q32:最近调试程序,不知怎么老出现下面的问题,请问是怎么回事?”erase check error at address0x1100

retry erase operation?"

知道是怎么回事?

A32:最可能的就是芯片电压太低,或者芯片有虚焊的。

Q33:请问MSP430F149程序下载时的电源要提供的电流为多大?

A33:这个电流主要用于flash的擦写。擦和写的典型电流都是3mA。

第二章:指令系统

Q1.IAR中怎样描述P2OUT.3脚,#define LCD_cs1P2OUT.3;对吗?

A1:430不能位寻址,所以一般的位操作,都通过“与”来作用。#define LCD_cs1(P2OUT&BIT3)。

Q2.__intrinsic是什么意思

A2:本征函数,不是C语言标准库,而是和MSP430汇编直接对应的函数,比如:

_NOP()

_EINT()

LPM0

引用msp430xxxx.h,默认引用的头文件

Q3:430中使用C和汇编语言的区别,优缺点比较?

A3:严格来讲430的C是ANSI C的一个子集,与汇编的差别主要有:

1、C有if、(do)while、switch等流程控制语句

2、C有有限的数据格式,如char、int、float、dou××e等

3、对430最有特色的R0--R15的使用,C不如汇编

4、430的C不易进行RAM管理

5、430各版本的C,互相之间存在差异,好象C在430上还不成熟

6、C的优点是在PC或PDA上,也就是在有操作系统的平台上,C的优点才会表现出来,但那已经不是430的C了,而是C++,它有丰富的数据类型,如结构、对象等

7、汇编的缺点,基本上就是C的优点,而汇编的优点基本上都是C的缺点

8、C函数有类型限定的形参和返回值以及强制类型转换,还有格式化输出,发挥C的这些特长,再结合结构化程序设计技术,容易编出思路清晰、结构灵活、可移值性比较强的程序。汇编也可以满足上述要求,但相对来讲要复杂些。

9、初学者建议先用汇编,由于对硬件的操作更加直观灵活,有利于对430内部结构的熟悉和熟悉编程思路。等掌握了30的开发技能,又熟悉了系统的合理分配资源和组织资源时再学习用c,那将使你进步最快的时候,因为c对程序的结构和调度真得很理想!

10、源代码隐藏性比较好,比较安全。

Q4:MSP430指令系统中,符号寻址方式有点不太理解。例如连续的两条指令是:

MOV.B#20H,0012H

MOV.B#34H,0200H

在反汇编窗口看这两条指令是:

mov.b#0x20,0x1112

mov.b#0x34,0x1300

不理解的是:

1.为什么反汇编后指令的第二个操作数地址变成了0x1112和0x1300?

2.上述反汇编指令似乎都在原有的地址基础上加上了0x1100,我知道保存程序的FLASH是从0x1100开始的。但实际在执行上述两条指令时,PC的值早就>0x1100.符号寻址操作数地址应该=(PC+0012H)、(PC+0200H)。而PC值在执行指令中应该是变化的?

A4:0012H和0200H是绝对地址。问题中程序用的是立即寻址,实际上应该用绝对寻址

那么地址就应该=PC addrress+0200(偏移量)。反编译出来的代码应该是

mov.b#0x20,&0x1112

mov.b#0x34,&0x1300

才对。

Q5:在程序里循环调用了sprintf函数,当循环了几次后程序就跑飞了,是堆栈大小不够吗?还有sprintf到底需要多大的堆栈,单步走了下,发现它使用堆栈都不是连续的?

A5:有可能是的sprintf函数堆栈数据把跳转地址挤掉,可以调开堆栈看一下。

Q6:问MSP430MOV命令

立即数寻址

MOV@PC+,X(PC);

偏移量可变址寻址

MOV X(PC),Y(PC);

怎么理解?

A6:MOV@PC+,X(PC);

将PC所指单元的内容送给PC+X所在单元,然后PC本身加1,指向相邻的下一单元.

MOV X(PC),Y(PC);

将PC+X所指单元的内容送给PC+Y所在单元

问题7:数据类型Small,Medium,Large的区别,以及怎么访问大于0X10000的地址空间?

数据放在大于0X10000的地址空间中,怎么去访问?同时Small,Medium,Large在何处可以体现它们的区别?A7:可以访问。值得注意的是option里的General Option选项内的数据类型得选择Large,程序大小,RAM 使用,运行速度都不一样。

1.F5XX430X

2.选择Large small medium产生效果是改变指针变量所占字节个数.IAR中指针变量默认2个字节,选择large 占用4个字节,那么指针就可以访问超过64K范围的地址.

3.可以采用IAR内部函数,*/

void__data20_write_char(unsigned long__addr,

unsigned char__value);

void__data20_write_short(unsigned long__addr,

unsigned short__value);

void__data20_write_long(unsigned long__addr,

unsigned long__value);

unsigned char__data20_read_char(unsigned long__addr);

unsigned long__data20_read_long(unsigned long__addr);

Q8:关于堆栈问题

问题:Error[e16]:Segment CSTACK(size:0x50align:0x1)is too long for segment definition.At least0x4more bytes needed.The pro××em occurred while processing the

××aila××e memory ranges were"CODE:5B4-600"

请问:这个错误是什么意思

A8:将stack设置减小,可通过编译,这时stack是静态的.

而会不会出错不是stack设置问题,而是在程序运行时,动态中,RAM占用量大小所定.

减少程序中的变量个数,变量类型尽量小,够用就可以,能减少动态运行时RAM的占用量.

Q9:浮点数运算问题,既然2.2A编译器能实现64浮点位运算,那么它的运算程序在哪个文档里。

A9:要使用64位的浮点运算需要设置编译器

首先选择project->option->general->target->dou××e floating point size

选中"64"

再选择project->option->XLINK->include->library->cl430d.r43

用c++的朋友要选择dl430d.r43库

建议用整型数进行运算,比如像开方,64位浮点数要用几十毫秒,而整型数随数据大小只要几微秒到几毫秒不等。

Q10:局部变量的问题,在中断服务程序中开中断响应其他中断,发现中断服务中定义的局部变量老被改动,换成全局变量没问题。想问一下这是啥原因?还想问一下c编程过程中应注意的细节?

A10:局部变量只是暂存变量,一般编译器会使用通用寄存器来保存这个变量值,汇编编程的话需要圧栈操作,C语言编程的话建议把变量申明为全局或者静态。

第三章:代码编程类

Q1:我在一个子程序中定义了一个变量,是在其头文件中定义的,然后在主程序中包含了此头文件,当在主程序中引用此变量时,编译器没有报错,但是要DEBUG时出错了,告诉我是redefine in main,请问这是怎么回事呢?

A1:肯定不能这样用了,相当于重复定义了.用外部变量声明可以解决这个问题.你可以在头文件中申明(加extern),在C文件中定义。

Q2:这是我的接收函数,但是当我发送ko时,收到两个o,发送ok时收到两个k,这是怎么回事呢。

#pragma vector=UART1RX_VECTOR

__interrupt void usart1_rx(void)

{

unsigned j;

//IFG2&=~URXIFG1;

for(j=0;j<2;)

{

data[j]=RXBUF1;

j++;

}

if(j==2)

{

TX_Flag=1;

}

A2:程序错了!!按你的程序,收到第一个字符K时,你将该字符填入数组,即数组内容为{K,K};收到第二个字符O时,你将该字符填入数组,即数组内容为{O,O},应该加一个判断,判断接收缓存里面的数据被存了,再存第二个。

Q3:问题:想要根据一个数据send,利用TA0产生中断,控制P2口产生3ms、1ms、3ms、1ms、3ms、1ms......的一组方波(‘1’发送3ms,‘0’发送1ms),但程序写出来后,发现执行过程非常不稳定,忽快忽慢。不知道是单片机的问题还是程序的问题,请专家帮帮!

附程序:

void data_send(unsigned char send)

{

unsigned char i;

for(i=0;i<8;i++)//发送8位

{

if(send&0x01)//如果最低位为1,发送3ms

{

CCR0=189;//3ms定时

CCTL0=CCIE;//打开中断

P2OUT|=BIT3;//P2口变高电平

flag=0;//flag清零,以便下一位的中断

P2OUT&=~BIT3;//P2口变低

}

else//当最低位为0时中断1ms

{

CCR0=63;

CCTL0=CCIE;

P2OUT|=BIT3;

while(flag==0);

flag=0;

P2OUT&=~send_BIT;

}

send=(send>>1);//左移一位

}

#pragma vector=TIMERA0_VECTOR//TA中断

__interrupt void TA_start(void)

{

flag=1;//中断时间到,设置标志位

}

TA0的时钟选用0.5M8分频,近似计数值63为1ms,使用连续计数方式。A3:void data_send(unsigned char send)

{

unsigned char i;

for(i=0;i<8;i++)//发送8位

{

if(send&0x01)//如果最低位为1,发送3ms

{

CCR0=189;//3ms定时

CCTL0=CCIE;//打开中断

P2OUT|=BIT3;//P2口变高电平

while(flag==0);//等待中断处理子程序返回标志位flag=1

flag=0;//flag清零,以便下一位的中断

P2OUT&=~BIT3;//P2口变低

}

else//当最低位为0时中断1ms

{

CCR0=63;

CCTL0=CCIE;

P2OUT|=BIT3;

while(flag==0);

flag=0;

P2OUT&=~BIT3;

}

send=(send>>1);//左移一位

}

#pragma vector=TIMERA0_VECTOR//TA中断

__interrupt void TA_start(void)

{

flag=1;//中断时间到,设置标志位

}

TACTL中的MC1、MC0为01值

Q4:求msp43的pwm捕捉下降沿的程序。

A4:TACCTL2=CM1+CCIS_1+CAP;//同步捕获模式,下降沿捕获

TACTL=TASSEL_2+MC_2+TACLR;//连续计数方式,时钟设置为SMCLK

I/O口也需要设置为第二功能口,建议看users guide和TI例程。

Q5:C文件LINKER后,报错Error[e46]:Udefined external"send1_buff"referred in sys_evet(D:\sc1\Debug\Obj\sys_evet.r43,请教如何可解决此问题,变量send1_buff在文件里已定义了extern。

A5:查看一下你的程序编译时先编译哪个文件,或在这个文件前先申明一下。

Q6::DINT

MOV.W#FWKEY+WRT,&FCTL1;Write bit=1

MOV.W#FWKEY+FSSEL0+FN0+FN1,&FCTL2

MOV.W#FWKEY,&FCTL3

TEST BIT#BUSY,&FCTL3

JNZ TEST

MOV.W R14,0(R12)

TEST1BIT#BUSY,&FCTL3

JNZ TEST1

MOV.W#FWKEY,&FCTL1

MOV.W#FWKEY+LOCK,&FCTL3;Lock=1

EINT

RET

想保存信息,R12是地址,1080,R14是内容,但是通过按键改变参数后,INFO写入的确实0,而不是要保存的数据。很奇怪。为什么不管什么数据,到INFO里都是0?

A6:原因在于你只改变单个字,而FLASH是要整段擦除,然后在更改。MOV.W#FWKEY+FSSEL0+FN0+FN1,&FCTL2 ,flash擦写时钟也是很重要的,经分频后时钟应该在257-476KHz的频率范围,偏离值太大,容易引起擦写的失败。

Q7::为什么485程序只能单字节传输呢?单片机经过232/485转换器接到电脑,用串口精灵调试的。大家看看有什么问题啊?

#include

void main(void)

{WDTCTL=WDTPW+WDTHOLD;

UCTL0&=~SWRST;

UCTL0|=CHAR;

UBR00=0X03;

UBR10=0X00;

UMCTL0=0X4A;

UTCTL0|=SSEL0;

ME1|=UTXE0+URXE0;

IE1|=URXIE0;

P3SEL|=0X30;

P3DIR|=0x70;

P3OUT&=~BIT6;

_BIS_SR(LPM3_bits+GIE);//Enter LPM3w/interrupt

}

#pragma vector=UART0RX_VECTOR

__interrupt void usart0_rx(void)

{

int i;

P3OUT|=BIT6;

while(!(IFG1&UTXIFG0));//USART1TX buffer ready?

TXBUF0=RXBUF0;//RXBUF1to TXBUF1

for(i=0;i<10000;i++){_NOP();}

P3OUT&=~BIT6;

}

A7:程序问题:

1发送第一个字节时候,中断服务程序中485使能端口操作(P3OUT|=BIT6与P3OUT&=~BIT6)之间的时间太长,导致这段时间的调试精灵发出的字节都丢失了。

2一般可以先将所有的数据接受完成之后(即放到缓冲区后),在开始切换485端口发送数据,最后确保所有数据发送完成后在切换成接受方向主动发送,中断接收,在串口接收中断中不要做太多事情,只压接收到的字节数据。

Q8:初学430,发现汇编语言中没有除法指令,请问版主和各位高手,能否提供一个32位/16位的除法汇编程序,谢谢。

A8:32位除以16位的自己改:

;ACCAx:除数,ACCBx:商,ACCCx:余数,ACCDx:被除数

;---------------------------------------------------------

Div48_32MOV.B#030H,TEMP

CLR.W ACClierdalierda;ACCBx:商

CLR.W ACCBM

CLR.W ACCBH

D_DIVS CLR.W;ACCCx:余数

CLR.W ACCCH

DIV_LOOP CLRC

RLC.W ACCDL;ACCDx:被除数

RLC.W ACCDM

RLC.W ACCDH

RLC.W ACCCL

RLC.W ACCCH

MOV.W ACCCH,R15

SUB.W ACCAH,R15

JNZ NOCHK

MOV.W ACCCL,R15

SUB.W ACCAL,R15

NOCHK JNC NOGO

NOCHK1SUB.W ACCAL,ACCCL

JC NOCHK2

DEC.W ACCCH

NOCHK2SUB.W ACCAH,ACCCH

SETC

NOGO RLC.W ACClierdalierda

RLC.W ACCBM

RLC.W ACCBH

DEC.B TEMP

JNZ DIV_LOOP

RET

Q9:在TI的例子程序中有

TACCTL1=CCIS0+OUTMOD0+CCIE;

TACCTL1|=OUTMOD2;

怎么理解。

A9:TACCTL1=CCIS0+OUTMOD0;是写整个寄存器;

执行后,寄存器TACCTL1的值=0x1000+0x2000=0x3000;

而TACCTL1|=OUTMOD2;只是把寄存器中的相关位置1,剩余的位保持不变;

执行后,寄存器TACCTL1的BIT7(0x0080)改写为1.

Q10:在程序中作循环,执行时间比较长。若循环次数少,则改变的数组中个数少;若多加,两次循环改变的个数就多。

A10:可能是堆栽溢出了!

Q11:想让menu_b定义在ROM区

unsigned int const menu_a[][3]={1,2,3};

unsigned int const menu_b[1]={&menu_a[0][0]};

IAR编译器为何编译不了?但这样就行,但是menu_b是定义在RAM区的

unsigned int const menu_a[][3]={1,2,3};

unsigned int const*menu_b[1]={&menu_a[0][0]};

A11:unsigned int const*menu_b[1]={&menu_a[0][0]};“unsigned int const*”表示指向const型(ROM型)unsigned int变量的指针,且由于前面没有再加一个const(如const unsigned int const*xxx),故按默认定义在RAM中。这是标准C的语法。!

Q12:最近才开始学MSP430,看利尔达公司的一个汇编实验程序时,发现很多类似这样的指令,mov.w #SHT0_2+ADC12ON,&ADC12CTL0这条指令是不是立即数寻址啊?如果是的话,#号后面不是直接加一个立即数

寄存器里面的一位或几位。这条指令是什么意思啊?

A12:SHT0_2,ADC12ON已经宏定义好的,其实表示一个数,这语句是对寄存器相应位置位。

Q13:用f147计算电压有效值,采样40个点,用平方和除以40再开根号,计算一次居然要10ms,有这么长时间么?我的基础时钟模块这样设的

//set basic system time

BCSCTL1|=XTS+XT2OFF;//HF model,4.096M,XT2close

BCSCTL2|=SELM_3+SELS;//MCLK、SMCLK use LFXT1CLK,都不分频

//set ADC12

ADC12CTL0|=SHT0_2+REF2_5V+REFON+ADC12ON+MSC;

//采样周期为8个ADC12CLK

//启用多次采样转换位

//2.5V参考电平,打开ADC内核

//转换时间溢出中断和溢出中断未打开

ADC12CTL1|=SHP+ADC12SSEL_1+CONSEQ_1;//使用采样定时器

//ACLK做时钟源

ADC12MCTL0|=INCH_0+SREF_1;//ref+=Vref+,channel=A0

ADC12MCTL1|=INCH_1+SREF_1+EOS;//ref+=Vref+,channel=A1

ADC12IE|=BIT1;

A13:是计算的时候出了问题,首先要求平方,在开根号,这样是算需要很多的时间!

Q14:程序运行报错:

Mon Oct1309:56:082008:Target reset

Mon Oct1309:56:342008:Breakpoint hit:Code@key.c:760.5

Mon Oct1309:56:342008:The stack'Stack'is filled to100%(80bytes used out of80).The warning threshold is set to90%.

Mon Oct1309:56:342008:The stack pointer for stack'Stack'(currently Memory:0x9A4)is outside the stack range (Memory:0x9B0to Memory:0xA00)

Mon Oct1309:56:392008:The stack'Stack'is filled to100%(80bytes used out of80).The warning threshold is set to90%.

Mon Oct1309:56:392008:The stack pointer for stack'Stack'(currently Memory:0x9A4)is outside the stack range (Memory:0x9B0to Memory:0xA00)请给与解释?

A14:可能是堆栽溢出了,修改一下STACK试试看!

Q15:The stack'Stack'is filled to100%(80bytes used out of80).The warning threshold is set to90%.,这个LED时间显示程序,是不是循环太多,还是程序太冗余,下载后出现了上述错误,该如何修改?

A15:假如真是STACK的容量问题,就说明你的程序结构有问题了。一般显示这些功能用不了几个字的堆栈。程序中尽量不要出现递归类的函数。函数的参数及返回值也不要太多,如果多了,可以用指针。

Q16:问题:编写UART的中断函数时用到语句interrupt[UART0RX_VECTOR]void UART0RX(void)

可是在编译时总是报错Error[Pe077]:this declaration has no storage class or type specifier

Error[Pe065]:expected a";"

在函数的总前面我已#include

#include

请问需要进行怎么修改?

A16:是IAR调试软件的问题,

在IAR1.26版和以下都是interrupt[UART0RX_VECTOR]void UART0RX(void)的写法,以上都是#pragma vector=TIMERB0_VECTOR

__interrupt void Timer_B(void)的写法。

Q17:P1DIR=0x10;

P1SEL=0x10;//p1.4为SMCLK

P2DIR=0x01;

P2SEL=0x01;//P2.0为ACLK

P5DIR=0x10;

P5SEL=0x10;//p5.4为MCLK

在设置好了时钟后,是不是能通过上面的语句在p1.4,p2.0,p5.4口用示波器看到时钟信号呢?但为什么没有看到?而用示波器观察晶振是起振的。

A17:程序没有死循环,跑到最后就复位了。原来的程序上加了语句:while(1);后当程序跑到这个空循环时,再用示波器测各个引脚时,就有aclk,mclk,sclk。

Q18:运用定时器A做定时,程序思想正确却无法执行,在tt==20的地方无法执行

该怎么办?

#include

#define uint unsigned int

#define uchar unsigned char

uchar num,tt;

uchar ta××e[]={

0xc0,0xfc,0x24,0x4f,

0x66,0x6d,0x7d,0x07,

0x7f,0x6f,0x77,0x7c,

0x39,0x5e,0x79,0x71};

void delay(uint z);

void main(void)

{

//WDTCTL=WDTPW+WDTHOLD;//Stop watchdog timer

WDTCTL=WDTPW+WDTHOLD;//Stop WDT

TACTL=TASSEL1+TACLR;//SMCLK,QINGCHU TAR

CCTL0=CCIE;//CCR0interrupt ena××ed

CCR0=40000;

TACTL|=MC0;

//

P1DIR=0;

P2DIR=0;

//

相关主题