第3章 C51入门例题Word文档下载推荐.docx

上传人:b****6 文档编号:18349750 上传时间:2022-12-15 格式:DOCX 页数:14 大小:74.20KB
下载 相关 举报
第3章 C51入门例题Word文档下载推荐.docx_第1页
第1页 / 共14页
第3章 C51入门例题Word文档下载推荐.docx_第2页
第2页 / 共14页
第3章 C51入门例题Word文档下载推荐.docx_第3页
第3页 / 共14页
第3章 C51入门例题Word文档下载推荐.docx_第4页
第4页 / 共14页
第3章 C51入门例题Word文档下载推荐.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

第3章 C51入门例题Word文档下载推荐.docx

《第3章 C51入门例题Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《第3章 C51入门例题Word文档下载推荐.docx(14页珍藏版)》请在冰豆网上搜索。

第3章 C51入门例题Word文档下载推荐.docx

AT89X51.H>

voidmain(void)

constunsignedchardesign[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{//dowhile型循环

for(b=0;

b<

32;

b++)

for(a=0;

a<

30000;

a++);

//延时一段时间

P2=design[b];

//读已经定义的花样数据并写花样数据到P2口

}

}while

(1);

[实验3-3]调用延时函数的流水灯程序。

如下程序中将延时循环语句单独编写成延时函数,并利用循环移位指令实现P2口的流水灯的流动。

reg51.h"

//通用51头文件

intrins.h"

//C51函数库,具有移位函数

#defineucharunsignedchar//重新定义unsignedchar类型名为uchar

#defineuintunsignedint//重新定义unsignedint类型名为uint

voidmDelay(unsignedintDelay)//具有延时参数的延时函数

{unsignedinti;

for(;

Delay>

0;

Delay--)

{for(i=0;

i<

124;

i++);

voidmain()//主函数

{unsignedcharOutData=0xfe;

//定义输出数据与初值

;

)//无限循环

P2=OutData;

//将OutData输出到P2口,使P2口中的一个LED灯亮

OutData=_crol_(OutData,1);

//使OutData循环左移,使亮的LED灯左移一位

mDelay(100);

//调用延时函数

[实验3-4]P3_2引脚连接的按键控制的流水LED灯

该实验中的按键控制P2口连接的流水LED灯是否流水,如果按键按下,使流水灯流水,否则流水灯全灭。

#include"

//该文件包含有_crol_()函数的定义

voidmDelay(unsignedintDelayTime)//延时函数

{unsignedintj=0;

DelayTime>

DelayTime--)

{for(j=0;

j<

125;

j++);

{

unsignedcharOutData=0xfe;

//定义变量为0xfe

while

(1)//无限循环

P3|=0x3c;

//00111100将P3口中间4位置1

while((P3|0xfb)!

=0xff)//11111011=0xfb若是P3_2引脚为1,则该循环条件不成立

{//若是P3_2引脚为0(按键按下),则该循环条件成立

//将OutData输出到P2口相连的LED灯

//将OutData循环左移1位

P2=0xff;

//将连接在P2口的LED灯熄灭

[实验3-5]采用移位指令实现的流水灯。

八个LED灯L1-L8分别接在单片机的P2.0-P2.7引脚上,输出“0”时,LED灯亮,按照P2.0→P2.1→P2.2→P2.3→┅→P2.7→P2.6→┅→P2.0顺序点亮,重复循环。

源程序如下:

unsignedchari;

//定义循环次数变量

unsignedchartemp;

//定义被循环的变量

unsignedchara,b;

//定义循环中间值变量

voiddelay(void)//定义延时函数

unsignedcharm,n,s;

for(m=20;

m>

m--)

for(n=20;

n>

n--)

for(s=248;

s>

s--);

}

voidmain(void)//主函数

{while

(1)

temp=0xfe;

//设置循环初值

P2=temp;

//送P2口显示

delay();

for(i=1;

8;

i++)//正向循环流水

a=temp<

<

i;

//如果i=1,a=1111,1100,i=2,a=11111000

b=temp>

>

(8-i);

//如果i=1,b=00000001,i=2,b=00000011

P2=a|b;

//如果i=1,P2=11111101,i=2,P2=11111011

i++)//反向循环流水

a=temp>

b=temp<

}}}

[实验3-6]用查表法控制P2口连接的8个LED灯。

可以按照需要自行加入表格元素,编辑表格元素时,应该先画显示的LED灯点亮图形,方法如下:

图型(0表示灯亮)

十六进制编码

01111110

7e

10111101

bd

11011011

db

11100111

e7

等等

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

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

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

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

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

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

0x7e,0xbd,0xdb,0xe7,

0x7e,0x3c,0x18,0x00,0x01};

//元素中只能有一个0x01,因为0x01是最后一个元素标志。

voiddelay(void)//定义延时函数

