51单片机C语言学习之道(语法函数Keil工具及项目实战)/清华开发者书库
出版时间 2018-02-01T00:00
C++
46078
作者:
编者:孙鹏
出版社:
清华大学
原售价:
49.00
折扣价:
37.24
折扣购买:
51单片机C语言学习之道(语法函数Keil工具及项目实战)/清华开发者书库
ISBN:
9787302490890
作者简介
无
内容简介
第3章单片机C语言开发基础
1.7节已经介绍了C语言的结构、数据类型、运算符、函数,本章将主要通过C语言编程控制学习板上的流水灯,学习如何灵活运用C语言中的运算符、控制语句、数组、指针、预处理。本章内容可以说是对C51知识点的一个完整总结,内容较多,初学者全面掌握有一定难度。初学者对其中一些知识点可做简单了解,在后续章节的学习中再结合具体应用,以加深理解。
3.1运算符的应用
C语言中的运算符主要包括: 算术运算符、关系运算符、逻辑运算符、赋值运算符等。以下就是几个应用运算符来编程的实例。
【例31】用单片机实现乘法78×18的运算,并通过P2口的发光二极管分时显示结果的高八位和低八位状态。
分析: 先设置两个字符型变量i和j,将它们分别赋值为78和18,可以先计算它们相乘的结果为1404,等于十六进制数0x057C,在程序中用变量s保存它们相乘的这个结果。因为i和j的值小于255,所以用字符型变量保存即可; 变量s的值大于255并小于65535,所以必须保存为整型变量。相乘的十六位结果在八位并口P2上显示,只能把它拆成高八位和低八位分别显示,显示时,为区别高八位和低八位,它们中间让发光二极管全灭,并停顿1s。变量s高八位的二进制数是0000 0101B,因为发光二极管的状态是并口为高时熄灭,所以高八位送显示时,将有最低位、倒数第二位的灯熄灭,其他灯亮; 变量s低八位的二进制数是0111 1100B,当高八位送显示时,将有最高位、最低位两位灯亮,其他灯熄灭。我们可以把以下程序下载到学习板,观察显示状态是否正确。
#include
#define uint unsigned int //宏定义
#define uchar unsigned char
delay()
{
uint m,n;
for(m=1000;m>0;m--)
for(n=110;n>0;n--);
}
void main()
{
uint s;//保存乘法结果
uchar i,j; //保存相乘的因数
i=78;
j=18;
s=i*j;
while(1)
{
P2=s/256; //取乘积的高八位送P2口显示
delay();
P2=0xff;
delay();
P2=s%256; //取乘积的低八位送P2口显示
delay();
}
}
程序中用指令“P2=s/256”取变量s的高八位送显示,指令右面的算式变量s除以256后取整,所以P2得到的是乘积的高八位。而用指令P2=s%256取变量s的低八位送显示,符号“%”表示取s和256相除的余数,即变量s的低八位。通过这个例子,我们练习了除法和取余运算的用法。如果修改程序中i和j所赋的初值,还可以得到其他情况下乘法运算的结果。
这个程序里用到了宏定义,宏定义的格式为:
#define 新名称 原内容
#define命令的作用是: 用“新名称”代替后面的“原内容”,一般用于“原内容”比较长,又在程序里反复用到的情况。这样如果在程序中出现“原内容”,就可以用一个比较简短的“新名称”代替,使程序的书写更加简化。例如,本例在程序开始已经做了宏定义“#define uint unsigned int”,在此宏定义的后面,所有应该写unsigned int的地方,都用uint代替了。同一个程序中,宏定义对一个内容只能定义一次。
【例32】用16个发光二极管显示除法运算结果。
在学习板上除了P2口接的8个发光二极管以外,P3口利用串并转换接口芯片74HC595也扩展了8个发光二极管。电路如图31所示。
其中,芯片74HC595是八位串行输入转并行输出移位寄存器。引脚SER(14)是串行移位输入引脚,串行数据从低位到高位在该引脚输入; 引脚SRCLK(11)移位时钟输入引脚,该引脚的上升沿可以使14脚的数据输入芯片内,即该引脚的上升沿控制数据串行移入; 引脚RCLK(12)并行输出时钟端,通常情况下该引脚保持低电平,当串行数据移入完成时,
图31发光二极管硬件驱动电路图注: 接地符号与软件界面截图保持一致,全书同。
该引脚产生一个上升沿,将刚才移入的数据在QA~QH端并行输出。由74HC595的工作原理可见,仅用了这一个芯片,就可以只占用单片机的3个I/O口(即P3.4~P3.6)来驱动8个发光二极管,大大节约了硬件资源。感兴趣的读者可以把例31中乘法运算的程序修改一下,结果在图31的16位发光二极管上显示出来。
假设本例中除法运算为“10÷6”结果只保留一位小数,结果中整数部分可以在P2口的发光二极管上显示,结果中,小数部分在74HC595扩展的发光二极管上显示。程序如下:
#include
#define uint unsigned int
#define uchar unsigned char
sbit data1=P3^4; //定义74HC595中用到的几个口
sbit iclk=P3^6;
sbit oclk=P3^5;
uchar i,j,k,m;
void delay()
{
uint a,b;
for(a=10;a>0;a--)
for(b=110;b>0;b--);
}
void xianshi(uchar m) //74HC595显示子程序
{
uchar n;
n=m; //要显示的数存放在n里
oclk=0;
iclk=0;
for(j=8;j>0;j--) //要显示的数左移串行输入
{
n=n<<1;
data1=CY;
iclk=1;
delay();
iclk=0;
}
oclk=1;//移位完成并行输出
delay();
oclk=0;
}
void main()
{
i=10; //被除数和除数赋给i和j
j=6;
P2=i/j;
k=((i%j)*10)/j; //小数位保存在k中
xianshi(k);//调用显示子程序
while(1);
}
这个程序主要用到了74HC595的显示驱动函数,命名为“xianshi()”,它的形参为m,即要送D9~D16显示的数据。在这个子函数里,首先定义了一个无符号字符型变量n,用来存放要显示的数,然后将74HC595的串行输入时钟和并行输出时钟都置为低电平。再开始串行输入: n左移一位,移出的位移到了CY里,再把CY的值(第一次移位是显示数据最高位)给74HC595串行数据输入端,再将串行输入时钟置高电平,该时钟原来为低电平,因此在该引脚形成了一个上升沿,将串行数据输入端的当前值移入74HC595,再延时将时钟端置低。串行数据输入的过程要反复移位8次,才能将要显示的八位二进制数全部移入,这里用了一个for循环,控制移位一共进行8次。当跳出循环时移位完成,此时需要将八位二进制数并行输出,输出通过并行输出时钟控制: 并行输出时钟原值为低电平,现在置为高电平,形成一个上升沿,这个上升沿控制74HC595将刚才移入的数据并行由QA~QH输出。输出完成后,再将输出时钟端置为低电平,为下一次显示做准备。
主程序里先将被除数和除数分别赋值给i和j,然后将i和j相除的结果取整后直接赋值给P2口,这是商的整数部分。小数部分的计算方法为: 先将i和j相除后取余数,再扩大10倍,再用除数除后取整,这样计算得到的小数部分只有小数点后的第一位,再调用74HC595的显示子函数,在发光二极管D9~D16显示这个小数位。发光二极管熄灭表示1,点亮表示0,通过观察学习板上发光二极管的亮灭状态,即可知道除数运算的结果。
上述方法在单片机控制小数点的显示时非常有用。也可以把本例中被除数和除数的值变化一下,观察发光二极管的状态有什么变化。另外,读者也可以考虑: 如果想显示更多的小数位时,程序应如何编写。
【例33】用自增、自减运算控制P2口的流水灯。
如果对变量i执行自增运算时写成“i++”,执行完i的值被加1; 对变量i执行自减运算时写成“i--”,执行完变量i的值被减1。这两个运算符主要用在for循环的表达式里,用来修改循环指针。
#include
void delay() //延时1s子程序
{
unsigned int i,j;
for(i=1000;i>0;i--)
for(j=110;j>0;j--);
}
void main()
{
unsigned char m,n;
while(1)
{
for(m=0;m<10;m++) //m从0到9自增1,状态从P2输出
{
P2=m;
delay();
}
for(n=10;n>0;n--) //n从10到1自减1,状态从P2输出
{
P2=n;
delay();
}
}
}
这个程序可以实现P2口的流水灯按一定规律变化。端口P2驱动的发光二极管在端口数据为1时,灯灭,在数据为0时,灯亮,亮灭规律都是按照二进制数的形式变化。程序中两个for循环使P2口输出数据按从0到10、再从10到0的规则循环变化,相应的发光二极管也按这个规律点亮或熄灭。从观察P2口灯亮灭状态的变化,就可以知道自增和自减指令的功能了。
3.2C语言的语句
一个完整的C程序是由若干条C语句按一定的方式组合而成的。按C语句执行方式的不同,C程序可分为顺序结构、选择结构和循环结构。
顺序结构: 指程序按语句的顺序逐条执行。
选择结构: 指程序根据条件选择相应的执行顺序。
循环结构: 指程序根据某条件的存在重复执行一段程序,直到这个条件不满足为止。如果这个条件永远存在,就会形成死循环。
一般的C程序都是由上述三种结构混合而成的。但要保证C程序能够按照预期的意图运行,还要用到以下5类语句来对程序进行控制。
1. 控制语句
控制语句完成一定的控制功能,C语言中有9种控制语句。
if…else: 条件语句;
for: 循环语句;
while: 循环语句;
do…while: 循环语句;
continue: 结束本次循环语句;
break: 终止执行循环语句;
switch: 多分支选择语句;
goto: 跳转语句;
return: 从函数返回语句。
2. 函数调用语句
调用已定义过的函数,例如延时函数。
3. 表达式语句
由一个表达式和一个分号构成,示例如下:
z=x+y;
《51单片机C语言学习之道》体系完善、循序渐进、深入浅出,从最简单的编程实例入手,通过大量具有代表性的实例讲述了51单片机C语言编程方法、硬件结构及应用。共分三篇:入门篇、应用篇、综合篇。入门篇主要讲解单片机的基础知识、C语言调试软件Keil的使用方法、C51函数的用法。应用篇讲解了定时计数器和中断的用法,并介绍了一些常用器件的驱动。综合篇则结合一些生产和生活的实例,介绍了一些实际应用中的单片机系统软硬件设计方法。




