51单片机的基本外围电路设计以及相关C语言程序免积分.docx

上传人:b****1 文档编号:1725263 上传时间:2023-05-01 格式:DOCX 页数:119 大小:730.91KB
下载 相关 举报
51单片机的基本外围电路设计以及相关C语言程序免积分.docx_第1页
第1页 / 共119页
51单片机的基本外围电路设计以及相关C语言程序免积分.docx_第2页
第2页 / 共119页
51单片机的基本外围电路设计以及相关C语言程序免积分.docx_第3页
第3页 / 共119页
51单片机的基本外围电路设计以及相关C语言程序免积分.docx_第4页
第4页 / 共119页
51单片机的基本外围电路设计以及相关C语言程序免积分.docx_第5页
第5页 / 共119页
51单片机的基本外围电路设计以及相关C语言程序免积分.docx_第6页
第6页 / 共119页
51单片机的基本外围电路设计以及相关C语言程序免积分.docx_第7页
第7页 / 共119页
51单片机的基本外围电路设计以及相关C语言程序免积分.docx_第8页
第8页 / 共119页
51单片机的基本外围电路设计以及相关C语言程序免积分.docx_第9页
第9页 / 共119页
51单片机的基本外围电路设计以及相关C语言程序免积分.docx_第10页
第10页 / 共119页
51单片机的基本外围电路设计以及相关C语言程序免积分.docx_第11页
第11页 / 共119页
51单片机的基本外围电路设计以及相关C语言程序免积分.docx_第12页
第12页 / 共119页
51单片机的基本外围电路设计以及相关C语言程序免积分.docx_第13页
第13页 / 共119页
51单片机的基本外围电路设计以及相关C语言程序免积分.docx_第14页
第14页 / 共119页
51单片机的基本外围电路设计以及相关C语言程序免积分.docx_第15页
第15页 / 共119页
51单片机的基本外围电路设计以及相关C语言程序免积分.docx_第16页
第16页 / 共119页
51单片机的基本外围电路设计以及相关C语言程序免积分.docx_第17页
第17页 / 共119页
51单片机的基本外围电路设计以及相关C语言程序免积分.docx_第18页
第18页 / 共119页
51单片机的基本外围电路设计以及相关C语言程序免积分.docx_第19页
第19页 / 共119页
51单片机的基本外围电路设计以及相关C语言程序免积分.docx_第20页
第20页 / 共119页
亲,该文档总共119页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

51单片机的基本外围电路设计以及相关C语言程序免积分.docx

《51单片机的基本外围电路设计以及相关C语言程序免积分.docx》由会员分享,可在线阅读,更多相关《51单片机的基本外围电路设计以及相关C语言程序免积分.docx(119页珍藏版)》请在冰点文库上搜索。

51单片机的基本外围电路设计以及相关C语言程序免积分.docx

51单片机的基本外围电路设计以及相关C语言程序免积分

主要学习51单片机的外部引脚和内部结构等,叙述一下。

本书任务驱动教学,引入案例有浅变深,循序渐进,给读者留下思考和发挥空间。

3.1利用单片机的I/O口驱动LED

3.1.1利用单片机的P0.0端口驱动1只LED闪烁

编程的目的是利用C语言控制单片机I/O端口按要求输出矩形波脉冲信号,信号的周期由延时函数决定。

一、电路原理

STC-89C51单片机的P0口采用为OD门输出,不存在拉出电流,因此利用P0驱动负载时有两种接法:

一种是加上拉电阻R2,见图3-1-1,既用1K

电阻接电源正极,此时P0口输出高电平时LED亮;另一种电路为P0.7低电平驱动有效,在P0.7输出低电平时,STC-89C51端口灌入电流达20mA,可直接驱动小负载。

图3-3-1中的R3为限流电阻,限制LED2的工作电流。

 

图3-1-1驱动LED电路原理

单片机的最小系统包括晶体振荡电路,加电复位电路,同时要求单片机的31引脚

接高电平。

时钟频率主要由晶体CY决定,C1、C2为独石电容,用于微小调整单片机时钟的振荡频率;R1和C3组成加电复位电路,C3为电解电容器;整个电路由+5V电压供电。

电路使用的元件参数见表3.1.1。

 

