单片机控制技术配套实验程序.docx
- 文档编号:10650774
- 上传时间:2023-02-22
- 格式:DOCX
- 页数:188
- 大小:696.63KB
单片机控制技术配套实验程序.docx
《单片机控制技术配套实验程序.docx》由会员分享,可在线阅读,更多相关《单片机控制技术配套实验程序.docx(188页珍藏版)》请在冰豆网上搜索。
单片机控制技术配套实验程序
单片机控制技术配套实验程序
数据类型
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
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 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位控
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 单片机 控制 技术 配套 实验 程序