第三章 单片机运算符及表达式
单片机C语言基础(单片机入门必看)

单片机C语言基础(单片机入门必看)今天我们要说的不是stm32,是关于单片机开发中所应用到的C 语言基础的。
C是单片机开发的必备基础,也是一定要学的,但是单片机的C语言和纯C语言开发相比学的东西要少很多,也正是因为这样刚刚学习单片机的朋友不要看到要学习C语言就开始发怵,其实这个是没有必要的,其学习深度是不一样的,多以不要过于担心!!下面来进入今天的主题单片机C语言编程基础。
用一个简单的c程序例子,介绍c语言的基本构成、格式、以及良好的书写风格,使小伙伴对c语言有个初步认识。
例1:计算两个整数之和的c程序:#include main() { int a,b,sum; /*定义变量a,b,sum为整型变量*/ a=20; /*把整数20赋值给整型变量a*/ b=15; /*把整数15赋值给整型变量b*/ sum=a+b; /*把两个数之和赋值给整型变量sum*/ printf(“a=%d,b=%d,sum=%d\n”,a,b,sum); /*把计算结果输出到显示屏上*/ }重点说明:1、任何一个c语言程序都必须包括以下格式:main() { }这是c语言的基本结构,任何一个程序都必须包含这个结构。
括号内可以不写任何内容,那么该程序将不执行任何结果。
2、main()----在c语言中称之为“主函数”,一个c程序有且仅有一个main函数,任何一个c程序总是从main函数开始执行,main 函数后面的一对圆括号不能省略。
3、被大括号{ }括起来的内容称为main函数的函数体,这部分内容就是计算机要执行的内容。
4、在{ }里面每一句话后面都有一个分号(;),在c语言中,我们把以一个分号结尾的一句话叫做一个c语言的语句,分号是语句结束的标志。
5、printf(“a=%d,b=%d,sum=%d\n”,a,b,sum); ----通过执行这条c语言系统提供给我们直接使用的屏幕输出函数,用户即可看到运行结果,本程序运行后,将在显示器上显示如下结果:a=20,b=15,sum=356、#include注意:(1)以#号开头 (2)不以分号结尾这一行没有分号,所以不是语句,在c语言中称之为命令行,或者叫做“预编译处理命令”。
第3章_C51语言编程基础

.
3
2、Keil C51语言简介
对于51单片机,目前广泛使用的是Keil C51语言,简称C51语言。
Keil C51语言是在标准C的基础上,针对51单片机的硬件特点进行 扩展,并向51单片机上移植的高效、简洁的实用高级语言。
与汇编语言相比的特点: (1)可读性好。 (2)可模块化开发。 (3)可移植性好。 (4)生成的代码效率较低。
unsigned char j ;
for(j=0; j<8; j++) {
buffer[j]=0; }
}
.
8
33
3、C51的基本运算 C51语言的基本运算与标准C类似,主要包括算术运算、关系运算、 逻辑运算、位运算和赋值运算及其表达式等。
1)算术运算符
.
34
2)关系运算符
关系表达式
int x=3; int y=6; int R;
bit的值可以是1(true),或0(false)。
格式: bit 变量名;
例如:
bit
flag;
flag = 0;
.
8
(2)特殊功能寄存器sfr 地址单元80H——FFH之间的片内数据存储区; “sfr” 数据类型占用一个内存单元; 利用它可以访问51单片机内部的所有特殊功能寄存器。 格式: sfr 寄存器变量名 = 字节地址常数;
01000000 | 11111111
00001000 << 3
.
38
【例】以字节操作方式对I/O口P1的P1.5清0 ,P1.1置为1, 其他位保持不变。
例如:
sfr
PSW = 0xd0;
//定义PSW寄存器地址为0xd0
51单片机位操作

