单片机控制技术配套实验程序.docx

上传人:b****8 文档编号:10650774 上传时间:2023-02-22 格式:DOCX 页数:188 大小:696.63KB
下载 相关 举报
单片机控制技术配套实验程序.docx_第1页
第1页 / 共188页
单片机控制技术配套实验程序.docx_第2页
第2页 / 共188页
单片机控制技术配套实验程序.docx_第3页
第3页 / 共188页
单片机控制技术配套实验程序.docx_第4页
第4页 / 共188页
单片机控制技术配套实验程序.docx_第5页
第5页 / 共188页
点击查看更多>>
下载资源
资源描述

单片机控制技术配套实验程序.docx

《单片机控制技术配套实验程序.docx》由会员分享,可在线阅读,更多相关《单片机控制技术配套实验程序.docx(188页珍藏版)》请在冰豆网上搜索。

单片机控制技术配套实验程序.docx

单片机控制技术配套实验程序

单片机控制技术配套实验程序

数据类型

C语言的数据结构是以数据类型出现的,数据类型可分为基本数据型和复杂数据类型,复杂数据类型由基本数据类型构造而成。

C语言中的基本数据类型有char、int、short、long、float和double六种。

对于C51编译器来说,short类型与int类型相同,double类型与float类型相同。

#include//预处理命令

voidmain(void)//主函数名

{

unsignedinta;//定义变量a为unsignedint类型

unsignedcharb;//定义变量b为unsignedchar类型

do

{//dowhile组成循环

for(a=0;a<65535;a++)

P1_0=0;//65535次设P1.0口为低电平,点亮LED

P1_0=1;//设P1.0口为高电平,熄灭LED

for(a=0;a<30000;a++);//空循环

for(b=0;b<255;b++)

P1_1=0;//255次设P1.1口为低电平,点亮LED

P1_1=1;//设P1.1口为高电平,熄灭LED

for(a=0;a<30000;a++);//空循环

}

while

(1);

}

bit位标量

bit位标量是C51编译器的一种扩充数据类型,利用它可定义一个位标量,但不能定义位指针,也不能定义位数组。

它的值是一个二进制位,不是0就是1,类似一些高级语言中的Boolean类型中的True和False。

7.sfr特殊功能寄存器

sfr也是一种扩充数据类型,占用一个内存单元,值域为0~255。

利用它可以访问51单片机内部的所有特殊功能寄存器。

如用sfrP1=0x90这一句定P1为P1端口在片内的寄存器,在后面的语句中我们用以用P1=255(对P1端口的所有引脚置高电平)之类的语句来操作特殊功能寄存器。

8.sfr1616位特殊功能寄存器

sfr16占用两个内存单元,值域为0~65535。

sfr16和sfr一样用于操作特殊功能寄存器,所不同的是它用于操作占两个字节的寄存器,如定时器T0和T1。

9.sbit可录址位

sbit同样是C51中的一种扩充数据类型,利用它可以访问芯片内部的RAM中的可寻址位或特殊功能寄存器中的可寻址位。

如先前我们定义了

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

sbitP1_1=P1^1; //P1_1为P1中的P1.1引脚

//同样我们可以用P1.1的地址去写,如sbitP1_1=0x91;

这样我们在以后的程序语句中就可以用P1_1来对P1.1引脚进行读写操作了。

通常这些可以直接使用系统提供的预处理文件,里面已定义好各特殊功能寄存器的简单名字,直接引用可以省去一点时间,我自己是一直用的。

当然您也可以自己写自己的定义文件,用您认为好记的名字。

sfrP1=0x90;//这里没有使用预定义文件,

sbitP1_0=P1^0;//而是自己定义特殊寄存器

sbitP1_7=0x90^7;//之前我们使用的预定义文件其实就是这个作用

sbitP1_1=0x91;//这里分别定义P1端口和P10,P11,P17引脚

voidmain(void)

{

unsignedinta;

unsignedcharb;

do{

for(a=0;a<50000;a++)

P1_0=0;//点亮P1_0

for(a=0;a<50000;a++)

P1_7=0;//点亮P1_7

for(b=0;b<255;b++)

{

for(a=0;a<10000;a++)

P1=b;//用b的值来做跑马灯的花样

}

P1=255;//熄灭P1上的LED

for(b=0;b<255;b++)

{

for(a=0;a<10000;a++)//P1_1闪烁

P1_1=0;

for(a=0;a<10000;a++)

P1_1=1;

}

}while

(1);

}

常量

常量又称为标量,它的值在程序执行过程中不能改变。

常量的数据类型有整型、浮点型、字符型和字符串型等

#include//预处理文件里面定义了特殊寄存器的名称如P1口定义为P1

