云题海 - 专业文章范例文档资料分享平台

当前位置:首页 > MSP430单片机原理 - 图文

MSP430单片机原理 - 图文

  • 62 次阅读
  • 3 次下载
  • 2025/12/10 15:47:42

15 (最低) , 逗号运算符 从左至右

从表2-7可知,C语言中的运算符的运算优先级共分为15级。1级最高,15级最低。在表达式中,优先级较高的要比优先级较低的先进行运算。 而在一个运算量两侧的运算符优先级相同时, 则按运算符的结合性所规定的结合方向处理。 C语言中各运算符的结合性分为两种,即左结合性(自左至右)和右结合性(自右至左)。需要时可在算术表达式中采用圆括号来改变运算符的优先级。

C语言中提供了一种用于求取数据类型、变量以及表达式的字节数的运算符: sizeof,该运算符的一般使用形式为:

sizeof(表达式)或sizeof(数据类型)

应该注意的是,sizeof是一种特殊的运算符,不要错误地认为它是一个函数。实际上,字节数的计算在程序编译时就完成了,而不是在程序执行的过程中才计算出来的。例如:int a = sizeof(float); 执行这条命令的结果是把4赋给了整型变量a,这意味着一个单精度数存储时占有4个字节内存。

1)尽可能避免浮点运算。对于单片机来说,浮点数的运算速度很慢, RAM开销也大,且有效位数有限;在低功耗应用中CPU运算时间直接关系到平均功耗。因此在编程初期就要养成尽量避免使用浮点数的习惯。

2)防止定点数溢出。定点数运算首先要防止数据溢出。例如: long x; int a; x=a*1000;

虽然x是long变量,但a和常数1000都是int型,相乘结果仍然是int型。在 a>65的情况下,结果就会溢出。程序应该修改为:

x=a*(long)1000; 或 x=(long)a*1000;

若遇到多个变量相乘,更需要细心检查。所以,在测试每一段软件的时候,一定要取边界条件做极限测试。

3)小数的处理。遇到需要保留小数的运算,可以采用浮点数,但是软件开销较大。用定点数也可以处理小数。原理就是先扩大,再运算。例如,我们需要计算温度并保留1位小数,假设温度计算公式是:

Deg_C=ADC*1.32/1.25-273 为了让小数 1.32 能被定点运算,先扩大 100 倍变成 132,当然,除数 1.25 也要随之扩大 100 倍,公式变为:Deg_C=(long)ADC*132/125-273 。

这样运算结果只能保留到整数,为了让结果保留 1 位小数,需要人为将所有数值都扩大 10 倍,得到最终计算公式 Deg_C=(long)ADC*1320/125-2730 。假设温度应该是 23.4 度,上述公式的运算结果将是 234。在显示的时候,将小数点添加在倒数第 2 位上,即可显示 23.4。用定点数处理小数,如需要保留 N 位小数,就要将数值扩大10N倍。注意防止溢出,且要记住每个数值所扩大的倍数,在程序中应添加注释。

4)尽量减少乘除法。430 单片机没有乘法/除法指令,乘除操作会被编译器转换成移位和加法来实现。如果乘除的数值刚好是 2 的幂,那么可以用移位直接替代乘除法,运算速度会提高很多。例如对 16 次采样数据求平均:

for(i=0;i<16;i++) Sum+=ADC_Value[i]; //求和 Aver=Sum/16; //这一句的运算较慢

13

对于除 16 写成如下形式,运行速度会提高很多: Aver=Sum>>4; // 除以 16

若将编译器优化级别设置得比较高,在遇到乘除 2 的幂表达式时,编译器会自动用移位替代除法(编译器很聪明),从而加快执行速度。

位操作指令大部分存在于早期速度不高的 CISC 处理器上(以 8051 为代表),以提高执行效率,弥补 CPU 运算速度的不足。目前几乎所有的 RISC 型处理器都取消了位操作指令,430 单片机也不例外。在 430 的 C 语言中,也不支持位变量,因为位操作完全可以由变量与掩模位(mask bits)之间的逻辑操作来实现。

例如将 P1.0 置高、将 P1.1 置低,将 P1.2 取反,我们可以写成: P1OUT |= 0x01; //P2.0 置高 P1OUT &= ~0x02; //P2.1 置低 P1OUT ^= 0x04; //P2.2 取反