C51单片机位操作方法C51对位的操控能力是非常强大的。
从这一点上,就可以看出C不光具有高级语言的灵活性,又有低级语言贴近硬件的特点。
这也是在各个领域中都可以看到C的重要原因。
在这一节中将详细讲解C51中的位操作及其应用。
1、位运算符C51提供了几种位操作符,如下表所示:1)“按位与”运算符(&)参加运算的两个数据,按二进位进行“与”运算。
原则是全1为1,有0为0,即:0&0=0; 0&1=0; 1&0=0; 1&1=1;如下例:a=5&3; //a=(0b 0101) & (0b 0011) =0b 0001 =1那么如果参加运算的两个数为负数,又该如何算呢?会以其补码形式表示的二进制数来进行与运算。
a=-5&-3; //a=(0b 1011) & (0b1101) =0b 1001 =-7在实际的应用中与操作经常被用于实现特定的功能:1.清零“按位与”通常被用来使变量中的某一位清零。
如下例:a=0xfe; //a=0ba=a&0x55;//使变量a的第1位、第3位、第5位、第7位清零a= 0b2.检测位要知道一个变量中某一位是‘1’还是‘0’,可以使用与操作来实现。
a=0xf5; //a=0bresult=a&0x08; //检测a的第三位,result=03.保留变量的某一位要屏蔽某一个变量的其它位,而保留某些位,也可以使用与操作来实现。
a=0x55; //a=0ba=a&0x0f; //将高四位清零,而保留低四位a=0x052)“按位或”运算符(|)参与或操作的两个位,只要有一个为‘1’,则结果为‘1’。
即有‘1’为‘1’,全‘0’为‘0’。
0|0=0; 0|1=1; 1|0=1; 1|1=1;例如:a=0x30|0x0f; //a=(0b)|(0b)=(0b)=0x3f“按位或”运算最普遍的应用就是对一个变量的某些位置‘1’。
单片机C51语言及程序设计

贰
壹
叁
C51编译器在头文件“REG51.H”中定义了全部sfr/sfr16和sbit变量。 用一条预处理命令#include <REG51.H>把这个头文件包含到C51程序中,无需重新定义即可直接使用它们的名称。
应用举例:
片内数据存储器,片外数据存储器和程序存储器。
通常下划线开头的标识符是编译系统专用的,因此在编写C语言源程序时一般不使用以下划线开头的标识符,而将下划线用作分段符。C51编译器规定标识符最长可达255个字符,但只有前32个字符在编译时有效,因此标识符的长度一般不要超过32个字符。
关键字是一种已被系统使用过的具有特定含义的标识符。用户不得再用关键字给变量等命名。C语言关键字较少,ANSI C标准一共规定了32个关键字,见表
变量名具有字母大小写的敏感性,如SUM和sum代表不同的变量。
【存储类别】 数据类型 【存储器类型】 变量名
变量名不得使用标准C语言和C51语言的关键字。
unsigned char data system_status = 0;
//定义system_status为无符号字符型自动变量,该变量位于data区中且初值为0。
sfr或sfr16型 51MCU中有21个SFR,如何定义与这些单元相关的变量?
例如,sfr P0 = 0x80; //定义P0口地址80H sfr PCON = 0x87; //定义PCON地址87H sfr16 DPTR=0x82; //定义DPTR的低端地址82H
单精度浮点数
for
程序语句
构成for循环结构
goto
程序语句
构成goto转移结构
if
程序语句
第3章51系列单片机程序设计(C语言部分)

idata
间接寻址片内数据存储区,可访问片内全部RAM地址空间(256字节)
pdata
分页寻址片外数据存储区(256字节)由MOV @Ri访问(i=0,1)
xdata
片外数据存储区(64 KB)由MOVX @DPTR访问
code
程序存储器64 KB空间,由MOVC @DPTR访问
第3章 51系列单片机程序设计(C部分)
/* Ary37定义为abry[3]的第7位 */
第3章 51系列单片机程序设计(C部分)
3.5 数 组
数组:数组是一组类型相同 有序数据的集合。用数组名 和下标来唯一确定数组中的 元素。
第3章 51系列单片机程序设计(C部分)
3.5.1 一维数组
一、一维数组的定义 形式:类型说明符 数组名 [常量表达式]
使用C51进行编程时,MCS-51片内的I/O口与片外扩展的I/O可以统一在一个头文 件中定义,也可以在程序中(一般在开始的位置)进行定义。
对于MCS-51片内I/O口按特殊功能寄存器方法定义。 例如:
sfr P0=0x80 ; /* 定义P0口,地址为80H */ sfr P1=0x90 ; /* 定义P1口,地址为90H */
第3章 51系列单片机程序设计(C部分)
3.4.3 C51数据的存储类型与MCS-51存储结构
表 3.4.2 C51存储类型与MCS-51存储空间的对应关系
存储类型 与存储空间的对应关系
data
直接寻址片内数据存储区,访问速度快(128字节)
bdata
可位寻址片内数据存储区,允许位与字节混合访问(16字节)
据 浮点型(float) 类
型 指针类型
详细见表3.4.1
单片机符号表

