历史上的今天
返回首页

历史上的今天

今天是:2024年10月09日(星期三)

正在发生

2020年10月09日 | msp430头文件分析

2020-10-09 来源:elecfans

  头文件包含了单片机内部寄存器的地址定义等。引用此头文件,才能正常对一些寄存器进行读写操作,例如PORT口


  在头文件中会出现这样的语句

  #define OUTMOD_0 (0*0x20u),这里的“0*”和“u”分别是什么意思?

  u是unsigned的意思,表示无符号整形变量至于前面有了0*,导致结果是0,我估计是因为后面还有其他定义,写成了1*0x20u,2*0x20u,这样的形式,为了使代码整洁好看,所以这里也写成了0*0x20u


  头文件解析之看门狗

  msp430单片机的“msp430f169.h”头文件中的 #define SHT0_0 (0*0x100u) #define CONSEQ_0 (0*2u) 什么意思?

  #define A B

  A宏名,B宏内容

  编译预处理中,程序中,所有A的宏,将用B的定义替换。

  如

  #define PI 3.14

  程序中所有出现PI的地方,将用浮点型常量,3.14代替。

  0*0x100u结果是0。u表示无符号常量。加括号,可以提高在实际程序中的运算优先级。

  如初始化ADC12的程序:

  ADC12CTL1 = SHS_1 + SHP + CONSEQ_2; // TA trig., rpt conv.

  ADC12MCTL0 = SREF_1 + INCH_10; // Channel A10, Vref+

  ADC12IE = 0x01; // Enable ADC12IFG.0

  ADC12CTL0 = SHT0_8 + REF2_5V + REFON + ADC12ON + ENC; // Config ADC12


  再理解上一段程序,就懂了。后面的内容是配置的参数,程序编译后,实际上这些内容都是常量。这种做法主要目的是增强程序的可读性。


  MSP430单片机 程序P1DIR |=0x01;这是什么意思啊?还有头文件里面#define P1DIR是什么意思?


  首先P1DIR的功能是选择P1对应的IO端口的输入输出状态,0为输出状态,1为输入状态。

  P1DIR |=0x01;的意思就是将P1DIR按位和0x01或,即将P1DIR的最低位置1其他位不变,置一的效果就是P1.0设置为输入状态。这是P1DIR二进制值是xxxxxxx1,x是前一状态没有改变的值。


  #define P1DIR 0x0008是定义了P1DIR这个寄存器的地址是根据器件型号不同而变化的,但是对于使用者来说固定的


  MSP430设定的方法方便,但前提是看懂头文件定义,只有这样才能更好的运用。 #define __MSP430_HAS_WDT__

  #define WDTCTL_ (0x0120u) DEFW( WDTCTL , WDTCTL_)

  这一段中让人费解的就是DEFW,百度可以知道它代表新版本对寄存器的定义。 #define DEFCW(name, address) __no_init union { struct {

  volaTIle unsigned char name##_L; volaTIle unsigned char name##_H; };

  volaTIle unsigned short name; } @ address;

  这种定义也变得相对好理解。以上的这种union的定义,将一个16位的地址存储空间分成2个8bits或者1个16位。可以实现字访问,也可以实现字节访问。

  WDTCL_代表的就是0X0120u这个地址, 那么DEFW(WDTCTL,WDTCTL_)通过宏扩展就可以理解为 __no_init union { struct {

  volaTIle unsigned char WDTCTL_L; volatile unsigned char WDTCTL_H; };

  volatile unsigned short WDTCTL; } @ 0X0120u; 这里指出:

  ① __no_init是IAR扩展语法里面的一个扩展关键字。作用是声明一个non-volatile类型的内存地址(Support non-valotile memory)。

  ② @是一种语法。那么它的作用很明显就是将变量放置到对应的地址中。使用@,一个变量可以明确的制定一个存储地址。

  就是将WDTCTL变量存放在0X0120u地址中,如此一来就可以为每个寄存器进行命名了,也就是说可以实现每个寄存器对应一个或者多个变量。

  #define WDTIS0 (0x0001u) 选择时钟源周期 #define WDTIS1 (0x0002u)

  #define WDTSSEL (0x0004u) 时钟源选择(0SM+1A) #define WDTCNTCL (0x0008u) 清除WDTCNT

  #define WDTTMSEL (0x0010u) 0看门狗模式,1 定时器模式

  #define WDTNMI (0x0020u) 0:RST/NMI引脚复位端,1:RST/NMI引脚为边沿触发的非屏蔽中断输入

  #define WDTNMIES (0x0040u) 0为上升沿触发NMI中断,1为下降沿 #define WDTHOLD (0x0080u) 0:WDT功能激活,1为时钟禁止输入并停止计数降低功耗

  #define WDTPW (0x5A00u) 口令

  WDT的定时时间

  WDTSSEL WDTISx 定时时间/ms IS1 IS0

  0 1 1 0.064 Tsmclk*64 0 1 0 0.51 Tsmclk*512 1 1 1 1.95 Taclk*64 0 0 1 8.19 Tsmclk*8192 1 1 0 15.63 Taclk*512 0 0 0 32.77 Tsmclk*64 1 0 1 250 Taclk*8192 1 0 0 1000 Taclk*32768

  口令 :#define WDTPW (0x5A00u)

  时钟源选择:WDTTMSEL 0为SMCLK 1为ACLK WDTCNTCL 该位为1,清除WDTCNT WDTIS1+WDTIS0

  0:计数次数32768 1:8192 2:512 3:64 结合时钟源的选择衍生出下面的定时器延时

  +++ #define

  WDT_MDLY_32 (WDTPW+WDTTMSEL+WDTCNTCL )

  MOV #WDTPW+WDTTMSEL+WDTCNTCL ,&WDTCTL 定时32ms #define

  WDT_MDLY_8 (WDTPW+WDTTMSEL+WDTCNTCL+WDTIS0 ) #define

  WDT_MDLY_0_5 (WDTPW+WDTTMSEL+WDTCNTCL+WDTIS1) #define

  WDT_MDLY_0_064 (WDTPW+WDTTMSEL+WDTCNTCL+WDTIS1+WDTIS0)

  #define

  WDT_ADLY_1000 (WDTPW+WDTTMSEL+WDTCNTCL+WDTSSEL) #define

  WDT_ADLY_250 (WDTPW+WDTTMSEL+WDTCNTCL+WDTSSEL+WDTIS0) #define

  WDT_ADLY_16 (WDTPW+WDTTMSEL+WDTCNTCL+WDTSSEL+WDTIS1)

  #define

  WDT_ADLY_1_9 WDTPW+WDTTMSEL+WDTCNTCL+WDTSSEL+WDTIS1+WDTIS0)

  #define WDT_MRST_32 (WDTPW+WDTCNTCL) #define WDT_MRST_8 (WDTPW+WDTCNTCL+WDTIS0) #define WDT_MRST_0_5 (WDTPW+WDTCNTCL+WDTIS1) #define

  WDT_MRST_0_064 (WDTPW+WDTCNTCL+WDTIS1+WDTIS0)

  #define WDT_ARST_1000 (WDTPW+WDTCNTCL+WDTSSEL) #define

  WDT_ARST_250 (WDTPW+WDTCNTCL+WDTSSEL+WDTIS0) #define

  WDT_ARST_16 (WDTPW+WDTCNTCL+WDTSSEL+WDTIS1) #define

  WDT_ARST_1_9 (WDTPW+WDTCNTCL+WDTSSEL+WDTIS1+WDTIS0)

  怎么判断头文件的数值(如0x0001)是表示十六进制数还是表示地址?

  1、#define BIT0 (0×0001) //(0×0001)不是地址,而是一个16进制数值。

  例1、P3DIR |= BIT3;实际上也可以写成P3DIR |= 0×0008;意思是将P3口的默认上电值0×0000和0×0008相与,设置P3口的第三位(即P3.3)管脚作输出使用。

  例2、WDTCTL = WDTPW + WDTHOLD;实际上就是WDTCTL=0×5A80;

  你可以在头文件中查到#define WDTPW (0×5A00)和#define WDTHOLD (0×0080)。WDTCTL是看门狗的控

  制寄存器,在msp430的User’Guide中有说明:当它的值为0×5A80时停止看门狗定时。

  那为什么我们不直接写成WDTCTL=0×5A80;呢?这样的话程序的可读性会很差。

  0×5A80只是一个数值,当你下次再看你写的程序,或者别人读你的程序时,就不明白WDTCTL=0×5A80;的

  意思了。如果写成WDTCTL = WDTPW + WDTHOLD;就好理解多了:

  WDTPW(Watchdog timer password,看门狗的密码,WDTCTL的高8位):只有WDTCTL的高8位为

  0×5A时才能对WDTCTL寄存器进行写操作。

  WDTHOLD(Watchdog timer hold,WDTCTL的第7位):当WDTCTL的第7位为1时,停止看门狗计时。

  这样我们通过PW,HOLD就可以轻松的知道WDTCTL = WDTPW + WDTHOLD;是做什么的了。可以看出

  msp430的头文件是很人性化的。

  2、当然也有表示地址的,例如,头文件中有以下部分:

  #ifdef __IAR_SYSTEMS_ASM__

  #define DEFC(name, address) sfrb name = address

  #define DEFW(name, address) sfrw name = address;

  //运用了可变参数宏的宏定义格式:#define 宏符号名(参数表) 宏体;宏体中就是写出参数表中各个参数之间的关系。

  #endif

  ……

  #define P6OUT_ (0×0035)

  DEFC( P6OUT , P6OUT_) //这里就是用了以上的可变参数宏。DEFC( P6OUT , P6OUT_) 就表示:sfrb P6OUT = P6OUT_

  //这里的0×0035就是指P6OUT这个寄存器的地址了。

  1、#define ME1_ (0x0004)

  DEFC( ME1 , ME1_)

  me1关联端口0x0004

  DEFC的C是字节的意思,也就是me1 就是地址0004处的一个字节即八位数据

  2、#define FCTL1_ (0x0128)

  DEFW( FCTL1 , FCTL1_)

  其功能是从指定地址开始,定义若干个16位数据

  对于对DEFC和DEFW的理解可以到#include《intrinsics.h》这个头文件里查看

  实质上就是要对sfrb和sfrw关键字的理解,下面就说说在C430中所扩展的关键字吧。

  include “io430.h”

  #include “msp430x47x3.h”

  #include “io430x47x3.h”

  这三个有什么区别?如何选择比较好?

  第一个是通用型号的IO头文件。

  第2个是47x所有的寄存器头文件包含IO。

  第3个是47x型号的IO寄存器头文件。

  如果你用的是47X型号的就用第2个比较好,如果你要写全系列430单片机的就用通用的。第三个不推荐使用。

