单片机应用技术郭玲03第三章_第1页
单片机应用技术郭玲03第三章_第2页
单片机应用技术郭玲03第三章_第3页
单片机应用技术郭玲03第三章_第4页
单片机应用技术郭玲03第三章_第5页
已阅读5页,还剩60页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

单片机应用技术主讲老师:郭玲单位:广东水利电力职业技术学院第三章单片机C语言及八段数码管显示在上章我们学习了用汇编语言编写程序,并控制led灯点亮和闪烁。在这一章我们将学习使用C语言编写单片机程序。3.1示例3.2单片机C语言3.2.1Cx51的数据3.2.2变量和常量3.3练习3.3.1数码管静态显示3.3.2数码管动态显示3.1示例上一章,我们书写了控制led点亮的汇编程序该功能也可以使用C语言来完成令P1口清零令P1.1置1结束开始#include<REGX52.H>main() //主程序{P1=0x0; //P1口清零

P1_1=1; //P1.1被置1,led点亮

while(1);}3.1示例Led闪烁的C语言程序编写#include<REGX52.H>sbitLED=P1^0;voidDelay();voidmain(){while(1){LED=1;//led点亮

Delay(); //延时

LED=0; //led熄灭

Delay(); //延时}}voidDelay(){unsignedchari,j;for(i=0;i<255;i++)for(j=0;j<255;j++);}4思考从上面两个C语言的程序,我们发现了那些元素?宏定义函数赋值语句子程序调用循环语句运算比较语句3.2单片机的C语言支持单片机开发的除了汇编语言,还有C语言C语言是一种结构化语言,由函数{}构成。与汇编语言相比,C语言优势:寻址、寄存器分配可由编译器管理;程序有规范结构,可分为多个不同函数,使程序结构化,可读性强;关键字及运算函数可用近似人的思维方式使用;已编好的程序可容易地植入新程序,是模块化编程技术。单片机C语言简称为C51C51编译器编译器也叫编译程序,功能是将高级语言的源码翻译成为汇编语代码,如将.C的源文件编译成.ASM汇编文件,将.ASM汇编为.OBJ目标文件,同时输出单片机可执行HEX文件。8051系列单片机已经是工业标准,从1985年开始就有单片机的C语言编译器。最著名的是德国的KEIL公司发行的KEIL系列编译器,在市场上已经销售多年。

目前KEIL编译器已经开始支持16位、32位ARM的C语言编译。C51程序的构成C语言的程序是由一个或多个函数构成的,最简单的程序只有一个main函数。一个函数由两部份组成函数的首部、即函数的第一行;包括函数名、函数类型、函数属性、函数参数(形参)名、参数类型。

函数体,即函数首部下面的大括号“{}”内的部份。函数体一般包括:

声明部份:定义所用到的变量,如voidDelay()中的unsignedchari,j;。执行部份:由若干个语句组成。

标识符

C语言规定标识符只能由字母、数字和下划线三种字符组成,且第一个字符必须为字母或下划线。变量名、常数名、数组名、函数名、文件名与类型名等统称为标识符。标识符分为预定义标识符和用户标识符。说明:C语言中大写字母与小写字母被认为是两个不同的字符。标识符在命名时应当简单,含义清晰,这样有助于阅读理解程序。关键字

关键字则是编程语言保留的特殊标识符,它们具有固定名称和含义,在程序编写中不允许标识符与关键字相同。在KeilC中的关键字除了有ANSIC标准的32个关键字外,还根据51单片机的特点扩展了相关的关键字。在KeilC的文本编辑器中编写C程序,系统把保留字以不同颜色显示,缺省颜色为天蓝色。C语言基本语句(P52)