voidmain(void)

{

//定义花样数据

unsignedchardesign[32]={0xFF,0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F,

0x7F,0xBF,0xDF,0xEF,0xF7,0xFB,0xFD,0xFE,0xFF,

0xFF,0xFE,0xFC,0xF8,0xF0,0xE0,0xC0,0x80,0x0,

0xE7,0xDB,0xBD,0x7E,0xFF};

unsignedinta;//定义循环用的变量

unsignedcharb;//在C51编程中因内存有限尽可能注意变量类型的使用

//尽可能使用少字节的类型,在大型的程序中很受用

do{

for(b=0;b<32;b++)

{

for(a=0;a<30000;a++);//延时一段时间

P1=design[b];//读已定义的花样数据并写花样数据到P1口

}

}while

(1);

}

运算符与表达式

条件语句

条件语句又称为分支语句,是用关键字if构成的。

C语言提供了三种形式的条件语句:

①.if(条件表达式)语句

其含义为:

若条件表达式的结果为真(非0值),就执行后面的语句;反之,就不执行后面的语句。

这里的语句也可以是复合语句。

②.if(条件表达式)语句1

else语句2

其含义为:

若条件表达式的结果为真(非0值),就执行语句1;反之,就执行语句2。

这里的语句1和语句2均可以是复合语句。

#include

sbitK1=P3^0;

sbitL1=P1^0;

 

voidmain(void)

{

while

(1)

{

if(K1==0)

{

L1=0;//灯亮

}

else

{

L1=1;//灯灭

}

}

}

开关语句

开关语句也是一种用来实现多方向条件分支的语句。

虽然采用条件语句也可以实现多方向条件分支,但是当分支较多时,会使条件语句的嵌套层次太多,程序冗长,可读性降低。

开关语句直接处理多分支选择,使程序结构清晰,使用方便。

开关语句是用关键字switch构成的,一般形式如下:

switch(表达式)

{

case常量表达式1:

语句1

break;

case常量表达式2:

语句2

break;

……

case常量表达式n:

语句n

break;

default:

语句d

}

开关SP1接在P3.7/RD管脚上,在AT89S51单片机的P1端口接有四个发光二极管,上电的时候,L1接在P1.0管脚上的发光二极管在闪烁,当每一次按下开关SP1的时候,L2接在P1.1管脚上的发光二极管在闪烁,再按下开关SP1的时候,L3接在P1.2管脚上的发光二极管在闪烁,再按下开关SP1的时候,L4接在P1.3管脚上的发光二极管在闪烁,再按下开关SP1的时候,又轮到L1在闪烁了,如此轮流下去。

#include

unsignedcharID;

voiddelay10ms(void)

{

unsignedchari,j;

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

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

}

 

voiddelay02s(void)

{

unsignedchari;

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

{delay10ms();

}

}

 

voidmain(void)

