MSP430单片机C语言的基本结构
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第 1页/共 13 页
例 1:C 程序的基本结构。图 1 的例子基本说明了 C 程序的基本结构,不论你的程序是大还是小,头文件、 主函数总是需要的。注意图中红色的标注,可以帮助我们理解在程序中每条语句是怎样被执行的。
图 1. C 程序的基本结构 如果要打一个比较形象的比喻,上面这个小例子的基本结构就是通过 while(1)语句让 CPU 在那儿不停 地跑圈,一直不停地依次执行相同的任务:间隔地点亮红色和绿色 LED。如果画一张图的话,应该像图 2 所示。
图 3. C 程序中的宏定义和引用
第 3页/共 13 页
例 3:C 程序中函数的定义和调用。定义函数和调用函数是 C 语言最突出的特点之一,也最有挑战性,函 数的英文名称是 Function,字面意义上就是一个功能,数学里的函数不就是一个功能吗? y f ( x ) 6 x 2 , 就是完成了一个功能,一个抛物线的功能。 C 语言中,通过定义函数完成相应的功能,并通过在主函数 main( )中调用函数来实现其功能。在函数定义中还可以给函数传递参数(形参) ,函数中还可以有复杂的 数学运算及逻辑处理。函数可以有返回值,也可以没有返回值(只完成某些操作) 。在图 4 的示例中只定 义了几个简单的函数,没有传递参数,没有复杂的数学或逻辑运算,也没有返回值。很多情况下,有些函 数定义了,但在主函数中没有调用它,则这个函数是不起作用的。
图 2. CPU 在跑圈,周围有一些可以产生中断的事件,但 CPU 不一定理会
第 2页/共 13 页
例 2:C 程序的宏定义。图 3 示例了宏定义的方法,通过宏定义可以把许多操作和语句定义为有字面含义 的名称, 如图 3 程序中的 Red_On_Green_Off, 一读就知道是让红色 LED 点亮, 绿色 LED 熄灭。 有人说过: 用 C 语言编程,无论变量、语句还是函数都是可以念出来并像让人听起来就懂的。因此给变量命名、函数 命名、宏定义等,都要起一些一看就知其意的名字,读起来可以朗朗上口的,有助于程序的可读性和相互 交流,也有助于你自己事后的修改和维护。
Biblioteka Baidu
图 4. 函数的定义和调用
第 4页/共 13 页
例 4:多文件管理和头文件。如果程序很大,则可以进行功能划分,把它模块化。如图 5 的工程中,有 Blink_and_Delay.c, Blink_and_Delay.h, Lighting Two LEDs with Multi C files.c 三个文档。
第 11页/共 13 页
下列各图示例了.cmd 文件中各寄存器地址的定义。
第 12页/共 13 页
实际上在 CCS 的编译环境下还包括了许多的头文件,包括数学运算,输入输入出等等,等等。
这些就是 MSP430 单片机 C 程序的大致框架。 如此说来我们的 C 程序在那儿干什么?它就是在那里赋值和运算还有中断处理, 当然这一切需要结合 着单片机内的硬件(其内部资源)以及单片机外的硬件电路安排来进行,这就是软件+硬件。至于汇编, 你先不要碰它好了,什么时候需要了,再去处理它也不迟。我们的任务已经很明确和简单了,我们手头上 有许多寄存器和控制寄存器,寄存器内有很多位(0 或者 1) ,这些就是我们的操作对象(而不是那十二把 舀子) ,当我们把一切都设置好了以后,单片机里的千军万马就听我们的调遣了,停!单片机的外面呢? 同样的有千军万马!外面的电阻、电容、电感,二极管、三极管、场效应管、稳压器、模拟集成电路、数 字集成电路、千奇百怪的传感器、通信模块、控制模块、LCD、按键、触摸键,上位机、下位机、USB、 以太网、物联网… …, 何止是千军万马啊,数不胜数啊。 因此,我们才刚刚上路哎。 希望这些能对大家能有所帮助,不妥之处敬请批评指正。 又及,写东西、码字是很累人的活,不知不觉半下午和一晚上又过去了。
第 7页/共 13 页
以下各图示例了 430 的头文件中的宏定义,包括各寄存器的定义,寄存器中各位的定义等等。这些头 文件中的内容千万不要动,不要改变,否则会很麻烦的。除非你很清楚你在干什么。 (后面还有一些文字, 请耐心看到最后一页)
第 8页/共 13 页
第 9页/共 13 页
第 10页/共 13 页
MSP430 单片机 C 语言的基本结构
王晓宁 2013/1/28
随着单片机处理速度的加快和存储容量的加大以及相应的开发软件中增强的代码优化功能, 用 C 语言 编写的程序其代码效率和运行速度已堪与汇编程序相媲美,而且 C 语言程序因其平易性、结构化、易维护 性和可移植性而日益广泛地应用于单片机的开发中。用 C 语言编程时必须结合单片机的特点,不同品牌、 不同系列或不同型号的单片机其内部资源、寄存器名称等都会不同,因此其软件的开发必须结合实际的硬 件来进行。 但 C 语言的程序结构还是有许多共性的, 下面结合 MSP430 单片机大致说一下 C 程序的基本结 构。 C 语言的程序结构还是比较规范的,一般包括头文件、宏定义、变量定义、函数定义、一个主函数 main( )、以及中断处理函数等。在多文件的管理中,还包括自定义的头文件等。根据不同的情形,一个完 整的 C 程序可以有不同的具体结构,但其框架基本上还是固定的。下面通过几个简单的小例子来看一下 C 程序的几种结构。 在此之前,先说一下 C 中的赋值方式。很多情况下,C 程序就是在那儿完成一些赋值操作。|= 是“或” 运算,&=是“与”运算,^= 是“异或”运算。比如 BIT0 已经在 430 的头文件里定义为:BIT0=0x0001, 0x0001 是 16 进制计数,转成 2 进制就是 00000001(低八位),那么 P1OUT|=BIT0,是一个什么结 果?这是一个“或”运算(英文称 or)。首先 P1OUT 是一个在头文件中定义好的寄存器,是 8 位的,因 此,我们可以把 P1OUT 就当成一个变量名好了,只不过这个变量是在头文件中定义的,我们直接拿来用 即可。P1OUT 的取值就是在 00000000~11111111 之间(二进制)。因此不管 P1OUT 原先的值时多少, P1OUT|=BIT0 就是(设 P1OUT 原先的值为 xxxxxxxx)xxxxxxxx 跟 00000001 进行或运算,最低位 (即 BIT0)的值肯定是 1 的,而对其它位没有影响。,因此这样赋值后 P1OUT=xxxxxxx1 ,达到了让 BIT0 位等于 1(称为“置 1”)的目的。P1OUT&=~BIT0 的结果呢?首先,这是一个“与”运算(英文 称 and),而“~”在 C 中是一个求反的符号(即 1 变 0,0 变 1),则~BIT0=11111110,也即把 BIT0 原来各位的值全求反了。那么不论 P1OUT 原来的值是多少,就假设为 xxxxxxxx ,则 xxxxxxxx 跟 , 11111110 相“与”的结果就是 xxxxxxx0,也就是 BIT0 这一位肯定是 0 的(称为“清 0”或“置 0”) 而 对 其 它 位 没 有 影 响 。 P1OUT^=BIT0 呢 ? 这 称 为 “ 异 或 ” 运 算 ( 英 文 称 为 xor ) ( 1^0=1,0^1=1,0^0=0,1^1=0 ) , BIT0=00000001 , 设 P1OUT=xxxxxxx1 , 则 ( xxxxxxx1 ) ^(00000001)=xxxxxxx0;若 P1OUT=xxxxxxx0,则(xxxxxxx0)^(00000001)=xxxxxxx1,因此 不管 P1OUT 的值原先是多少, 经过 P1OUT^=BIT0 的运算后, (原先是 1 变为 0, BIT0 这一位总是取反的 原先是 0 变为 1)。综上,P1OUT|=BIT0 是赋 1 运算,P1OUT&=~BIT0 是赋 0 运算,P1OUT^=BIT0 是 求反运算,而且都是只对 BIT0 位产生影响,对其它位是没有影响的(其它位还保留它们原先的值)。这 是一种很好的处理方法,因为单片机的寄存器,其每一位都是有控制作用的,我们只改变我们想赋值的那 一位,而对其它位不造成影响。当然其它一些赋值方法也是可以的,如:WDTCTL=WDTPW+WDTHOLD 等。 另 外 BIT6+BIT0 是 互 不 影 响 的 , 因 为 BIT6=01000000 , BIT0=00000001 , 因 此 BIT6+BIT0=01000001 , 各 位 之 间 互 不 干 扰 ( 或 称 为 互 不 打 架 ) 。 很 多 位 相 加 也 是 同 理 : BIT7+BIT6+BIT3+BIT1=10000000+01000000+00001000+00000010=11001010,各位互不影响。 因此,可以有这样的赋值运算:P1DIR|=BIT6+BIT0,P1OUT&=~(BIT7+BIT5+BIT1)等等。其它的 运算就是加减乘除了。这些事情在许多单片机的书及资料中都有叙述,可能没有讲得这么细。
图 5. 多文档的管理
图 6. 文档 1
第 5页/共 13 页
图 7. 文档 2
图 8. 文档 3
第 6页/共 13 页
例 5.中断及其处理。图 9 示例了中断及其中断服务程序的编写方法。
图 9. 中断及其处理,本例中运用了低功耗模式 0 中断是控制器或处理器为了快速响应及处理外部事件(如按键、触摸屏、AD 转换结束、定时器计时 到、以及与外部模块接口等等)而采取的一种应对机制。中断就是一种临时打断,如图 2 中所示,CPU 本 来在那儿跑圈,如果我们的程序中允许了某些中断并开启了总中断,则当这些中断事件发生时,CPU 就会 响应这些中断,也就是 CPU 先去处理这些中断事件(或称突发事件) ,处理完后,CPU 再返回到原来的被 中断点,继续处理它原来的事情。这个过程会涉及到 PC(程序计数器)值的变化及 SP(堆栈指针)的改 变等等,不过 PC 和 SP 的变化在我们的 C 程序中是不可见的,或者说是我们不需要关心的,我们只要写 好我们的 C 语言就一切 OK 了。
第 13页/共 13 页