C语言的程序是由一个或多个函数组成的,而函数又是由若干个语句组成的。语句是由一些基本字符和定义符按照C语言的语法规定组成的,每个语句以分号结束,分号是C语句的必要组成部份。C语言的语句可分为以下5种类型:表达式语句函数调用语句控制语句空语句C51源程序的书写通常,一个语句占用一行;一个语句用分号“;”结束不同层次结构,从不同起始位置开始表达式语句表达式语句是由一个表达式加一个分号构成一个语句,其作用是计算表达式的值或改变变量的值。它的一般形式是:表达式;即在表达式末尾加上分号,就变成了表达式语句。最典型的表达式语句是:在赋值表达式后加一个分号构成赋值语句。例如:a=3是一个赋值表达式a=3;是一个赋值语句函数调用语句由一个函数调用加一个分号构成函数调用语句,其作用是完成特定的功能。它的一般形式是:函数名(参数列表);例如mDelay(100);//调用延时函数,参数是100

控制语句控制语句用于完成一定的控制功能,以实现程序的各种结构方式。C语言有9种控制语句,可分为以下三类。条件判断语句:if语句、switch语句。循环语句:for语句、while语句、do-while语句。转向语句:break语句、continue语句、goto语句、return语句。空语句只有一个分号的语句称为空语句。它的一般形式是:;空语句是什么操作也不执行,常用于作为循环语句中的循环体,表示循环体什么也不做。

注释

注释内容可以单独写在一行上,也可以写在一个语句之后;可以用/*…..*/的形式为C程序的任何一部份作注释;KeilC也支持C++风格的注释,就是用“//”引导的后面的语句是注释,例:

P1_0=!P1_0;//取反P1.0这种风格的注释,只对本行有效,书写比较方便,所以在只需要一行注释的时候,我们往往采用这种格式。C51中的函数分为两大类:库函数、用户自定义函数库函数:Cx51在库文件中已定义的函数,其函数说明在相关的头文件中。这类函数,用户在编程时只要用include预处理指令将头文件包含进来,直接调用即可。用户自定义函数:用户自己定义,自己调用的一类函数。从某种意义上来看,C编程实际上是对一系列用户函数的定义。函数的书写一个Cx51程序仅有一个main主函数,其它都是子程序函数。函数的书写类型函数名(参数表){

数据说明; 执行语句;}voidDelay(){unsignedchari,j;for(i=0;i<255;i++)for(j=0;j<255;j++);}程序的书写子函数可以在主函数的前面,也可以在主程序的后面,如在后面,在初始化声明中预先声明。头文件;初始化声明;类型函数名(参数表)//子函数{

数据说明; 执行语句;}类型函数名(参数表)//主函数{

数据说明; 执行语句;}#include<REGX52.H>sbitLED=P1^0;voidDelay();voidmain(){while(1){LED=1;//led点亮

Delay(); //延时

LED=0; //led熄灭

Delay(); //延时}}voidDelay(){unsignedchari,j;for(i=0;i<255;i++)for(j=0;j<255;j++);}#include<REGX52.H>sbitLED=P1^0;voidDelay(){unsignedchari,j;for(i=0;i<255;i++)for(j=0;j<255;j++);}voidmain(){while(1){LED=1;//led点亮

Delay(); //延时

LED=0; //led熄灭

Delay(); //延时

}}技能训练——8个led灯的循环点亮8个led灯共阴极接法P1口接发光二极管(LED)的阳极,P1口的管脚输出高电平时对应的发光二极管点亮。通过程序按一定的规律向P1口的管脚输出低电平和高电平,控制八只发光二极管循环点亮。LED循环点亮功能实现分析

由于LED循环点亮电路的LED是采用共阴极接法,这样我们就可以通过“1”和“0”来控制LED的亮和灭。例如:在P1口输出十六进制数0x01(二进制00000001B),D1被点亮。LED循环点亮功能实现过程如下:8个LED全灭,控制码为0x00;D1点亮,P1口输出0x01,(二进制00000001B),延时后;D2点亮,P1口输出0x02,(二进制00000010B),延时后;D3点亮,P1口输出0x03,(二进制00000100B),延时后;……D8点亮,P1口输出0x80,(二进制10000000B),延时后;重复第二步,这样就可以实现LED循环点亮。可以采用位左移语句,位左移规定将一个字节的位全部左移若干位,移位后,空白位补0,而溢出的位舍弃。如a=EAH,a<<28个LED循环电路程序(C语言)Voidmain(){unsignedchari;unsignedchartemp;P1=0x00;//十六进制全0,熄灭所有LEDwhile(1){temp=0x01;//第一位为1for(i=0;i<8;i++){P1=temp;//temp值取反送P1口

Delay();temp=temp<<1;//temp值左移一位

}}思考1.如何改变循环点亮的方向?2.C51程序中用到了延时程序,该延时无法估算具体时间量,请查阅相关资料,将前面书写的汇编延时模块嵌入到C51程序中。