{while

(1)

{if(P3_7==0)

{delay10ms();

if(P3_7==0)

{

ID++;

if(ID==4)

{

ID=0;

}

while(P3_7==0);

}

}

switch(ID)

{case0:

P1_0=~P1_0;

delay02s();

break;

case1:

P1_1=~P1_1;

delay02s();

break;

case2:

P1_2=~P1_2;

delay02s();

break;

case3:

P1_3=~P1_3;

delay02s();

break;

}

}

函数的定义

从用户的角度来看,有两种函数:

标准库函数和用户自定义函数。

标准库函数是C51编译器提供的,不需要用户进行定义,可以直接调用。

用户自定义函数是用户根据自己需要编写的能实现特定功能的函数,必须先定义之后才能调用

#include

sbitL1=P1^0;

 

voiddelay02s(void)//延时0.2秒子程序

{

unsignedchari,j,k;

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

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

for(k=248;k>0;k--);

}

 

 

voidmain(void)

{

while

(1)

{

L1=0;

delay02s();

L1=1;

delay02s();

}

}

多路开关状态指示

 

#include

unsignedchartemp;

 

voidmain(void)

{

while

(1)

{

temp=P1>>4;

temp=temp|0xf0;

P1=temp;

}

}

#include

 

voidmain(void)

{

while

(1)

{

if(P1_4==0)

{

P1_0=0;

}

else

{

P1_0=1;

}

if(P1_5==0)

{

P1_1=0;

}

else

{

P1_1=1;

}

if(P1_6==0)

{

P1_2=0;

}

else

{

P1_2=1;

}

if(P1_7==0)

{

P1_3=0;

}

else

{

P1_3=1;

}

}

}

广告灯的左移右移

#include

unsignedchari;

unsignedchartemp;

unsignedchara,b;

 

voiddelay(void)

{

unsignedcharm,n,s;

for(m=20;m>0;m--)

for(n=20;n>0;n--)

for(s=248;s>0;s--);

}

voidmain(void)

{

while

(1)

{

temp=0xfe;

P1=temp;

delay();

for(i=1;i<8;i++)

{

a=temp<

b=temp>>(8-i);

P1=a|b;

delay();

}

for(i=1;i<8;i++)

{

a=temp>>i;

b=temp<<(8-i);

P1=a|b;

delay();

}

}

}

广告灯(利用取表方式)

1.     实验任务

利用取表的方法,使端口P1做单一灯的变化:

左移2次,右移2次,闪烁2次(延时的时间0.2秒)。

#include

unsignedcharcodetable[]={0xfe,0xfd,0xfb,0xf7,

0xef,0xdf,0xbf,0x7f,

0xfe,0xfd,0xfb,0xf7,

0xef,0xdf,0xbf,0x7f,

0x7f,0xbf,0xdf,0xef,

0xf7,0xfb,0xfd,0xfe,

0x7f,0xbf,0xdf,0xef,

0xf7,0xfb,0xfd,0xfe,

0x00,0xff,0x00,0xff,

0x01};

unsignedchari;

 

voiddelay(void)

{

unsignedcharm,n,s;

for(m=20;m>0;m--)

for(n=20;n>0;n--)

for(s=248;s>0;s--);

}

 

voidmain(void)

{

while

(1)

{

if(table[i]!

=0x01)

{

P1=table[i];

i++;

delay();

}

else

{

i=0;

}

}

}

报警产生器

1.实验任务

用P1.0输出bHz和500Hz的音频信号驱动扬声器,作报警信号,要求1KHz信号响100ms,500Hz信号响200ms,交替进行,P1.7接一开关进行控制,当开关合上响报警信号,当开关断开告警信号停止,编出程序。

C语言源程序

#include

#include

 

bitflag;

unsignedcharcount;

 

voiddely500(void)

{

unsignedchari;

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

{

_nop_();

}

}

 

voidmain(void)

{

while

(1)

{

if(P1_7==0)

{

for(count=200;count>0;count--)

{

P1_0=~P1_0;

dely500();

}

for(count=200;count>0;count--)

{

P1_0=~P1_0;

dely500();

dely500();

}

}

}

}

世上只有妈妈好

#include

sbitspeaker=P3^3;//接音频放大电路,

//sbitspeaker=P3^2;

//电后位后,sw合上后就开始放音乐,灯开始闪动,sw断开,音乐停止,灯也同时停止闪动

unsignedchartimer0h,timer0l,time,led=1,j=0;

unsignedcharflagd=0;

//世上只有妈妈好数据表

codeunsignedcharsszymmh[]={6,2,3,5,2,1,3,2,2,5,2,2,1,3,2,6,2,1,5,2,1,

6,2,4,3,2,2,5,2,1,6,2,1,5,2,2,3,2,2,1,2,1,

6,1,1,5,2,1,3,2,1,2,2,4,2,2,3,3,2,1,5,2,2,

5,2,1,6,2,1,3,2,2,2,2,2,1,2,4,5,2,3,3,2,1,

2,2,1,1,2,1,6,1,1,1,2,1,5,1,6,0,0,0

};

//音阶频率表高八位

codeunsignedcharFREQH[]={

0xF2,0xF3,0xF5,0xF5,0xF6,0xF7,0xF8,

0xF9,0xF9,0xFA,0xFA,0xFB,0xFB,0xFC,0xFC,//1,2,3,4,5,6,7,8,i

0xFC,0xFD,0xFD,0xFD,0xFD,0xFE,

0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFF,

};

//音阶频率表低八位

codeunsignedcharFREQL[]={

0x42,0xC1,0x17,0xB6,0xD0,0xD1,0xB6,

0x21,0xE1,0x8C,0xD8,0x68,0xE9,0x5B,0x8F,//1,2,3,4,5,6,7,8,i

0xEE,0x44,0x6B,0xB4,0xF4,0x2D,

0x47,0x77,0xA2,0xB6,0xDA,0xFA,0x16,

};

voiddelay(unsignedchart)

{

unsignedchart1;

unsignedlongt2;

for(t1=0;t1

{

for(t2=0;t2<8000;t2++)

{

;

}

}

TR0=0;

}

voidt0int()interrupt1

{

TR0=0;

speaker=!

speaker;

TH0=timer0h;

TL0=timer0l;

TR0=1;

}

voidsong()

{

TH0=timer0h;

TL0=timer0l;

TR0=1;

delay(time);

}

voidmain(void)

{

unsignedchark,i;

TMOD=1;//置CT0定时工作方式1

EA=1;ET0=1;//IE=0x82//CPU开中断,CT0开中断

while

(1)

{

i=0;

time=1;

while(time)

{

if(j==8)

{

//led=1;

j=0;flagd=~flagd;

if(flagd)

{

led=0x80;

}

else

{

led=1;

}

}

else

{

P1=~led;

if(flagd)

{

led=led>>1;

}

else

{

led=led<<1;

}

j++;

}

k=sszymmh[i]+7*sszymmh[i+1]-1;

timer0h=FREQH[k];

timer0l=FREQL[k];

time=sszymmh[i+2];

i=i+3;

song();

}

}

}

用外中断方式读按键,控制灯的亮灭

外中断的用法。

也就是外部IO的中断INT0,和INT1。

对应的引脚是P32和P33。

在我们的电路图中,P32也就是接在K1的引脚。

所以当我们按下P32接到地的时候,可以触发一个INT0中断,当然,必须预先初始化才会启动。

这种中断方式的按键,可以实现按键的立即响应。

对于需要快速响应的场合是很有用的。

外部IO中断还常用在用IO模拟通讯的场合,可以对数据的到来立即响应。

下面请看代码:

―――――――――――――――――

#defineucharunsignedchar//定义一下方便使用

#defineuintunsignedint

#defineulongunsignedlong

#include//包括一个52标准内核的头文件

sbitP10=P1^0;//头文件中没有定义的IO就要自己来定义了

sbitP11=P1^1;

sbitP12=P1^2;

sbitP13=P1^3;

sbitK1=P3^2;

bitldelay=0;//长定时溢出标记,预置是0

ucharspeed=10;//设置一个变量保存默认的跑马灯的移动速度

ucharspeedlever=0;//保存当前的速度档次

//用外中断方式读按键K1,点亮一个LED

voidmain(void)//主程序

{

IT0=1;//外中断跳变产生中断

EX0=1;

EA=1;//打开总中断

while

(1)//主程序循环

{

}

}

//外中断0

int0()interrupt0

{

P10=0;//在中断里点亮LED

}作业:

用中断方式的按键K1,控制一个LED灯的亮和灭两种状态

提示:

需要去抖操作,否则按键抖动会引起多种中断。

定时/计数器结构

⏹定时/计数器简称定时器,89C51单片机有2个16位的定时/计数器:

定时器0(T0)和定时器1(T1)。

它们都有定时器或事件计数的功能,可用于定时控制、延时、对外部事件计数和检测等场合。

⏹T0由2个特殊功能寄存器TH0和TL0构成,T1则由TH1和TL1构成。

作计数器时,通过引脚T0(P3.4)和T1(P3.5)对外部脉冲信号计数,当输入脉冲信号从1到0的负跳变时,计数器就自动加1。

计数的最高频率一般为振荡频率的1/24。

定时/计数器工作方式

⏹每个定时/计数器还有4种工作模式,也就是每个定时器可构成4种电路结构模式。

⏹在模式0、1和2,T0和T1的工作模式相同,在模式3,两个定时器的模式不同。

下面以T1为例,分述各种工作模式的特点和用法。

 

定时/计数器控制寄存器

⏹定时器共有2个控制寄存器TMOD和TCON,由软件写入TMOD和TCON两个8位寄存器,设置各个定时器的操作模式和控制功能。

二、定时器的结构

初学者不必去深入研究单片机的内部硬件电路,只要掌握单片机的使用方法,通过实际编程,充分发挥单片机的特定功能即可。

与定时器有关的特殊功能寄存器之间的信号关系示于图1。

图中,TLO、THO、TL1、TH1以及TMOD和TCON都是单片机的特殊功能寄存器。

TLO和THO组成16位的定时/计数器(T0),TL1和TH1组成16位的定时/计数器(T1),TMOD是T0和T1的工作方式控制寄存器,TCON是T0和T1的运行状态控制寄存器,这些寄存器在程序2中已多次出现。

在实际应用时,应首先根据需要对这些寄存器进行初始化,即设置T0和T1的工作方式并对T0和T1定时器装入初始值以得到精确的定时时间。

T0和T1的工作方式及运行状态是由TMOD和TCON两个特殊功能寄存器控制的,而TMOD和TCON是由用户所编的程序控制的。

因此,学好用好定时/计数器必须掌握这些寄存器的功能及使用方法。

三、TMOD

TMOD是定时器的工作方式控制寄存器,其格式见表1。

表1定时器工作方式寄存器格式

TMOD是8位的控制寄存器,低4位控制T0的工作方式,高4位控

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 外语学习 > 法语学习

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1