{unsignedcharm,n,s;

voidmain(void)//主函数

while

(1)//无限循环语句

if(table[i]!

=0x01)//判断是否是表格的最后一个元素

P2=table[i];

//将表格元素赋予P2口,在与P2口相连的LED灯上显示

i++;

//准备显示下一个表格元素

//调用延时函数延时

else//如果是最后一个元素,使循环次数变量为0

{i=0;

}}}

 

3.2具有定时器的C51程序实验

[实验3-7]定时器中断控制LED闪烁。

由于51单片机从中断发生到进入中断的时间不定,是3至8个机器周期,在进入了中断后,软件才重新置定时器初始值,这样就会存在定时误差。

不是精确定时,如果要精确定时,需要使用定时器自动装载方式,也就是在定时器溢出的同时,硬件逻辑就自动把定时器初始值装载进去,而不是在中断服务程序里赋初始值,只有这样才可以实现精确定时,在精确定时的情况下,定时误差由晶振的频率不稳定引起。

中断引起P2.0引脚连接的LED灯闪烁。

TMOD=0X01;

//定时器0,工作模式1,16位定时模式,GATE=0,C/T=0

TR0=1;

//启动定时器

ET0=1;

//允许定时器中断

EA=1;

//允许总中断

while

(1);

//无限循环

timer0()interrupt1//定时器0中断服务程序

TH0=0X00;

//写入定时器TH初值00H

TL0=0X06;

//写入定时器TL初值06H,计数器溢出值为65530

P2_0=~P2_0;

//闪烁LED

[实验3-8]精确定时0.5s。

在定时器中断服务函数里,设置了一个静态变量kk,静态变量kk的值在进入函数时是不会被初始化的,而是保持上次的值。

它用来计数定时器的溢出次数,也就是T0中断服务函数进入的次数,每溢出2000次,就是间隔0.5秒,使P2.0连接的LED灯亮灭一次。

TMOD=0x02;

//定时器0,工作模式2(0000,0010),8位定时模式

//GATE=0,C/T=0,

TH0=0x06;

//写入预置初值到定时器TH,预置6,使250微秒溢出一次(12MHz)

TL0=0x06;

//写入预置值

staticunsignedintkk;

//设置局部静态变量

kk++;

//每中断一次加1

if(kk==2000)//当中断2000次后,相当于0.5秒0.25ms*2000=0.5s

{kk=0;

//闪烁LED

[实验3-9]精确定时的流水灯。

所有的中断都要尽快的运行和退出,中断服务程序越短越好,这样才不至于干扰主程序的工作和其他中断的运行。

所以应该尽量把程序代码从中断服务函数里搬到主程序中运行。

对于定时器的中断的工作方式,可以建立一个全局变量的标记,在中断服务程序中置位这个标记,然后就退出中断服务。

在主程序里检查到这个全局变量标记之后,就运行相关的程序。

对于CPU任务比较多的程序来说,这种工作方式可以获得较好的工作效率。

采用查表的方式,将要点亮LED灯的顺序预先设置好,到了指定的时间,就一起将LED灯亮灭信息送到P2口。

unsignedintldelay=0;

//长定时溢出标记ldelayt,预置值是0

voidmain(void)//主程序

unsignedcharcodeledp[4]={0xfe,0xfd,0xfb,0xf7};

//预定的灯亮灭顺序,写入P2

unsignedintledi;

//用来确定表格位置的变量

//定时器0,工作模式2(0000,0010),8位定时模式

//GATE=0,C/T=0,

//写入预置初值到定时器TH,预置6,250微秒溢出一次(12MHz)

//启动定时器

//允许定时器中断

while

(1)//无限循环

if(ldelay==1)//时间溢出标记为1,处理如下事件

ldelay=0;

//清除溢出标记

P2=ledp[ledi];

//读出一个表格值送到P2口

ledi++;

//指向下一个表格值

if(ledi==4)//如果表格查过一遍

ledi=0;

//指向第一个表格值

}}}

//定义静态局部变量

//每次中断服务程序执行,kk增加1

if(kk==2000)//T0的预置值0x06,溢出2000次就是0.5秒钟,晶振12MHz

kk=0;

//如果中断服务程序执行2000次,则执行下一个语句

ldelay=1;

//将该标记置1,以便主程序处理

[实验3-10]定时/计数器工作在模式1,设置定时/计数器0初值为15536,因此计数溢出值为50000,在时钟频率为12MHz时,中断周期为50ms,每20次中断使P2.0引脚取反,使相连的LED灯闪烁;

每20次中断使变量nn加1,用连接在P1和P0口的数码管显示nn值(范围0~59),源程序如下:

reg_c51.h"

unsignedcharhex[16]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,

0x88,0x83,0xC6,0xA1,0x86,0x8E};

//数码管十六进制译码表

unsignedcharn,nn;

//定义中断次数变量

TMOD&

=0xF0;

//定时/计数器0运行在模式1,16位模式

TMOD|=0x01;