关键字:C51嵌入汇编3.3.1Cx51数据(P101)一、数据类型数据的不同格式叫做数据类型。课本P101表15列出了Keil

uvison支持的数据类型。C51数据类型

P101表15数据类型长度数值范围unsignedchar1字节0~255signedchar1字节-128~+127unsignedint2字节0~65535signedint2字节-32768~+32767unsignedlong4字节0~4294967295signedlong4字节-2147483648~+2147483647float4字节±1.175494E-38~±3.402823E+38*1~3字节对象的地址bit位0或1sfr1字节0~255sfr162字节0~65535sbit位0或1举例unsignedchara=123;//1个字节7BHunsignedinta=123;//2个字节007BHunsignedlonga=123;//4个字节0000007BHC51基本数据类型

char字符类型长度是一个字节(8位)通常用于处理字符数据的变量或常量。分无符号字符类型unsignedchar和有符号字符类型signedchar默认值为signedcharunsignedchar表达范围:0~255signedchar最高位是符号位,补码形式,范围-128~127C51基本数据类型

int整型长度为两个字节(16位)

分有符号signedint和无符号unsignedint,默认值是signedintunsignedint表示的数值范围是0~65535signedint表示的数值范围是-32768~32767,补码形式C51基本数据类型

long长整型长度为四个字节(32位)signedlong,unsignedlong,默认为signedlongunsignedlong数值范围0~4294967295signedlong数值范围-2147483648~2147483647C51基本数据类型

float浮点型长度为四个字节(32位)会用即可*指针型指针型本身就是一个变量,在这个变量中存放的是指向另一个数据的地址。这个指针变量要占据一定的内存单元,在C51中它的长度一般为1~3个字节。

C51扩展的数据类型

bit位变量sfr特殊功能寄存器sfr1616位特殊功能寄存器sbit可寻址位bit位变量

bit位变量与MCS-51硬件特性操作有关位变量必须定位在MCS-51单片机内部RAM的位寻址空间中。但不能定义位指针,也不能定义位数组。bit位变量的值就是一个二进制位,不是0就是1,类似True和False。例如:bitflag;//flag为bit位变量,其值是0或1sfr特殊功能寄存器与标准C语言不兼容,只适用于对MCS-51系列单片机进行C语言编程。Sfr占用一个字节,数值范围为0~255。利用它可以访问51单片机内部的所有特殊功能寄存器。特殊功能寄存器C51定义的一般语法格式如下:

sfr

特殊功能寄存器名=特殊功能寄存器的字节地址;例如:

sfrP1=0x90;这一句定义了P1为P1端口在内部的寄存器。又如:

sfr

SCON=0x98;

//串口控制寄存器,地址为0x98

sfr

TMOD=0x89;

//定时器/计数器方式控制寄存器sfr1616位特殊功能寄存器sfr16占用两个字节。在许多新的MCS-51系列单片机中,有时会使用两个连续地址的特殊功能寄存器来指定一个16位的值。如52子系列的定时器/计数器2。为了有效地访问这类SFR,可使用关键字“sfr16”来定义,16位SFR定义语句的语法格式与8位SFR相同,只是“=”后面的地址必须用16位SFR的低字节地址,即低字节地址作为“sfr16”的定义地址。例如:

sfr16

T2=0xCC

//定时器/计数器2:T2低8位地址为0xCC,T2高8位地址为0xCDsbit可寻址位C51的扩充功能支持特殊位的定义,与SFR定义一样,关键字“sbit”用于定义某些特殊位,利用它可以访问芯内部部的RAM中的可寻址位或特殊功能寄存器中的可寻址位。如先前我们定义:

sfrP1=0x90;因P1端口的寄存器是可位寻址的,所以我们可以定义:

sbitP1_1=P1^1;

//P1_1为P1中的P1.1引脚这样我们在以后的程序语句中就可以用P1_1来对P1.1引脚进行读写操作了。在C语言里,由于P1.1不是一个合法的C语言变量名,得给它另起一个名字,这里起的名为P1_1,所以必须给它们建立联系,这里使用了C51的关键字sbit来定义sbit

的用法有三种格式第一种格式sbit

bitname=sfrname^intconstant;其中“bitname”是一个寻址位符号名,该位符号名必须是MCS-51单片机中规定的位名称;“sfrname”必须是已定义过的SFR的名字;“^”后的整常数是寻址位在特殊功能寄存器“sfrname”中的位号,必须是0~7范围中的数。例如:sfr

PSW=0xD0;

//定义PSW寄存器地址为0xD0sbit

OV=PSW^2;

//定义OV位为PSW.2,地址为0xD2sbit

CY=PSW^7;

//定义CY位为PSW.7,地址为0xD7sbit

的用法有三种格式第二种格式:sbit

bit-name=int

constant^intconstant;其中“=”后的intconstant为寻址地址位所在的特殊功能寄存器的字节地址;“^”符号后的intconstant为寻址位在特殊功能寄存器中的位号。例如:sbit

OV=0xD0^2;

//定义OV位地址是0xD0字节中的第2位sbit

CY=0xD0^7;

//定义CY位地址是0xD0字节中的第7位sbit

的用法有三种格式第三种格式:sbit

bit-name=intconstant;其中“=”后的intconstant为寻址位的绝对位地址。例如:sbit

OV=0xD2;

//定义OV位地址为0xD2sbit

CY=0xD7;

//定义CY位地址为0xD7

3.2.2C51中的常量与变量常量是在程序运行过程中不能改变的,而变量是可以在程序运行过程中不断变化的。变量的定义可以使用所有C51编译器支持的数据类型,而常量的数据类型只有整型、浮点型、字符型、字符串型和位变量。

常量常量是程序运行过程中不能改变值的量。如固定的数据表,字库等。常量的数据类型只有整型、浮点型、字符型、字符串型和位标量。整型常量,十进制123,十六进制0x123

浮点型常量,可分为十进制和指数形式。十进制由数字和小数点组成,如0.888,3345.345,0.0。指数可以表示为[±]数字[.数字]e[±]数字。125e3,7e9,-3.0e-3字符型常量,单引号,’a’,转义符位标量,它的值是一个二进制。常量常量的定义方式有几种,下面来加以说明。#difineFalse0x0;//用预定义语句可以定义常量#difineTrue0x1;//这里定义False为0,True为1程序中用到False和True,在编译时,False替换为0,True替换为1。unsignedint

codea=100;//用code把a定义在程序存储器中并赋值constunsignedintc=100;//用const定义c为无符号int常量并赋值

以上两句它们的值都保存在程序存储器中,而程序存储器在运行中是不允许被修改的,所以如果在这两句后面用了类似a=110,a++这样的赋值语句,编译时将会出错。变量变量就是一种在程序执行过程中其值能不断变化的。要在程序中使用变量必须先用标识符作为变量名,并指出所用的数据类型和存储模式,这样编译系统才能为变量分配相应的存储空间。定义一个变量的格式如下:[存储种类]数据类型[存储器类型]变量名表在定义格式中除了数据类型和变量名表是必要的,其它都是可选项。存储种类存储种类有四种自动(auto),缺省类型为自动(auto)外部(extern)静态(static)寄存器(register)

存储器类型存储器类型的说明就是指定该变量在C51硬件系统中所使用的存储区域,并在编译时准确的定位。存储器类型说明data直接访问内部数据存储器(128字节),访问速度最快bdata可位寻址内部数据存储器(16字节),允许位与字节混合访问idata间接访问内部数据存储器(256字节),允许访问全部内部地址pdata分页访问外部数据存储器(256字节),用MOVX@Ri指令访问xdata外部数据存储器(64KB),用MOVX@DPTR指令访问code程序存储器(64KB),用MOVC@A+DPTR指令访问存储模式