在寄存器头文件中,已经将 BIT0~BIT7 定义成 0x01~0x80,上述程序也可以写成:

P1OUT |= BIT0; //P2.0 置高 P1OUT &= ~BIT1; //P2.1 置低 P1OUT ^= BIT2; //P2.2 取反

对于多位可以同时操作,例如将 P1.1、P1.2、P1.3、P1.4 全部置高/低可以写成:

P1OUT |= BIT1+BIT2+BIT3+BIT4; //P1.1/2/3/4 全置高

P1OUT &=~(BIT1+BIT2+BIT3+BIT4); //P1.1/2/3/4 全置低 注意括号! 实际上,这条语句相当于

P1OUT |= 0x1e; //P1.1/2/3/4 全置高 对于读操作,也可以通过寄存器与掩模位(mask bits)之间的“与”操作来实现。例如有通过 P1.5、P1.6 口控制位于 P2.0 口的 LED。下面代码示范读取 P1.5 和 1.6 的值:

char Key;

if((P1IN & BIT5)==0)

P2OUT|=BIT0;//若P1.5为低,则P2.0口的LED 亮 if( P1IN & BIT5)

P2OUT|=BIT1;//若P1.5为高,则P2.1口的 LED 亮 if( P1IN & (BIT5+BIT6))

P2OUT|=BIT0;//若 P1.5 和 P1.6 任一为高,则点亮LED if((P1IN & (BIT5+BIT6)) != (BIT5+BIT6))

P2OUT|=BIT0;//若 P1.5 和 P1.6 任一为低,则点亮 LED if(P1IN & BIT5) Key=1; Else

Key=0; //读取 P1.5 状态赋给变量 Key。

另外还有一种流行的位操作写法,用(1<

if((P1IN & (1<<5))==0) P2OUT|=(1<<0); //若 P1.5 为低,则 P2.0 口的LED 亮。

这种写法的好处是使用纯粹的 C 语言表达式实现,不依赖于 msp430 的头文件中 BITx的宏定义,无需改动即可移植到任何其他单片机上,但可读性较差。

2.2.3 函数

14

C语言程序是由若干个函数单元组成的,每个函数都是完成某个特殊任务的子程序段。组成一个程序的若干个函数可以保存在一个源程序文件中,也可以保存在不同源程序文件中。文件名由程序设计人员根据某种规则自己确定,其扩展名统一为“.C”。一个完整的C语言程序应包含一个主函数main()和若干个其它功能的函数。函数之间可以相互调用,但main()函数只能调用其它的功能函数,而不能被其它函数所调用。功能函数可以是C语言编译器提供的库函数,也可以由用户按实际需要自行编写的函数。不管main()函数处于程序中的什么位置,程序总是从main()函数开始执行。一个函数必须预先定义或声明后才能调用。函数定义或声明位于源程序的预处理命令之后的开始位置。函数定义部分包括有函数的存储类型、返回值数据类型、函数名、形式参数说明等,函数名后面必须跟一个圆括弧(),形式参数说明在圆括弧()内进行。函数也可以没有形式参数。函数的位置比较自由。函数由函数名和一对花括弧“{}”组成,在“{}”里面的内容就是函数体,如果一个函数有多个“{}”,则最外面的一对“{}”为函数体的范围。

函数是C语言中的一种基本模块。在进行程序设计的过程中,如果所设计的程序较大,一般应将其分成若干个子程序模块,每个子程序模块完成一种特定的功能。在C语言中,子程序是用函数来实现的。对于一些需要经常使用的子程序可以按函数来设计,以供反复调用。此外,EW430编译器还提供了丰富的运行库函数,用户可以根据需要随时调用。这种模块化的程序设计方法,可以大大提高编程效率。标准库函数见IAR for msp430安装目录文件clib.pdf,路径D:\\Program Files\\IAR Systems\\Embedded Workbench 6.0 Evaluation\\430\\doc\\clib.pdf。

从用户的角度来看,有两种函数:标准库函数和用户自定义函数。标准库函数是IAR EW430编译器提供的,不需要用户进行定义,可以直接调用。用户自定义函数是用户根据自己的需要编写的能实现特定功能的函数,它必须先进行定义之后才能调用。

函数的定义

无参数函数定义的语法格式: Void 函数名() {

声明部分 程序语句 }

void delay(void) //函数头 {

unsigned int i,j; //声明部分 for(i=100;i>0;i--) //程序语句 for(j=112;j>0;j--) {;} }

有参数函数定义的语法格式:

函数类型 函数名(形式参数表) { 形式参数说明; 局部变量定义;

15

函数体语句; }

其中,“函数类型”说明了自定义函数返回值的类型。

int compare(int a,int b)//函数头,括号里为形式参数 {

if(a>b) //以下是程序语句 return a; else

return b; }