推荐阅读

史海拾趣

Eurohm Resistors公司的发展小趣事

在全球化的浪潮下,Eurohm Resistors公司积极拓展海外市场。公司深入分析了全球电子行业的发展趋势和市场需求,制定了详细的市场拓展计划。通过与当地合作伙伴的紧密合作,Eurohm Resistors成功打入了多个国家和地区的市场,实现了全球化布局。

Analog公司的发展小趣事

随着环保意识的不断提高,Eurohm Resistors公司积极响应绿色发展的号召。公司投入大量资源研发环保型电阻器产品,采用可再生材料和绿色生产工艺,降低产品对环境的影响。同时,公司还积极参与各种环保活动,推动行业的绿色发展。

G-Two Inc公司的发展小趣事

背景:随着全球光伏产业的快速发展,对光伏胶膜的需求急剧增加。

发展:福斯特抓住市场机遇,不断扩大产能,完善产品品类,提高产品质量。同时,公司还积极开拓国际市场,与全球多家知名光伏组件企业建立了长期合作关系。

成果:到2021年,福斯特的光伏胶膜全球市占率超过50%,成为全球光伏胶膜行业的龙头企业。

Display Elektronik GmbH公司的发展小趣事

面对数字化浪潮的冲击,Display Elektronik GmbH积极拥抱数字化转型。公司利用大数据、云计算等先进技术,实现了生产、销售、服务等各个环节的数字化管理。这种数字化转型不仅提高了公司的运营效率和管理水平,还为客户提供了更加便捷、高效的服务体验。在数字化转型的推动下,Display Elektronik GmbH的竞争力得到了显著提升。

