单片机c语言概述
高金鹏:男,银川科技学院计算机与人工智能学院,2022级别计算机科学与技术本科生,单片机原理及应用课程第六组。
指导教师:王兴泽
电子邮件:高金鹏3535558665@qq.com
个人****:暴躁的海绵宝宝 暴躁的海绵宝宝-****博客
单片机作为计算机科学与技术中的最重要的学科之一,****是有着极大的流量和专业人才的网站,故借此平台提高我的博客写作能力,并且提高对单片机原理和应用的了解更好的掌握这门学科。
本篇文章是参考《单片机原理及应用(c语言版)第2版》杨居易·编著编写的笔记
由海鹏、赵若晨、徐丽钧、开海洋共同完成此篇文章,其中海鹏负责程序开发概述与程序结构,徐丽钧负责标识符与关键字的内容,赵若晨负责数据类型的内容,开海洋负责C51数据的存储类型,高金鹏负责总结核对校验文档编写最后确认。
模块一程序设计与实践
项目一单片机C语言概述
- c51程序开发概述
单片机的C语言采用c51编译器(简称C51)。由C51产生的目标代码短、运行速度高、所需存储空间小、符合C语言的ANS标准生成的代码遵循lntel目标文件格式,而且可与A51汇编语言目标代码混合使用。
采用C51的优势:进行单片机应用系统的程序设计,编译能自动完成变量的存储单元的分配。
2.c51程序结构
与普通的C语言程序类似,C51程序是由若干模块化的函数构成。主程序(main())可以根据需要用来调用函数。当函数执行完毕时,就发出返回(return)指令,而主程序main()后面的指令来恢复主程序流的执行。同一个函数可以在不同的地方被调用,并且函数可以重复使用。
C语言程序的扩 C语言程序的扩展名为“.c”,如“practise-1.c”。一个C程序的执行总是从main()函数开始,调用其他函数后返回到main()中,最后在主函数main()中结束整个C程序的运行。
3.标识符与关键字
(1)标识符
C语言规定:标识符只能是字母(A~Z,a~z)、下划线“”和数字(0~9)组成的字符串,并要求首字符是字母或下划线,不能是数字。例如,可以使用x、y作为变量的标识符,使用delay()作为函数的标识符。字母的大小写是有区别的,如max和MAX是两个完全不同的标
识符。
(2)关键字
关键字是一种已被系统使用过的具有特定含义的标识符。用户不得再用关键字给变量等命名。C语言关键字分为如下三类:
①类型说明符:用来定义变量、函数或其他数据结构的类型,如unsigned char、int、long等。
②语句定义符:用来标识一个语句功能,如条件判断语句“i”、“while”等。
③预处理命令字:表示预处理命令的关键字,如程序开头的"include"。
由ANSIC标准定义了32个关键字,如表3-1所示。
表3-1 ANSIC语言的关键字 | ||
关键字 |
用途 |
说明 |
Auto |
存储种类说明 |
用以说明局部变量 |
break |
程序语句 |
推出最内层循环 |
case |
程序语句 |
Switch语句中的选择项 |
char |
数据类型说明 |
单字节整型数或字符型数据 |
const |
存储种类说明 |
在程序执行过程中不可更改的常量值 |
continue |
程序语句 |
转向下一次循环 |
default |
程序语句 |
Switch语句中的失败选择项目 |
do |
程序语句 |
构成do…while循环结构 |
double |
数据类型说明 |
双精度浮点数 |
else |
程序语句 |
构成if…else选择结构 |
enum |
数据类型说明 |
枚举类型 |
extern |
存储种类说明 |
在其他程序模块中说明了的全局变量 |
float |
数据类型说明 |
单精度浮点数 |
for |
程序语句 |
构成for循环结构构成got |
goto |
程序语句 |
构成got转移结构 |
if |
程序语句 |
构成if…else选择结构 |
int |
数据类型说明 |
基本整型数 |
long |
数据类型说明 |
长整型数 |
register |
存储种类说明 |
使用CPU内部寄存器的变量 |
return |
程序语句 |
函数返回 |
short |
数据类型说明 |
短整型数 |
signed |
数据类型说明 |
有符号数,二进制数据的最高位为符号位 |
sizeof |
运算符 |
计算表达式或数据类型的字节数。 |
static |
存储种类说明 |
静态变量 |
struct |
数据类型说明 |
结构类型数据 |
switch |
程序语句 |
构成Switch选择结构 |
typedef |
数据类型说明 |
重新进行数据类型定义 |
union |
数据类型说明 |
联合类型数据 |
Unsigned |
数据类型说明 |
无符号数数据 |
void |
数据类型说明 |
无类型数据 |
volatile |
数据类型说明 |
该变量在程序执行中可被隐含地改变 |
while |
程序语句 |
构成while和do…while循环结构。 |
另外51单片机还扩展了相应的关键字。表3-2为Keil C51编译器扩展的关键字。
关键字 |
用途 |
说明 |
bit |
为标量声明 |
声明一个位标量或位类型的函数 |
sbit |
为变量声明 |
声明一个可位寻址变量 |
sfr |
特殊功能寄存器声明 |
声明一个特殊功能寄存器(8)位 |
sfr16 |
特殊功能寄存器声明 |
声明一个16位的特殊功能寄存器 |
data |
存储器类型说明 |
直接寻址的8051内部数据存储器 |
bdata |
存储器类型说明 |
可位寻址的8051内部数据存储器 |
idata |
存储器类型说明 |
简洁寻址的8051内部数据存储器 |
pdata |
存储器类型说明 |
“分页”寻址的8051外部数据存储器 |
xdata |
存储器类型说明 |
8051外部数据存储器 |
code |
存储器类型说明 |
8051程序存储器 |
Interrupt |
中断函数声明 |
定义一个中断函数 |
reetrant |
再入函数声明 |
定义一个再入函数 |
using |
寄存器组定义 |
定义8051的工作寄存器组 |
例如:
sfr P1=0x90;/*定义地址为“0x90”的特殊功能寄存器名字为“P1”,对P1的操作也就是对地址为0x90的寄存器操作*1。(格式:sfr特殊功能寄存器名=地址常数)
sbit S=P2^0;//位定义S为P2.0(P2口的第0位)。(格式:sbit 位变量名=特殊功能寄存器名^位位置)。
4.数据类型
数据的不同格式叫数据类型。C语言中常用的数据类型有整型、字符型、实型、指针型和空类型。而根据变量在程序执行中是否发生变化,还可将数据类型分为常量和变量两种。在程序中,常量可以不经说明而直接引用,而变量则必须先定义类型后才能使用。
1常量与变量
在程序运行过程中,其值不能被改变的量称为常量。常量区分为不同的类型,如10、0-4为整型常量,
2.6、-3.15为实型常量,a'、'd'为字符常量。
C语言中还有一种符号常量,其定义形式如下:
#define符号常量的标识符 常量
例如:
# define price 30
main()
{
int a,s;
a=10;
s=a * price;
printf("total=%d",total);
}
程序中用#define命令行定义price代表常量30,此后凡在本文中出现的price都代表30,它可以与常量一样运算。
2整型数据
整型数据包括整型常量和整型变量。
(1)整型常量
整型常量就是整型常数。在C语言中,整型常量可用以下三种形式表示:
- 十进制整数。用0~9表示,如321,-106等。
- 八进制整数。以0开头的数是八进制数,用0~~7表示。如0215表示八进制数215,即等于十进制数141。
- 十六进制整数。以0x开头的数是十六进制数,用0~9和A~
F表示。如0xff代表十六进制数FF,等于十进制数255。
(2)整型变量
整型变量可分为基本型和无符号型,基本型类型说明符为int,在内存中占2个字节;无符号型类型说明符为unsigned,同样在内存中占2个字节。
KeilC51软件编译器支持的数据类型如表3-3所示。
数据类型 |
长度 |
取值范围 |
|
字符型 |
signed char |
8 |
-128~127 |
unsigned char |
8 |
0~255 |
|
整型 |
signed int |
16 |
-32768~32767 |
unsigned int |
16 |
0~65535 |
|
长整型 |
signed long |
32 |
-21474883648~21474883647 |
unsigned Iong |
32 |
0~4294967295 |
|
浮点型 |
float |
32 |
±1.75494E-38~±3.402823E+38 |
位型 |
bit |
1 |
0,1 |
sbit |
1 |
0,1 |
|
访问SFR |
sfr |
8 |
0~255 |
Sfr16 |
16 |
0~65535 |
(3)实型数据
实型数据有两种表示形式:(本书没有用到,不介绍)
(4)字符型数据
字符型数据包括字符型常量和字符型变量。
- 字符型常量
字符常量是用单引号括起来的一个字符。如‘a',‘x', ‘d',“?”,‘等都是字符常量。字符型常量常用作显示说明
② 字符型变量
字符型变量用来存放字符常量,只能放一个字符,其说明符是“char”,长度是1个字节,定义形式为:
char x,y;/*它表示x和y为字符型变量,在内存中各占一个字节*/
unsigned char 与signed char型数据的区别是有无符号位,unsigned无符号位的数值范围是0~255; signed有符号位的数值范围是-128~127。
③ 字符串常量
是一对双引号括起来的字符序列。
例如:
“Welcome to China.";/是字符串常量
‘a';//是字符常量
(5) 指针型数据
有时在程序中围绕变量的地址展开操作,这就引入“指针”的概念。变量的地址称为变量的指针,指针即是地址。
(6) 位类型数据
位类型数据是C51编译器的一种扩充数据类型,利用它可以定义一个位变量,但不能定义位指针,也不能定义位数组。该类型数据取值为“0”或“1”。
(7)空类型数据
C语言经常使用函数,当函数被调用完后,无需返回一个函数值,这个函数值称为空类型数据,例如:
****************************************
函数功能:用整型型数据延时一段长时间
void delay()/*用“void”说明该函数为“空类型”即无返回值,
void的字面意思是“无类型”*/
unsigned int i; /*定义无符号整数,最大取值范围65535*/
for(i=0;i<50000;i++)//做50000次空循环Ⅱ/什么也不做,等待一个机器周期
(8)变量赋值
程序中常需要对一些变量预先赋值。C语言允许在定义变量的同时给变量赋值。
如:
int a=3;*指定a为整型变量,值为3*/float f=3.56;/*指定f为实型变量,值为3.56*/char c='a';/*指定c为字符变量,值为'a'*/也可以使被定义的变量的一部分赋值。如:int a, b, c=5;
表示指定a、b、c为整型变量,只对c赋值,c的值为5。
5.C51数据的存储类型
对于80C51系列单片机来说,访问片内的RAM比访问片外的RAM的速度要快得多,所以对于经常使用的变量应该置于片内RAM,即用bdata、data、idata来定义;对于不常使用的变量或规模较大的变量应该置于片外RAM中,即用pdata、xdata来定义。
例如:
bit bdata my_flag;/*位变量my_flag被定义为bdata存储类型C51编译器将把该变量定义在80C51片内数据存储区(RAM)中的位寻址区(地址:20H~2FH)*/
6.80C51硬件结构的C51
C51是适合于80C51单片机的C语言。它对标准C语言进行扩展,从而具有对80C51单片机硬件结构的良好支持与操作能力。
(1)特殊功能寄存器的定义。
80C51单片机内部RAM的80H~FFH区域有21个特殊功能寄存器,为了对它们能够直接访问,C51编译器利用扩充的关键字SFR和SFR16对这些特殊功能寄存器进行定义。
特殊功能寄存器的定义形式如下:
sfr特殊功能寄存器=地址常数
例如:
sfr P0=0x80; /*定义P0口,地址为0x80*/
sfr TMOD=0x89 /*定时器/计数器方式控制寄存器地址 89H*/
(2)特殊功能寄存器中特定位的定义
在C51中可以利用关键字sbit定义可独立寻址访问的位变量,如定义80C51单片机特
殊功能寄存器中的一些特定位。定义的形式如下。
第一种形式。
Sbit 位变量名=特殊功能寄存器名^位的位置(0~7);
例如:
sfr PSW=0xDD; /*定义PSW寄存器地址为0Xd0h*/
sbit ov=PSW^2 /*定义OV位为PSW.2,地址为0xd2*/
sbit ov=PSW^7 /*定义CY位为PSW.7,地址为0xd7*/
第二种形式
sbit 位变量名=字节地址^位的位置;
例如:
sbit OV=0xd0^2; /*定义OV位的地址为0Xd2*/
sbit CF =0xd0^7; /*定义CF 位的地址为0xd7*/
第三种形式
sbit 位变量名=位地址
例如:
sbit OV=0xd02; /*定义OV位的地址为0Xd2*/
sbit CF =0xd07; /*定义OV位的地址为0Xd7*/
(3)80C51并行口及其C51定义
(1)对于80C51片内I/O用关键字sfr 来定义。
例如:
sfr P0=0x80; /*定义P0口,地址位80h*/
sfr P1=0x90; /*定义P1口,地址位90h*/
(2)对于片外扩展I/O口,则根据其硬件译码地址,将其视为片外数据存储器的一个单元,使用define语句进行定义。
例如:
#including<absacc.h>
#def ine PORTA XBYTE [0x78f0]; /*将PORTA定义位外部口,地址为78F0,长度为8位*/
一旦在头文件或程序中这些片内外的I/O进行定义以后,在程序中就可以*使用这些端口了。定义口地址是为了便于C51编译器按 80C51实际硬件结构建立V/O口变量名与其实际地址的联系,以便程序员能用软件模拟80C51硬件操作。
7.位变量(bit)及其定义
C51编译器支持位数据类型,具体说明如下:
(1)位变量的C51定义语法及语义。
bit dir_bit; /*将dir_bit定义为位变量*/
bit lock_bit; /*将lock_bit定义为位变量*/
(2)函数可包含类型为bit的参数,也可以将其作为返回值。
bit func(bit b0,bit b1)
{/*...*/}
return(b1);
(3)对位定义的限制。位变量不能定义成一个指针,如bit ※bit_ptr 是非法的。不存在位数组,如不能定义bit arr[ ]。
在位定义中允许定义存储类型,位变量都放在一个段位中,此段总位于80C51片内RAM中,因此存储类型限制为data或idata。如果将位变量的存储类型定义成其他类型,编译时将出错。
(4)可位寻址对象。可位寻址对象是指可以字节寻址或位寻址的对象。该对象位于80C51片内RAM可位寻址RAM区中,C51编译器允许数据类型为idata的对象放入80C51片内可位寻址的区中。先定义变量的数据类型和存储类型:
bdata int ibase; /*定义ibase为bdata整型变量*/
bdata char bary[4]; /*定义bary[4]为bdata字符型数组*/
然后可使用sbit定义可独立寻址访问的对象位,即:
sbit mybit0 = ibase^0; /*mybit0定义为ibase的第0位*/
sbit mybit15= ibase^15; /*mybit15定义为ibase的第15位※/
sbit ary01= bary[0]^1; /*ary01定义为bary[0]的第1位*/
sbit ary25= bary[2]^5; /*ary25定义为bary[2]的第5位*/