单片机原理及应用笔记:单片机的结构原理与项目实践

时间:2024-10-16 16:04:25

单片机c语言概述

高金鹏:男,银川科技学院计算机与人工智能学院,2022级别计算机科学与技术本科生,单片机原理及应用课程第六组。

指导教师:王兴泽

电子邮件:高金鹏3535558665@qq.com

个人****:暴躁的海绵宝宝  暴躁的海绵宝宝-****博客 

单片机作为计算机科学与技术中的最重要的学科之一,****是有着极大的流量和专业人才的网站,故借此平台提高我的博客写作能力,并且提高对单片机原理和应用的了解更好的掌握这门学科。

本篇文章是参考《单片机原理及应用(c语言版)第2版》杨居易·编著编写的笔记

由海鹏、赵若晨、徐丽钧、开海洋共同完成此篇文章,其中海鹏负责程序开发概述与程序结构,徐丽钧负责标识符与关键字的内容,赵若晨负责数据类型的内容,开海洋负责C51数据的存储类型,高金鹏负责总结核对校验文档编写最后确认。

模块一程序设计与实践

项目一单片机C语言概述

  1. 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位*/