对于实参与形参的特点有以下的几点补充:

1)实参与形参在类型﹑数量﹑顺序应保持一致,否则会在编绎的时候出现警告或者程序运行的结果错误。

2)被调用函数的形参只有被调用的时候才会被分配内存空间,退出了函数之后,所分配的内存单元立即被释放,所以退出了函数之后形参就不能再使用。

3)实参在调用前一定要有确定的值,因此在函数调用前必须先赋予实参一个确定的值。

如果定义函数时只给出一对花括号{}而不给出其局部变量和函数体语句,则该函数为所谓“空函数”,这种空函数也是合法的。在进行C语言模块化程序设计时,各模块的功能可通过函数来实现。开始时只设计最基本的模块,其它作为扩充功能在以后需要时再加上。编写程序时可在将来准备扩充的地方写上一个空函数,这样可使程序的结构清晰,可读性好,而且易于扩充。

C语言程序中函数是可以互相调用的。所谓函数调用就是在一个函数体中引用另外一个已经定义了的函数,前者称为主调用函数,后者称为被调用函数。主调用函数调用被调用函数的一般形式为: 函数名(实际参数表);

其中,“函数名”指出被调用的函数。

“实际参数表”中可以包含多个实际参数,各个参数之间用逗号隔开。实际参数的作用是将它的值传递给被调用函数中的形式参数。

在C语言中可以采用三种方式完成函数的调用:

1)函数语句。在主调函数中将函数调用作为一条语句。

2)函数表达式。在主调函数中将函数调用作为一个运算对象直接出现在表

达式中。 3)函数参数。在主调函数中将函数调用作为另一个函数用的实际参数。

在进行函数调用时,必须用主调函数中的实际参数来替换被调函数中的形式参数,这就是所谓的参数传递。在C语言中,对于不同类型的实际参数,有三种不同的参数传递方式:

1)基本类型的实际参数传递

当函数的参数是基本类型的变量时,主调函数将实际参数的值传递给被调函数中的形式参数,这种方式称为值传递。前面讲过,函数中的形式参数在未发生数调用之前是不占用内存单元的,只有在进行函数调用时才为其分配临时存储单元。而函数的实际参数是要占用确定的存储单元的。

值传递方式是将实际参数的值传递到为被调函数中形式参数分配的临时存储单元中,函数调用结束后,临时存储单元被释放,形式参数的值也就不复存在,但

16

搜索更多关于: MSP430单片机原理 - 图文 的文档
  • 收藏
  • 违规举报
  • 版权认领
下载文档10.00 元 加入VIP免费下载
推荐下载
本文作者:...

共分享92篇相关文档

文档简介:

15 (最低) , 逗号运算符 从左至右 从表2-7可知,C语言中的运算符的运算优先级共分为15级。1级最高,15级最低。在表达式中,优先级较高的要比优先级较低的先进行运算。 而在一个运算量两侧的运算符优先级相同时, 则按运算符的结合性所规定的结合方向处理。 C语言中各运算符的结合性分为两种,即左结合性(自左至右)和右结合性(自右至左)。需要时可在算术表达式中采用圆括号来改变运算符的优先级。 C语言中提供了一种用于求取数据类型、变量以及表达式的字节数的运算符: sizeof,该运算符的一般使用形式为: sizeof(表达式)或sizeof(数据类型) 应该注意的是,sizeof是一种特殊的运算符,不要错误地认为它是一个函数。实际上,字节数的计算在程序编译时就完成了,而不是在程序执行的过程中才

× 游客快捷下载通道(下载后可以自由复制和排版)
单篇付费下载
限时特价:10 元/份 原价:20元
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信:fanwen365 QQ:370150219
Copyright © 云题海 All Rights Reserved. 苏ICP备16052595号-3 网站地图 客服QQ:370150219 邮箱:370150219@qq.com