//GATE0=0;

C/T0#=0;

M10=0;

M00=1;

TH0=0x3c;

//设初值,初值=(65536-15536)/256=3cH

TL0=0xb0;

//设初值,初值=(65536-15536)%256=b0H,,50ms

//允许定时/计数器0中断

//允许总中断

//启动定时/计数器0

P1=hex[nn/10];

//显示中断次数变量n的高位

P0=hex[nn%10];

//显示中断次数变量n的低位

voidit_timer0(void)interrupt1//定时/计数器0中断服务函数

TH0=0x3C;

//重设初值

n++;

//每中断一次,n加1

if(n==20)//如果中断20次,则执行如下语句

n=0;

//将n清0

nn++;

//使nn加1

if(nn==60)//如果nn=60,执行如下语句

{nn=0;

}//将nn清0

P2_0=~P2_0;

//将P2_0引脚的状态取反,使相连的LED灯闪烁

P2_1=~P2_1;

//每次中断都取反P2_1引脚,使相连的LED灯闪烁

[实验3-11]脉冲宽度调制(PWM)方式控制LED灯亮度。

在一定的频率的方波中,调整高电平和低电平的占空比,即可实现LED灯亮度控制。

如图4-7所示,程序中使用定时器0产生2.5ms周期脉冲,使用占空比控制变量scale控制占空比,在低电平期间使LED灯亮,在高电平期间使LED灯灭,改变scale就改变了高电平与低电平的时间,因此也就控制了LED灯(连接在P2.0引脚)的亮度。

图4-7PWM占空比控制示意图

//模拟PWM输出控制灯的10个亮度级

unsignedintscale;

//占空比控制变量

voidmain(void)//主程序

//延时循环变量

//定时器0,工作模式2(0000,0010),8位定时模式

//写入预置初值6到定时器0,使250微秒溢出一次(12MHz)

//写入预置值

//启动定时器

//允许定时器0中断

//允许总中断

while

(1)//无限循环,实际应用中,这里是做主要工作

50000;

//每过一段时间,就自动加一个档次的亮度

scale++;

//占空比控制变量scale加1

if(scale==10)scale=0;

//如果scale=10,使scale为0

staticunsignedinttt;

//tt用来保存当前时间在一秒中的比例位置

tt++;

//每250微秒增加1

if(tt==10)//2.5毫秒的时钟周期

tt=0;

//使tt=0,开始新的PWM周期

//使LED灯亮

if(scale==tt)//按照当前占空比切换输出为高电平

//使LED灯灭

程序中从tt=0开始到scale为低电平,从scale开始到tt=10为高电平,由于scale是变量,所以改变scale就可以改变占空比。

3.3串行通信实验

[实验3-12]51单片机串口与PC机通信

单片机采用模式1(8位),定时器1采用模式2产生波特率,晶体频率11.0592MHz,9600波特率,PC机上运行的串口助手向单片机发送16进制数据,然后单片机将接收到的数据(16进制)返回串口助手。

单片机用P2口连接的LED灯和P1和P0口连接的数码管显示接收到的数据。

单片机串口通过电平转换芯片与PC机串口相连。

unsignedcharuart_data;

unsignedcharcodetable[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,

0x08,0x03,0x46,0x21,0x06,0x0e};

//十六进制-7段译码表

unsignedcharng,ns,temp;

//ng是接收到数据的低4位,ns是高四位,temp是暂存接收数据的变量

voidmain(void)

SCON=0x50;

//8位串行口模式1,允许接收,REN=1

TMOD=TMOD|0x20;

//定时器1,在模式2

TH1=0xFD;

//波特率为9600,晶体频率为11.059MHz

TL1=0xFD;

//波特率为9600,晶体频率为11.059MHz

ES=1;

//使能串行口中断

EA=1;

//使能全局中断

TR1=1;

//无限循环

voidserial_IT(void)interrupt4//串口中断服务程序

{if(RI==1)//如果是接收中断,则执行如下语句

RI=0;

//清除接收中断标志

uart_data=SBUF;

//接收数据

SBUF=uart_data//将接收的数据发送

temp=uart_data;

//暂存接收到的数据

P2=~temp;

//将接收的数据求反后送P2口,用LED灯显示

ng=temp&

0x0f;

//取低4位,ng是接收到数据的低4位

ns=temp>

4;

//将高4位右移4位

ns&

=0x0f;

//取低4位。

ns是接收到数据的高4位

P0=table[ng];

//将低4位送P0口,用数码管显示低4位

P1=table[ns];

//将高4位送P1口,用数码管显示高4位

elseTI=0;

//清除发送标志

图3-2串口助手与实验3-12的程序通信

图3-2显示的是串口助手软件与实验3-12程序通信的情况,串口助手发送55H,51单片机收到后,向串口助手转发55H,串口助手收到并显示在接收区中。

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

当前位置:首页 > 职业教育 > 职高对口

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

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