SMALL存储模式把所有函数变量和局部数据段放在8051系统的内部数据存储区,这使访问数据非常快。在写小型的应用程序时,变量和数据放在data内部数据存储器中是很好的,因为访问速度快;但在较大的应用程序中data区最好只存放小的变量、数据或常用的变量(如循环计数、数据索引),而大的数据则放置在别的存储区域。COMPACT存储模式中所有的函数和程序变量和局部数据段定位在8051系统的外部数据存储区,最多可有256字节。LARGE存储模式所有函数和过程的变量和局部数据段都定位在8051系统的外部数据区,最多可有64KB。存储种类和存储器类型完全无关。3.4练习——七段数码管显示数码管:多个led灯组成。ABCDEFGDP由多个发光二极管封装在一起组成“8”字型的器件,8字形有7个二极管,还有一个小数点也是led灯。可显示1,2,…,9A,b,C,d,E,F

数码管电路共阴数码管:将所有led的阴极都连接在一起片选片选共阳数码管:将所有led的阳极都连接在一起公共端做片选

数码管电路单个数码管——静态显示P83图73数码管显示代码表从高位到低位:Dp,G,F,E,D,C,B,A对应端口口线:bit7,6,5,4,3,2,1,0数字0-9的显示代码:P85表14共阴:3FH,06H,5BH,4FH,66H…共阳:0C0H,0F9H,0A4H,0B0H,99H….字符A-F的显示代码:共阴:77H,7CH,39H,5EH,79H,71H共阳:88H,83H,0C6H,0A1H,86H,8EH

数码管电路多个数码管模块,并联连接——动态显示P84图74四位共阴七段数码管电路每个数码管的同名波段输出引线连接在一起。有片选引线,通过“片选”选择数码管。四个数码管,片选端低电平时选中该数码管。P20P21P22P23

单个数码管静态显示程序设计举例:1、令一个(最右边)数码管显示数字。开始片选结束显示1#include<REGX51.H> main() { P2=0x0f; P2_0=0; P0=0x3f;//0x06;while(1);}

单个数码管静态显示程序设计举例:2、一个数码管(最右边)以0.5s间隔时间显示数字0-9.开始片选结束显示1延时。。。#include<REGX51.H> main() { P2=0x0f; P2_0=0; while(){P1=0x3f;delay(); P1=0x06;delay();…P1=0x6f;delay()}}

单个数码管静态显示程序设计要显示某个数字或字母时都要去查编码。将显示代码事先放置在ROM中,查表取数据(汇编中是DB指令)。单个数码管静态显示程序设计显示代码事先放置在ROM中C51语句编写unsignedcharcodetable[]={0x3f,

0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};上述语句定义了数据类型,存储器类型,以及数组table该数组里的每个元素都是usignedchar类型,且放置在ROM里。数组的地址与数组第1个元素的地址相同。每个元素地址顺序增加1,因为char类型占用1个字节。第1个元素table[0],第2个元素table[1],….单个数码管依次显示数字#include<REGX51.H>unsignedcharcodetable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};voiddelay(){ unsignedchari,j,k;

for(i=40;i>0;i--)

for(j=40;j>0;j--)

for(k=248;k>0;k--); }main(){ P2=0x0f;//0f; P2_0=0; while(1) { P1=table[0]; delay(); P1=table[1]; delay(); ... P1=table[9]; } } 作业1:开发板硬件电路调试调试开发板检查电路板,电源是否正常单片机晶振是否正常是否有漏焊、虚焊装载学院的WAVE软件,插上usb线,手动查找实验板的usb驱动,检查电路板usb通信是否正常。在学院的WAVE软件下点击“实验板测试程序”,下载测试程序,如果测试通过,说明电路板正常。同学之间可交换检查,如有失效零部件,向电子协会领取新的

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论