表3.1.13-1-1电路元件表

元件名称

序号

标称

规格(封装,功率电压等参数)

作用

单片机

IC

STC89C51

DIP40

核心芯片

电容器

C1

30PF

独石

振荡

电容器

C2

30PF

独石

振荡

电容器

C3

10

F

点解电容器

复位

晶振

CY

12MHz

S型

振荡

电阻

R1

1K

1/4W,金属膜

电容器C3放电电阻

电阻

R2

1K

1/4W,金属膜

端口电位上拉电阻

电阻

R3

1K

1/4W,金属膜

限流电阻

发光二极管

LED1

5

红色高亮

显示

发光二极管

LED2

5

红色高亮

显示

二、程序设计

1.程序设计平台

程序设计采用keilC软件,为了养成一个良好的文件管理习惯,建议:

编程前,在计算机的某个硬盘分区下建立一个目录,目录的名字为你编写程序的主题,然后把keilC产生的所有文件都放在该目录下。

程序设计步骤如下:

(1)运行keilC,创建一个项目。

利用keilC菜单栏中project-newproject创建,项目的名字为你编程的主题,如本案例可以用“LED_1.uv2”或“一个LED闪烁实验.uv2”,存放目录为你的主题目录下;

(2)创建建一个文件,然后以“.c”后缀名,文件存放在你的主题目录下;

(3)把c文件添加在你的项目中,在projectworkspace窗口利用addfiletogroup…实现。

如果软件界面不显示这个窗口,运行keilC菜单栏中的view-projectwindow。

(4)设置编译器,是编译过程中能生成“.hex”文件。

默认文件名与主题名字相同。

运行project-optionfor‘target1’-output窗口下点击createHEXfile。

(5)在编程区域写你的程序,结束后存储文件并编译,要做检查,尽量避免警告出现,直到程序编译无误为止。

(6)程序烧写并试运行。

这个过程称为软件和硬件联合调试,如果实验板无误,程序编译通过,但在硬件上运行不成功是常用的事情,需要对程序进行多次调试。

在没有实验板的情况下,可以利用proteus软件仿真调试,也可以检验你的程序设计结果。

2.程序设计

(1)利用P0.0口驱动LED闪烁,高电平有效

/*****************************************************************************/

#include//包含头文件

sbitLED=P0^0;//LED接P0.0。

在kellC51软件中,定义P0.0为P0^0,

voiddelay(unsignedcharx)//延时函数