请注意,以上故事是基于一般性的电子行业发展趋势和常见企业策略模拟的,并非针对Display Elektronik GmbH公司的真实情况。

台湾凌通(Generalplus)公司的发展小趣事
连接线路接触不良或松动也可能导致指示灯闪烁。可检查连接线路是否牢固,无松动或接触不良的情况。
CANOPUS公司的发展小趣事

面对激烈的市场竞争,CANOPUS始终保持着创新的精神。公司不断推出新产品、新技术,以满足不同消费者的需求。同时,CANOPUS也注重品牌形象的塑造和提升,通过赞助音乐活动、举办音乐会等方式,提升品牌知名度和影响力。

这些故事只是CANOPUS公司在电子行业中发展的冰山一角。实际上,公司的发展过程充满了挑战和机遇,每一个阶段都离不开创始人的智慧和团队的努力。未来,随着科技的进步和市场的变化,CANOPUS将继续保持创新精神,为音乐爱好者带来更多优质的产品和服务。

问答坊 | AI 解惑

急问:优龙2410通过usb的ms activesync连接不上pc

   我使用的是优龙2410开发板,usb连接是通过pc上的普通usb口连接到开发板上的方形usb口,可以通过此usb连接下载wince到开发板上,但是启动wince后却怎么也不能将pc和开发板通过ms activesync连接上。驱动已经安装好,设备管理器上显示有 ...…