PC = progammer counter //程序计数器ACC = accumulate //累加器PSW = progammer status word //程序状态字SP = stack point //堆栈指针DPTR = data point register //数据指针寄存器IP = interrupt priority //中断优先级IE = interrupt enable // 中断使能TMOD = timer mode //定时器方式(定时器/计数器控制寄存器) ALE = alter (变更,可能是) 寄存器控制PSEN = progammer saving enable //程序存储器使能(选择外部程序存储器的意思)EA = enable all(允许所有中断)完整应该是enable all interrupt PROG = progamme (程序) SFR = special funtion register //特殊功能寄存器TCON = timer control //定时器控制PCON = power control //电源控制MSB = most significant bit//最高有效位LSB = last significant bit//最低有效位CY = carry //进位(标志)AC = assistant carry //辅助进位OV = overflow //溢出ORG = originally //起始来源DB = define byte //字节定义EQU = equal //等于DW = define word //字定义E = enable //使能OE = output enable //输出使能RD = read //读WR = write //写中断部分:INT0 = interrupt 0 //中断0INT1 = interrupt 1//中断1T0 = timer 0 //定时器0T1 = timer 1 //定时器1TF1 = timer1 flag //定时器1 标志(其实是定时器1中断标志位)IE1 = interrupt exterior //(外部中断请求,可能是)IT1 = interrupt touch //(外部中断触发方式,可能是)ES = enable serial //串行使能ET = enable timer //定时器使能EX = enable exterior //外部使能(中断)PX = priority exterior //外部中断优先级PT = priority timer //定时器优先级PS = priority serial //串口优先级助记符号的记忆方法表格列举法把44个指令助记符按功能分为五类,每类列表记忆。
单片机基础与应用(C语言版)第3章 C51程序设计基础

选择语句
多分支选择的switch语句, 其一般形式如下: switch(表达式)
{ case常量表达式1: 语句组1;break; case常量表达式2: 语句组2;break; …… case常量表达式n: 语句组n;break; default : 语句组n+1;
} 该语句的执行过程是:首先计算表达式的值,并逐个与case后的常量表达 式的值相比较,当表达式的值与某个常量表达式的值相等时,则执行对应 该常量表达式后的语句组,再执行break语句,跳出switch语句的执行,继 续执行下一条语句。如果表达式的值与所有case后的常量表达式均不相同, 则执行default后的语句组。
位运算
按位或操作符: |
或操作
格式:x|y
规则:对应位均为0时才为0,否则为1 例如, i=i|0x0f; 等同于
i|=0x0f;
主要用途:将1个数的某(些)位置1,其余各位不变
位运算
异或操作
按位异或操作符:^ 格式:x^y 规则:对应位相同时为0,不同时为1
例如, i=i^0x0f; 等同于 i^=0x0f; 主要用途:使1个数的某(些)位翻转(即原来为1的位 变为0,为0的变为1),其余各位不变。
右移运算符“>>”的功能,是把“>>”左边的操作数 的各二进制位全部右移若干位,移动的位数由“>>” 右边的常数指定。进行右移运算时,如果是无符号数, 则总是在其左端补“0”
练习
1 .若x = 10, 则!X的值为真或假? 2. 若a = 3, b = 2, 则if(a&b)的值为真或假? 3. 5 && 0 ||8的值为?
浮点型 指针型 位类型 特殊功能寄存器 16位特殊功能寄存器 可寻址位
单片机教学大纲(两篇)2024