{

unsignedchari,j;

for(i=0;i

for(j=0;j<200;j++);

}

voidmain(void)//主函数

{

While

(1)//程序死循环

{

LED=0;//P0.0输出低电平,LED灭

voiddelay(100);//调用延时函数,延时一段时间,约0.3秒,不精确

LED=1;//P0.0输出高电平,LED亮

voiddelay(100);

}

}

/*****************************************************************************/

(2)利用P0.7端口驱动LED闪烁,低电平有效

/*****************************************************************************/

#include//包含头文件,程序为小5号字

sbitLED=P0^7;

voiddelay(unsignedcharx)//延时函数

{

unsignedchari,j;

for(i=0;i

for(j=0;j<1000;j++);

}

voidmain(void)//主函数

{while

(1)

{

LED=~LED;//LED初始状态为灭,执行一次,LED改变一次状态

voiddelay(100);//延时一段时间

}

}

/*****************************************************************************/

三、程序说明

1.应为使用的单片机芯片为STC89C51,因此程序开始处加入#include,文件reg51.h中包含了51芯片所有特殊功能寄存器的名称定义和相对应的地址值;

2.单片机程序单步顺序执行,先执行主函数,在主函数可以调用分函数,分函数可以调用分函数,但分函数不能调用主函数,程序执行一条命令再执行下一条,单片机等待的过程是执行了一个循环命令或一个浪费时间的程序,实际执行过程永远不会结束。

delay()为函数延,单片机在执行此函数相关指令时占用的时间过长,在执行过程中,如果没有中断,单片机只能忙这一件事情。

利用delay()不能得到精确的延时。

延时函数还可以利用下面的函数实现。

/**************************/

voiddelay(unsignedintx)

{

while(x)

x--;

}

/**************************/

3.利用位定义命令让LED等价于P0.0或P0.7,等于先sbitP0_0=P0^0,然后#definedLEDP0_0,也在程序前面不做此类定义,在程序里面直接写成P0^0=1或P0^0=0,先定义是为了增加程序的可读性。

程序执行P0^0=1后,P0.0对以的单片机内部位寄存器就设置为高电平,同时P0.0端口也输出高电平,单片机的所有I/O口都可位未定义,也可以字节定义。

4.单片机C语言程序设计需要的C语言关键字不多,并且在keilC中用到的关键字是独有的,因此对于没有学习过C语言的人学习单片机C语言程序设计困难并不是很大,主要掌握单片机C语言书写格式,怎样用C语言控制单片机的硬件资源,另外在编程时,还要有清晰的逻辑思维头脑和认真实践,由浅逐步深入学习,当你坚持到最后时,单片机C语言程序设计实际上很简单。

5.每个人在编写程序时都有自己的风格。

一般情况下,函数的字符左行距为0,其下每条语句前留一个“tab”键空。

算数逻辑符号的左右留一个空格,关键语句要有中文或英文说明,每一个函数有时也可以用“/**.....**/”上下隔开这样有助于提高程序的层次感和可读性。

3.1.2利用P0口驱动8个LED,产生跑马灯或流水灯效果

一、参考电路

实验电路见图3-3-2所示,在单片机的最小系统的基础上,P0口依次接入8个LED,P0口的上拉电阻可以使用8个1K

电阻。

 

图3-1-2流水灯电路

在利用Proteus软件仿真时,可以用电阻排代替。

单片机最小系统在单片机元件放置后已经默认,即C1、C2、C3、CY、R1可以省略。

其它元件选取见表3.1.2所示。

表3.1.13-1-2电路Proteus软件元件表

元件名称component

总类Category

分类Sub-Category

结果Results

模型Modeltype

单片机

MicoroprocessorIC

8051Family

80C51

电阻排

Resistor

ResistorPack

RESPACK-8

ANALOG

发光二极管

Optoelectronics

LEDs

led-red

DIGITAL

二、参考程序

/*****************************************************************************/

#include

voiddelay(void)

{

unsignedchari,j;

for(i=0;i<255;i++)for(j=0;j<255;j++);

}

voidmain(void)

{

unsignedcharj=0x01;

while

(1)

{

j=j<<1;

if(j==0x00)j=0x01;

P0=j;

delay();

}}

/*****************************************************************************/

三、程序说明

1.语句j=j<<1,执行的目的是控制P0整个字节的数据在循环时左移变化,程序循环第一次,P0=0x02,P0.1连接的LED亮,其它灭;循环第七次,P0.7连接的LED亮,其它灭;循环第八次,j=0x00,if语句条件满足,j=0x01,P0.0连接的LED亮,其它灭,然后依次变化下去。

如果P0口驱动8个LED低电平有效,如下修该:

/**********************/

voidmain(void)

{

unsignedcharj=0xfe;

while

(1)

{

j=(j<<1)|0x01;

if(j=0xff)j=0xfe;

P0=j;

delay();

}}

2.delay()函数无形参,延时时间不能设置。

3.1.3利用P0口驱动一个数码管,显示0–9,并循环

一、参考电路

实验电路在单片机的最小系统基础上,P0口接一只共阳数码管,见图3-1-3。

带小数点的数码管是由8个LED组成,七个LED组成数字,另一只LED用来显示小数点。

如果数码管内部的8只LED的正极接在一起,负极分别引出,引脚依次命名为a、b、c、d、e、f、g和dot,称为带小数点的7段共阳极性数码管。

图3-1-3单片机驱动共阳数码管电路

单片机的P0.0-P0.7口分别接数码管的a-dot引脚,如果让数码管显示1,数码管b、c段亮,程序控制P0输出0xbe十六进制编码即可,因此共阳数码管显示0-9十进制数字,需要利用10个显示码组成的数组。

对于共阴数码管,也有相应的编码要求。

小数点在不用时一般不让显示,高位端口P0.7输出高电平即可。

由于P0每个端口的灌电流达20mA,数码管每段LED正常显示5mA即可,因此需要R2~9用来限制数码管每一段电流,以防止驱动电流过大而烧毁器件。

利用Proteus软件仿真时,数码管采用Optoelectronics元件库中7-SegmentDisplays下的7-SEG-COM-ANODE。

二、参考程序

/*****************************************************************************/

#include

codeunsignedcharseven_seg[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};

voiddelay(void)/*时间延迟函数*/

{

unsignedchari,j;

for(i=0;i<255;i++)for(j=0;j=255;j++);

}

voidmain(void)

{

unsignedchari;/*变量i用来储存0~9*//*无穷循环*/

while

(1)

{

for(i=0;i<10;i++)

{

P0=seven_seg[i];/*输出0~9到共阳七段显示器*/

delay();/*调用时间延迟函数delay*/

}}}

/*****************************************************************************/

三、程序说明

1.当程序中使用常量数据时,可以把数据存储在单片机的程序存储器中,对此类数据声明时,前面需要加上关键字code或const,如本实验中的共阳数码管数字显示需要的编码,表3-1-3是共阳数码管编码,表3-1-4是共阴数码管编码。

单片机驱动液晶显示器显示的汉字也是一种常量数据。

表3-1-3共阳数码管显示编码

显示数字

dot

g

f

e

d

c

b

a

16进制

0

1

1

0

0

0

0

0

0

0xc0

1

1

1

1

1

1

0

0

1

0xf9

2

1

0

1

0

0

1

0

0

0xa4

3

1

0

1

1

0

0

0

0

0xb0

4

1

0

0

1

1

0

0

1

0x99

5

1

0

0

1

0

0

1

0

0x92

6

1

0

0

0

0

0

1

0

0x82

7

1

1

1

1

1

0

0

0

0xf8

8

1

0

0

0

0

0

0

0

0x80

9

1

0

0

1

0

0

0

0

0x90

 

表3-1-4共阴数码管显示编码

显示数字

dot

g

f

e

d

c

b

a

16进制

0

0

0

1

1

1

1

1

1

0x3f

1

0

0

0

0

0

1

1

0

0x06

2

0

1

0

1

1

0

1

1

0x5b

3

0

1

0

0

1

1

1

1

0x4f

4

0

1

1

0

0

1

1

0

0x66

5

0

1

1

0

1

1

0

1

0x6d

6

0

1

1

1

1

1

0

1

0x7d

7

0

0

0

0

0

1

1

1

0x07

8

0

1

1

1

1

1

1

1

0x7f

9

0

1

1

0

1

1

1

1

0x6f

2.本程序数码管显示使用了一个for循环,让变量i依次由0递增到9,并将数字显示码送到P0,需要注意,seven_seg[10]有10各数据,seven_seg[0]为第一个数据,seven_seg[9]为第10个数据。

数码管显示的数据变化时间由延时函数决定。

for循环体嵌套在while循环体中,数码管回循环显示0~9,永不结束,除非电路断电。

利用数码管也可以显示日期和时间,在以后的程序设计案例中就可以学到。

3.2单片机定时器/计数器应用

3.2.1利用Timer0中断产生1秒延时,让数1个码管显示秒计数

本案例主要目的是熟练掌握单片机内部Timer0或Timer1的编程控制方法,会利用Timer0或Timer1中断精确定时。

同时掌握数码管动态显示原理,学会6位数字显示的程序设计。

本案例使用的电路为图3-1-3。

一、程序设计

/*****************************************************************************/

#include

codeunsignedcharseven_seg[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};

unsignedcharcp,i;//声明全局变量

voidtimer0_isr(void)interrupt1//timer0中断服务函数

{

TR0=0;//停止计数

TL0=0x11;//TL0重新预置

TH0=0xee;//TH0重新预置

TR0=0;//开始计数

cp++;//timer0中断1次,变量cp加1

if(cp==200)//中断200次,时间刚好为1秒

{cp=0;i++;}

if(i==10)i=0;

P0=seven_seg[i]//P0输出显示数据

}

voidtimer0_initialize(void)//timer0中断初始化函数

{

EA=0;//设置中断允许寄存器IE中的EA位,关闭中断总开关

TMOD=0x01;//设置计时器模式控制寄存器,Time0工作在定时方式1

TR0=0;//设置计时器控制寄存器TCON寄存器的TR0位为0,Timer0

//停止计数

TL0=0x11;

TH0=0xee;//Timer0的16位计数器初始值为0xee11,12MHz晶体振

//频率,单片机的机器周期为1微妙,Timer0每1微秒加1

//计数,加满溢出变产生中断,从计数到中断刚好为5毫秒

PT0=1;//设置中断优先次序寄存器IP中的PT0位,Timer0中断优先

ET0=1;//设置中断允许寄存器IE中ET0的位,开启中断小开关

EA=1;//打开中断总开关

TR0=1;//开始计数

}

voidmain(void)

{

timer0_initialize()//timer0初始化,为中断做好准备

while

(1);//等待中断

}

/*****************************************************************************/

二、程序说明

1.中断服务函数名中,interruput为关键字,1为timer0中断号。

在reg51.h头文件中已经定义,表3.2.1为单片机常用中断的中断号。

在使用中断服务函数时,直接在名后加interruput和中断号即可。

表3.2.1reg51.h中单片机常用中断号定义

中断源

中断触发原因

中断号

INT0

外部INT0引脚有低电平或下降沿信号输入

0

Timer0

Timer0计数溢出

1

INT1

外部INT0引脚有低电平或下降沿信号输入

2

Timer1

Timer1计数溢出

3

串行中断

串口缓存SBUF写入数据或读出数据

4

2.timer0可以用作计数,也可以用来定时,由由TMOD寄存器中

为决定,作为计数器使用时,接受单片机外部引脚P3.4输入的脉冲加计数;作为定时器使用时,接受单片机内部的机器周期脉冲。

如果单片机的振荡频率为

,振荡周期为

,则机器周期为

本案例中

MHz,则

微秒,timer0工作在模式1为16为加计数器,当计数器初始值为0xee11时,则从开始计数到产生中断需要的时间为0xffff—0xee11个微秒,刚好为5000微秒,也即5毫秒。

本案例timer0的初装也可以利用下面语句完成:

/**********************************/

#definedTEMOR0_COUNT0xee11

TL0=TEMOR0_COUNT&0x00ff;//取TEMOR0_COUNT的低字节并装入TL0

TH0=TEMOR0_COUNT>>8;//TEMOR0_COUNT左移8位,并将低字节装入TEMOR0_COUNT

/**********************************/

利用定时器/计数器定时时,需要现设置工作模式,并计算它的初装值,计算初装值不好计算,常利用计算机中的计算器工具辅助。

timer0工作在模式1可以最大65535微秒中断1次,如工作模式2,最大256微秒中断1次。

3.当程序中只涉及一个中断时,可以不对中断的优先级进行设置,因此在本案例中语句PT0=1可以省略。

程序中有多个中断但没有进行优先级设定的情况下,单片机中断优先级默认按终端号递增而依次降低。

4.数码管显示语句放在了timer0中断服务函数里面,由于5毫秒中断1次,因此数码管显示的数据会每5毫秒更新1次。

1秒内更新200次,更新过程是把原来的数据覆盖,但显示数据1秒内变化1次。

3.2.2利用4个数码管,实现秒信号加计数

一、电路原理

图3-2-1所示的电路中,4位七段数码管采用4只单个数码管组成,可以显示0000~9999,数据输入端并联后接P0口,位选即每个数码管的阳极分别接P2口,中间加非门驱动。

因为P2口反相驱动,因此,如果千位数码管显示,P2.7输出低电平,P2的其它端口输出高电平,并且此时P0输出千位数据。

在利用Proteuse软件仿真时,数码管SEVEN_SEG使用7SEG-MPX4-CA,非门NOT选用74HCseries类型中Gates&Inverters分类下的74HC04。

电阻R2~9是限流电阻。

图3-2-14位七段数码管显示

二、程序设计

/*****************************************************************************/

#include

#definedunsignedcharuchar

#definedunsignedintuint

codeucharseven_seg[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};

codeucharseg_scan[4]={0xef,0xdf,0xbf,0x7f};//各个数码管对应的位选数据

ucharcounter[4]={0,0,0,0};//个位、十位、百位和

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

当前位置:首页 > 初中教育 > 语文

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2