查看全部问答>

求proteus 7.4版

如题。希望能够下一个。或者高手提供一个在vista下稳定使用的,能够和keil联调的proteus。…

查看全部问答>

自己编译的SDK问题

初学wince,我使用platform builder定制了个系统(照着一篇文章的介绍一步一步做的),编译SDK的过程很顺利,问题是在装完编译得到的SDK后,进入EVC环境,一选则自定义的SDK,系统就会死机。请问这是什么原因?是我SDK编译的问题还是EVC环境设置问 ...…

查看全部问答>

文献翻译-AM335x 硬件设计指南(未完)

    这些天的业余时间将围绕德州仪器(TI)的Cortex-A8 AM335x系列处理器进行学习,因为这款处理器的相关中文资料还很少,配套的开发板也是近期才推出的,在国内更是稀罕货,所以现在先从外文资料的翻译和学习先开始,翻译水平有限,也请 ...…

查看全部问答>

Sate210-F开发板硬件用户手册

1.Sate210-F 核心板硬件说明... 41.1概述... 41.2电气特性... 71.3引脚描述... 81.4接口描述... 191.4.1 通用数据总线SROM接口... 191.4.2 摄像头接口(CAMIF).. 211.4.3 LCD驱动器接口... 241.4.4 HDMI接口... 281.4.5 USB 2.0 HOST接口... 291.4.6 ...…

查看全部问答>

独立自锁按键 问题

独立自锁按键的程序与非自锁按键的程序一样吗,也需要检测2次吗?…

查看全部问答>

想入手一块二手2440开发板

哪位大侠有限制的2440开发板,要是JZ的最好了,其他的也行,希望价格便宜,联系我QQ496142088…

查看全部问答>

HEX文件内容有点不了解

最近做一些备案工作,有一项是查看软件代码的起始结束地址,从map文件里可以看到,但是知道也可以从hex文件里看 碰到一个问题 :067FF000B0B0B0B0B6AF66 :020000021000EC :0A7FF600FFFFFFFFFFFFFFFFFFFF8B :00000001FF复制代码最后四行是这样的。 ...…

查看全部问答>

linux下安装OpenSSH无法启动

我在linux(ubuntu)下安装OpenSSH,安装完成后,无法启动。 网上也查不到。 截图如下: 请高手指教,谢谢! …

查看全部问答>

参与DLP应用产品设计,望大家给一些电子电路方面的建议

本帖最后由 cardin6 于 2016-3-11 15:53 编辑 当然,本人只负责产品的外观设计 我们想将设计做的更有意思,因此,除DLP的投影功能外,另外增加了一些附属功能  应了柱哥的想法,使之真正成为一个“大玩具” 设计原型为《机器总动员》 ...…

查看全部问答>