引言概述:正文内容:1.硬件设备与基本概念1.1单片机基础知识1.1.1单片机的定义和分类1.1.2单片机的结构和工作原理1.1.3单片机的常用引脚功能与连接方法1.2单片机开发板选型与使用1.2.1不同型号单片机开发板的特点和功能1.2.2单片机资源配置与接口扩展1.2.3单片机开发环境的搭建和使用方法2.嵌入式C语言编程基础2.1C语言基本语法2.1.1数据类型与变量2.1.2运算符和表达式2.1.3控制结构与循环语句2.2单片机C语言编程入门2.2.1I/O口配置与控制2.2.2延时和定时器控制2.2.3中断处理3.单片机外设驱动3.1数码管与LED显示驱动3.1.1数码管的原理与显示方法3.1.2数码管驱动电路设计与编程实现3.2液晶显示屏驱动3.2.1液晶显示驱动的原理3.2.2液晶显示屏驱动电路设计与编程实现3.3三轴加速度传感器驱动3.3.1三轴加速度传感器基本原理3.3.2传感器接口与数据读取4.串口通信与通信协议4.1串口通信基础4.1.1串口通信协议与通信波特率4.1.2串口通信硬件连接与配置4.2单片机与PC的串口通信4.2.1串口通信的原理与方法4.2.2串口通信协议的设计与实现4.3单片机与其他设备的串口通信4.3.1串口通信的硬件连接与配置4.3.2串口通信协议的设计与实现5.单片机应用开发5.1温湿度监测系统5.1.1温湿度传感器的原理和接口设计5.1.2数据采集与显示控制的编程实现5.2无线通信系统5.2.1无线通信模块与单片机的接口设计5.2.2数据传输与接收的编程实现5.3蜂鸣器音乐播放系统5.3.1蜂鸣器的基本工作原理和控制方法5.3.2音乐资源的存储与播放控制的编程实现总结:本教学大纲以逻辑顺序将单片机教学内容进行了详细介绍,从硬件设备与基本概念开始,逐步向学生展示了单片机开发的全过程。
通过掌握单片机编程的基本原理和实践技巧,学生将能够应用单片机实现各种嵌入式应用。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第三章运算符及表达式说明:Cx51的运算符与普通C语言的几乎完全一样,带复习性质,重点介绍在单片机中应用的特点。
一、运算符及表达式运算符:完成某种特定运算的符号。
运算符按其表达式中与运算符的关系可分为单目运算符,双目运算符和三目运算符。
单目就是指需要有一个运算对象,双目就要求有两个运算对象,三目则要三个运算对象。
运算对象:在程序运行时,有数值或有数值传递给它。
表达式:表达式则是由运算符及运算对象所组成的具有特定含义的式子。
C是一种表达式语言,表达式后面加";"号就构成了一个表达式语句。
例:x=a*(b+c-a);子表达式:成对的括号以及在它们之间的全部符号组成的表达式。
上例中(b+c-a)就是子表达式。
二、运算符1、赋值运算符1) 赋值运算符赋值符号“=”完成的操作即为赋值运算,它是右结合性,且优先级最低。
2) 赋值表达式将一个变量与表达式用赋值号连接起来就构成赋值表达式。
形式如下:变量名=表达式赋值表达式中的表达式包括变量、算术运算表达式、关系运算表达式、逻辑运算表达式等,甚至可以是另一个赋值表达式。
赋值过程是将“=”右边表达式的值赋给“=”左边的一个变量,赋值表达式的值就是被赋值变量的值。
例如:a=(b=4)+(c=6);,该表达式的值为10,变量a 的值为10。
3) 赋值的类型转换规则在赋值运算中,当“=”两侧的类型不一致时,要将数据转换成同一数据类型,转换的方式有两种,一种是系统自动转换,一种是强制转换。
(1)系统自动转换编译时,将右边表达式的值转换成左侧变量的类型,再赋给该变量。
转换规则如下:①实型数据赋给整型变量时,舍弃小数部分。
②整型数据赋给实型变量时,数值不变,但以IEEE 浮点数形式存储在变量中。
③长字节整型数据赋给短字节整型变量时,实行截断处理。
如将long 型数据赋给int型变量时,将long 型数据的低两字节数据赋给int 型变量,而将long 型数据的高两字节的数据丢弃。
④短字节整型数据赋给长字节整型变量时,进行符号扩展。
如将int 型数据赋给long型变量时,将int 型数据赋给long 型变量的低两字节,而将long 型变量的高两字节的每一位都设为int 型数据的符号值。
(2)强制转换使用强制类型转换运算符转换:(类型名) (表达式);将表达式的数据类型转换为前面要求的类型名。
例1:x=(float)a;y=(int)(x+y);例2:unsigned char x,y;unsigned int z;z=x+(unsigned int)y;4)应用在单片机中,经常要给寄存器、I/O口赋值:(1) P1=0xff;//给P1口全置1(2)P2=0x08; //给P2的第三位置1(3)TF0=0;//清定时器T0的溢出标志位(4)sbit P10=P1^0;//注意大写bit x;x=P10;P10=!P10;2、算术运算符c语言中的算术运算符有:+ 加或取正值运算符- 减或取负值运算符* 乘运算符/除运算符%模(求余)运算符上面这些运算符中加、减、乘、除为双目运算符,它们要求有两个运算对象。
这些大家已经很熟悉了。
3、关系运算符c语言中有6种关系运算符:> 大于< 小于>=大于等于<=小于等于==等于!=不等于前4种关系运算符具有相同的优先级,后两种关系运算符也具有相同的优先级;但前4种的优先级高于后2种。
优先级别:(低)赋值运算符→关系运算符→算术运算符(高)4、逻辑运算符逻辑运算符用来求某个条件式的逻辑值。
Cx51提供了3种逻辑运算符:|| 逻辑或( AND)&& 逻辑与(OR)! 逻辑非(NOT)逻辑表达式:用逻辑运算符将关系表达式或逻辑量连接起来。
逻辑表达式的一般形式为:逻辑与:条件式l&&条件式2逻辑或:条件式l || 条件式2逻辑非:!条件式例如:x&&y、a|| b、!z都是合法的逻辑表达式。
逻辑表达式的值是一个逻辑量真或假,0代表假,1代表真。
在逻辑运算中,把非0都看作逻辑1。
例:a=4;b=0;c=a||b;// c= 1c=a&&b;//c=0;c=!a;//c=0;5、位运算符1)能对运算对象进行按位操作,C语言中其有6种位运算符:&按位与| 按位或^ 按位异或~按位取反<< 左移>> 右移位运算符的作用是按位对变量进行运算,并不改变参与运算的变量值。
2)位运算符的优先级从高到低依次是:按位取反(~)→左移(<<)和右移(>>)→按位与(&) →按位异或(^)→按位或(|)。
3)所有位运算符的对象是int或 char数据类型,不能为实数。
4)位运算的应用例:P1=P1&0xf8;//将P1口的P1.0、P1.1、P1.2清零,其他位不变st=P0&0x07;//读P0.0、P0.1、P0.2的值,送入变量stP1=P1|0x08;//将P1口的P1.3置1,其他位不变P1=(P1&0xbf)|0x04;//给P1.6置低电平, P1.2置高电平,其//他位不变X=a^b//判断a是否与b相等,相等为05)位左移和位右移运算符(<<、>>)位左移、位右移运算符“<<”和“>>”,用来将一个数的各二进制位的全部左移或右移1位;移位后,空白位补0,而溢出的位舍弃。
注意汇编语言的区别。
例:若a=EAH=11101010B则表达式: a=a<<2,将a值左移两位,其结果为A8H。
汇编语言是循环移位,而C语言不是循环移位,但有循环移位的函数Unsigned char _cror_(unsigned char c, unsigned char c);上面时循环右移函数,c为待移动字符,b为移动位数。
循环左移函数是:Unsigned char _crol_(unsigned char c, unsigned char c);也可以自己编程循环移位。
下面讲右循环移位的例子。
例1:若a=11000011B=0C3H,将a值右循环位移两位。
对a进行循环右移二位的程序如下:#include<intrins.h>main(){ unsigned char a=0xc3,b,c,d;char data n=2;b=a<<(8-n);//b像左移6位,1、2位到7、8位c=a>>n;//右移2位d=c|b;//结果为11110000=0xf0,教材中方法c=_cror_(a,2);//用库函数实现}(调“循环移位”演示)例2:LED动态显示时,位码要不断移动,现在用C语言编程实现。
P1=0x08;P1=P1>>1;//每显示一位后移位一次(1)符号比较(2)位运算是对各位进行运算,逻辑运算的对象是逻辑变量。
例:#include <AT89X51>Main(){ unsigned char a=136,b=34,x1,x2,x3,x4,x5,x6;//a=0x88,b=0x22x1=!a; //x1=0x2=~a; //x2=0x77x3=a||b;//x3=1x4=a|b; //x4=0xaax5=a&b; //x5=0x00x6=a&&b;//x6=1}(运行“逻辑运算”)6、自增减运算符、复合运算符1)自增减运算符自增减运算符的作用是使变量值自动加1或减1。
如:++i,- -I “运算符在前,先运算后使用”即:在使用i之前,先使i值加(减)1。
i++,i-- “运算符在后,先使用后运算”即:在使用i之后,再使i值加(减)1。
例:若i值原来为5,则j=++i; j值为6,i值也为6;j=i++; j值为5,i值为6。
2) 复合运算符及其表达式凡是二目运算符,都可以与赋值运算符“=”一起组成复合赋值运算符。
Cx51共提供了10种复合赋值运算符,即 +=,-=,*=,/=,%=,<<=,>>=,&=,^=,|=。
采用这种复合赋值运算的目的,是为了简化程序,提高C程序编译效率。
如: a+=b 相当于a=a+ba%=b 相当于a=a%ba-=b 相当于a=a-ba<<=3 相当于a=a<<3a*=b 相当于a=a*ba>>=2 相当于a=a>>2a/=b 相当于a=a/b7、条件运算符?:条件运算符,根据条件进行选择的运算符。
关系表达式1 ?表达式2;表达式3;表达式1的值为1,执行表达式2,否则执行表达式3。
例:z=(a>b)?a:b;z=a;elsez=b;8、应用例子下面举一个使用位操作运算扫描识别键盘的例子。
1)工作原理图示为8051单片机与一个4×4键盘接口的扫描电路。
(1) P1口的高四位作为行驱动线,轮流给高4位输出高电平,经非门变为低电平;(2)读P1的低4位,如无键按下,P1的低4位应全为1;若有键按下,则不全为1。
(3)判断是否为同一次按键,将前次采集的值和本次采集的值相异或,同一次按键异或后为0,则不用新值替换旧值,若不一样,用新值替换旧值。
源程序如下:#include<at89x51.h>#define uchar unsigned charchar data old;//全局变量,传递数据key(){uchar cl;for(cl=0x10;cl!=0;cl=cl<<1)//item1{P1=0x0f|cl;//给高位轮流置1,给低位高电平,准备读端口if((P1&0x0f)!=0x0f)//判断低4为是否全为1{if((P1^old)>0)//用异或判断按下的是否是新键 old=P1;//不同将新值存入旧值中}}}main(){uchar i;old=0xff;//先给旧键值赋初值for(i=1;i<10;i++)key();}iteml:在程序中使用了for循环,详细内容将在第四章讨论。
到发现变量cl变成O为止,这段程序将循环四次。
变量cl的初值为Oxl0,在向左移动四次后,有1的位将变为0,变量cl的所有位的值将全为0。
像汇编语言执行一个位移指令一样,一个<<指令逐次将所有移动的值填上0。
(调“键盘”)。