任务238位流水灯.docx

上传人:b****7 文档编号:9164043 上传时间:2023-02-03 格式:DOCX 页数:22 大小:1.14MB
下载 相关 举报
任务238位流水灯.docx_第1页
第1页 / 共22页
任务238位流水灯.docx_第2页
第2页 / 共22页
任务238位流水灯.docx_第3页
第3页 / 共22页
任务238位流水灯.docx_第4页
第4页 / 共22页
任务238位流水灯.docx_第5页
第5页 / 共22页
点击查看更多>>
下载资源
资源描述

任务238位流水灯.docx

《任务238位流水灯.docx》由会员分享,可在线阅读,更多相关《任务238位流水灯.docx(22页珍藏版)》请在冰豆网上搜索。

任务238位流水灯.docx

任务238位流水灯

任务三8位流水灯

2.3.1任务内容

流水灯在我们的日照生活中有着非常多的应用,如广告牌的设计和节日彩灯的设计都用到它的原理。

本节的任务是把开发板上的8个发光二极管依次点亮。

另外一IO口接外部电平,高电平时流水灯从左向右依次点亮,低电平时流水灯从右向左依次点亮。

2.3.2知识准备

1、单片机IO的构造

在上一单元中发光二极管闪烁的实例中,I/O控制小灯闪烁,只需在Keil中对I/O写‘0’、和写‘1’就可以了,使用起来非常简单。

但是在实际应用中如果不了解I/O的特点,设计的电路存在缺陷,I/O应用起来未必会得心应手。

初学者不必深究I/O控制原理,但至少得弄明白几个基本的概念,这对后期学习高档单片机也很有帮助。

在I/O构造电路中,有三极管(实际上是MOS管)、锁存器等,我们先来学习一下这两个基本器件的特点。

(1)三极管

在I/O构造电路中,有一个器件是MOS管,I/O能对外输出高低电平全依赖MOS管的导通与否。

MOS管和三极管在外特性很相像,由于我们更熟悉三极管,所以这里讲解三极管。

三极管是模拟电路和数字电路的基石。

在模拟电路中,三极管主要用于放大弱信号。

在数字电路中,三极管更多作为开关管来使用。

三极管的基本结构是两个反向联结的的PN接面,如图所示,有NPN和PNP两种组合。

三个接出来的端点依次被称为发射极(E)、基极(B)和集电极(C)。

图中也显示了NPN和PNP三极管的电路符号,射极被特别标出,箭头由外指向内的是NPN,由内指向外的是PNP。

PNP三极管NPN三极管

图2.3.1PNP三极管和NPN三极管

NPN三极管电流由基极和集电极流入,发射极流出;而PNP三极管则相反,从发射极流进,从基极和集电极流出。

不管是NPN三极管还是PNP三极管,都满足这样几个特性:

①:

三个极之间的电流的关系为:

流进的=流出的,即IB+IC=IE。

②:

Ic大小跟Ib有关:

Ib为0,则Ic也为0;Ib从0开始增大,Ic也跟着增大,而且在这一过程中,Ic=βIb,其中β为放大倍数,不同三极管β不一样,从几十到几百倍;当Ic的值到了极限时,Ib再增大,Ic也不再跟着增大了。

③:

基极和发射极之间可以等效成一个二极管,要获得基极电流,基极电压要高于发射极电压0.6~0.7V,而且一旦导通之后,这个电压基本保持不变。

三极管本质上是一个以弱控强的器件,大家可以想象一下用一个阀门控制大坝匝门的情形。

当阀门关闭时,大坝匝门也关闭,水流就不能从上游流到下游去,对应三极管,即没有IB,则也没有IC,这一区域称为“截止区”;转动阀门,大坝的匝门也跟着开启,阀门拧的圈数越多,匝门的开合度也越大,从上游到下游的水流也越大,对应三极管,则为Ic=βIb,这一状态称为“放大区”;当大坝匝门完全开启,再拧阀门,匝门的开合度已经到了最大值,水流不能再增大了,对应三极管,即当Ic的值到了极限时,Ib再增大,Ic也不再跟着增大了,这一区域称之为“饱和区”。

下面结合图2.3.2的电路通过实验对三极管的三个区做一下测试。

 

(a)实验原理图(b)在面包板上实验测数据

图2.3.2三极管特性实现

电路讲究理论与实践的统一,说白了就是在学完理论后,只要有条件,一定要动手做实验,来验证理论的正确性,这样才会真正理解电路的特性。

对于一些简单的实验,推荐使用如图2.3.2所示的面包板板来验证。

图中三极管型号为较为常用的直插中小功率NPN三极管8050,VCC=5V。

基极限流电阻Rb,阻值10KΩ,,集电极电阻RC阻值510Ω。

三极管的基极电压由3296电位器提供,通过旋转电位器,不断调整A点电位,让A点电位以0.2V的步进升高,从0V到5V,,然后用万用表测试A点、B点和C点电压,Ib=(Ua-Ub)/Rb,Ic=(VCC-Uc)/Rc,β=Ic/Ib。

表2.3.1三极管实现数据表

Ua(V)

Ub(V)

URb(V)

Ib(uA)

Uc(V)

URc(V)

Ic(uA)

β

0.203

0.203

0

0

5

0

0

0

0.401

0.401

0

0

5

0

0

0

0.598

0.556

0.042

0.567

4.984

0.016

31.372

55.3

0.812

0.62

0.192

2.594

4.722

0.278

545

210

1.003

0.638

0.365

4.932

4.406

0.594

1165

236

1.201

0.648

0.553

7.473

4.091

0.909

1782

238

1.399

0.655

0.744

10.054

3.785

1.215

2382

239

1.602

0.662

0.94

12.702

3.455

1.545

3029

238

2.001

0.671

1.33

12.792

2.802

2.198

4309

239

2.403

0.678

1.725

23.311

2.171

2.829

5547

236

2.799

0.686

2.113

28.554

1.566

3.434

6733

236

3.206

0.692

2.514

33.972

0.961

4.039

8078

238

3.602

0.698

2.904

39.243

0.412

4.588

8996

229

4.003

0.702

3.301

44.608

0.171

4.829

9468

212

4.201

0.702

3.499

47.283

0.143

4.857

9523

201

4.392

0.703

3.689

49.851

0.135

4.865

9539

191

4.597

0.703

3.894

52.621

0.132

4.868

9545

181

4.797

0.703

4.094

55.324

0.129

4.871

9550

173

4.985

0.703

4.282

57.864

0.124

4.876

9560

165

当A点电压<0.598V时(A点电压为0.203V和0.401V),B点电压和A点电压相同,C点电压与电源VCC相同,这说明在这段区间内,基极电流为0(电阻Rb上没有压降),集电极电流也为0(电阻Rc上没有压降)。

这段区域我们称之为截止区。

当A点电位超过0.6V后,基极和集电极都有电流,而且在一段区间内,随着输入电压的提高,集电极电流和基极电流都跟着升高,但其比值是不变的(β=238)。

三极管的输出端满足VCC=Ic*Rc+UCE,URc升高,UCE下降,这段区域我们称之为放大区,Ic=βIb。

由关系式VCC=Ic*Rc+UCE可以看出,随着Ic的增大,UCE减低,当UCE接近0V时,Ic到达最高值,再往后,集电极电流不再跟随基极电流变化。

从实验数据可以看出,A点电压超过4V后,C点电位下降至0.1V后,集电极电流和基极电流不再成比例关系。

这段区域我们称之为饱和区。

基极电流再升高,UCE间始终存在0.1V左右的电压,我们称之为饱和压降。

在单片机应用电路中,三极管作为开关管来使用,三极管工作于截止区和饱和区。

在截止区时,三极管的CE之间如同一个开关断开时,CE之间没有电流通过;而在饱和区时,三极管的CE之间如果一个开关导通一样,CE之间以最大电流通过,所以我们把三极管工作于这两个区的状态称之为开关。

(2)D触发器

在实际的数字系统中往往包含大量的存储单元,而且经常要求他们在同一时刻同步动作,为达到这个目的,在每个存储单元电路上引入一个时钟脉冲(CLK)作为控制信号,只有当CLK到来时电路才被“触发”而动作,并根据输入信号改变输出状态。

把这种在时钟信号触发时才能动作的存储单元电路称为触发器。

D触发器是触发器的一种。

图2.3.2是D触发器的内部构造图。

图2.3.2D触发器内部构造

D触发器的方程为Q=D,即输出Q的值等于输入D的值,但这种情况只发生在时钟的上升沿。

在时钟上升沿到来之前,即使输入发生改变,输出也不会立即改变。

(3)P1口、P2口和P3口的内部构造

51单片机的P1口、P2口和P3口的构造大同小异,在这里暂且把他们当成是同一类型。

图2.3.3中是这些I/O口的内部构造图。

在图2.3.3中,P1、P2、P3口输出端是一个接上拉电阻的MOS管,漏极输出,考虑到初学者对MOS管不太熟悉,而MOS管和三极管的外特性相似,我们暂且把MOS管当成是NPN型的三极管来讲解,即图中三极管发射极接地,集电极输出电平。

我们要把I/O口置成高电平,需要在程序中对I/O口写“1”,D锁存器的输入端为高电平“1”,则D触发器的反相输出端输出低电平,则NPN三极管截止,输出端对外呈现高电平;反之,当我们在程序中写“0”,D触发器的反相端输出高电平,三极管饱和导通,输出低电平。

因内部上拉电阻R的阻值较大,所以称之为弱上拉输出。

图2.3.3P1、P2和P3口的内部构造

(4)P0内部构造

图2.3.4是P0口的内部构造图。

与P1、P2和P3口相比,P0口构造比较特殊。

P0口既可以作为普通I/O口使用,也可以作为扩展存储器的地址/数据线使用。

P0口怎样作为地址/数据总线来使用,我们暂且不要理会,但地址/数据总线的输出形式值得一提,从图上可以看出,MUX开关打向上边,IO作为地址/数据用,MOS管T1和T2轮流导通,这种形式成为推挽输出。

这种双管轮流导通的方式是AVR/PIC等单片机I/O口输出的主要形式,输出和输入都具有大电流。

P0口用作普通I/O时,MUX开关打向D锁存器的输出端,D锁存器只能控制MOS管T2,对MOS管T1不起作用,MOS管T1截止。

P0口用作普通I/O时,和P1、P2和P3口类似,不同之处在于,由于MOS管T1截止,MOS管T2没有电源和上拉电阻,即T2漏极开路,。

所以P0口作为普通IO使用,还需在P0口的外部接上拉电阻。

我们的开发板上外接了5.1K的排阻。

图2.3.4P0口内部构造

图2.3.4P0口内部构造

2、拉电流与灌电流

拉电流和灌电流是衡量数字电路输出驱动能力的参数。

数字电路的输出只有高、低(即“0”和“1”)两种电平值,高电平输出时,一般是输出端对负载提供电流,其提供电流的叫“拉电流”;低电平输出时,一般是输出端要吸收负载的电流,其吸收电流的叫“灌电流”。

如图2.3.5所示。

 

图2.3.5拉电流和灌电流

灌电流越大,输出端MOS管的饱和压降就会越大,则输出低电平则会变高,数字电路的低电平是有一定限制的,它有一个最大值UOLMAX。

电路工作时,不允许超过这个数值,TTL逻辑门的规范规定UOLMAX≤0.4~0.5V。

所以,灌电流有一个上限,灌电流太大,不仅会使I/O输出端电压升高,而且还可能使I/O烧坏。

拉电流越大,输出端的高电平就越低。

这是因为MOS管的输出端有上拉电阻的原因,输出电流越大,上拉电阻上的压降也会越大,则对外输出的电压越低。

数字电路的高电平有一个最小值UOHMIN。

工作时,不允许超过这个数值,TTL逻辑门的规范规定UOHMIN≥2.4V。

所以,拉电流也有一个上限。

3、STC89C52的拉电流和灌电流大小

STC89C52的官方手册并没有给出I/O的拉电流和灌电流的大小,只是说和传统8051单片机一样,是弱上拉。

表2.3.2是拉电流的测试数据,测试方法是在P20引脚外接一个电阻,电阻另外一端接地,用万用表测试一下P20引脚的电压,然后换其它阻值的电阻测试。

表2.3.3是灌电流的测试数据,测试方法是类似拉电流的测试,不同之处在于电阻的另外一端接电源VCC。

表2.3.2拉电流测试数据表2.3.3灌电流测试数据

电阻(Ω)

I/O电压(mV)

输入电流(mA)

5K

75

0.985

1K

347

4.653

500

722

8.556

电阻(Ω)

I/O电压(V)

输出电流(uA)

95K

4.594

48

32K

4

125

21K

3.5

166

从表2.3.2和表2.3.3中可以看出STC89C52的灌电流和拉电流能力都比较弱,但相比较而言,灌电流要远远大于拉电流,拉电流是uA级别的,而灌电流是mA级别。

另外根据表2.3.2中的数据计算,STC89C52单片机I/O中内置上拉电阻的阻值在7-10KΩ左右。

通过实验分析,就不难解释为什么我们在驱动发光二极管时,采用低电平驱动而不是高电平驱动了。

由于STC89C52的上拉电阻在10K级别,就算不接限流电阻,发光二极管也不会被点亮。

4、C语言中的位运算

流水灯的程序实现有两种方法,其中之一是采用移位的方法。

C语言中的位运算在单片机程序中格外重要,程序中到处可见位运算,我们先了解一下C51的位运算种类和特点。

C51提供了几种位操作符,如下表所示:

表2.3.2C语言中的位运算符号

运算符

含义

运算符

含义

&

按位与

~

取反

|

按位或

<<

左移

^

按位异或

>>

右移

 

(1)“按位与”运算符(&)

参与与操作的两个位,原则是全1为1,有0才为0,即:

0&0=0;0&1=0;1&0=0;1&1=1。

如下例:

a=0x05&0x03,即a=(0b0101)&(0b0011)=0b0001。

(2)“按位或”运算符(|)           

参与或操作的两个位,原则是有一个为1,则结果为1,全0为0。

即:

0|0=0;0|1=1;1|0=1;1|1=1。

例如:

a=0x30|0x0f;即a=(0b00110000)|(0b00001111)=(0b00111111)=0x3f。

(3)“异或”运算符(^)

异或运算符^又被称为XOR运算符。

当参与运算的两个位相同(‘1’与‘1’或‘0’与‘0’)时结果为‘0’。

不同时为‘1’。

即相同为0,不同为1。

0^0=0;0^1=1;1^0=1;1^1=0。

例如:

a=0x55^0x3f;即a=(0b01010101)^(0b00111111)=(0b01101010)=0x6a。

(4)“取反”运算符(~)

与其它运算符不同,“取反”运算符为单目运算符,即它的操作数只有一个。

它的功能就是对操作数按位取反。

也就是是‘1’得‘0’,是‘0’得‘1’。

如下例:

a=0xaa;a=0b10101010,

b=~a,则b=0b01010101。

(5)左移运算符(<<)

左移运算符用来将一个数的各位全部向左移若干位。

如:

a=a<<2,表示将a的各位向左移2位,右边补0。

如a=34(0b00100010),左移2位得0b10001000。

  

(6)右移运算符(>>)

右移与左移相类似,只是位移的方向不同。

如:

a=a>>2,表示将a的各位向右移动2位,左边补0。

如a=34(0b00100010),左移2位。

得0b10001000。

5、C运算符

位运算属于C众多运算符中的一种,除了位运算,还有算术运算符、关系运算符、逻辑运算符等。

(1)算术运算符

算术运算符用于各类数值运算,包括加(+)、减(-)、乘(*)、除(/)、求余(%)、自增(++)、自减(—)。

在C语言中,乘法运算符为“*”,不能写成数学中的“×”,除法运算符为“/”,不能写成“÷”。

对于“/”运算符,C语言规定,当它的两个运算分量都为整数时,其结果为整数,如果两个运算分量其中一个为浮点数时,则结果为浮点数。

“%”运算符,是用来求两个数相除后的余数,相处的两个数必须为整形数据。

“++”和“—”是C语言中的自增运算符,如a++,++a。

其中a++是表示先使用a的值,再加1,++a表示先加1,再使用a的值。

“—”的用法和“++”类似,是自减1。

下面是算术运算符的举例。

5+3:

结果为5;5-3:

结果为2;5*3:

结果为15;5/3:

结果为1;5++:

结果为6。

(2)关系运算符

C语言提供6种关系运算符,分别是大于(>)、大于等于(>=)、小于(<)、小于等于(<=)

、等于(==)、不等于(!

=)。

需要注意的等于运算符,是双等于号,不是单个等号,单个等号是赋值。

关系运算符的结果只有两种,0(假)和1(真)。

关系成立为1,不成立则为0。

如100>=20,结果1;7==3,结果为0;‘a’<’A’,结构为0。

(3)逻辑运算符

逻辑运算符有三种,分别是逻辑与(&&)、逻辑或(||)和逻辑非(!

),注意和位运算的区别。

逻辑运算的结果只有两种:

0(假)和1(真)。

具体功能如表2.3.4所示:

表2.3.4逻辑运算符

a

b

a&&b

a||b

!

a

 

6、数组

流水灯实现的第二种方法是采用取表的方式。

我们这里所谓的“取表”实际上就是C语言中的数组。

在程序设计中,为了处理方便,把具有相同类型的若干变量按有序的形式组织起来,这些按序排列的同类数据元素的集合称为数组。

C语言支持一维数组和多维数组。

我们这里先来学习简单的一维数组。

(1)一维数组的定义方式

在C语言中使用数组必须先进行定义,才能使用。

一维数组的定义方式为:

类型说明符数组名[常量表达式];

其中,类型说明符是任一种基本数据类型或构造数据类型。

数组名是用户定义的数组标识符。

方括号中的常量表达式表示数据元素的个数,也称为数组的长度。

例如:

inta[10];/*整型数组a,有10个元素*/

charch[20];/*字符数组ch,有20个元素*/

需要说明几点,类型说明符实际是数组元素的取值类型,数组名的书写规则遵循标示符的规定,方括号中的常量表达式用来表示数组中元素的个数,如a[5]表示数组中有5个元素,但是其下标从0开始计算,因此5个元素分别是a[0]、a[1]、a[2]、a[3]、a[4]。

(2)一位数组的初始化

数组赋值既可以在定义的时候给数组元素赋初值,也可以在定义后用赋值语句逐个赋值。

初始化赋值的一般形式为:

类型说明符数组名[常量表达式]={值,值……值};

其中在{}中的各数据值即为各元素的初值,各值之间用逗号间隔。

例如:

inta[10]={0,1,2,3,4,5,6,7,8,9};相当于a[0]=0;a[1]=1...a[9]=9;

另外数组在初始化的时候,[]内数组元素的个数可以不写,编译系统会根据{}内数据的个数计算数组元素的个数。

(3)一位数组的引用

数组元素引用的一般形式为:

数组名[下标]。

其中下标只能为整型常量或者整型表达式,不能为变量。

7、选择语句

C语言的选择语句中包括if语句和switch语句。

我们先来看一学习一下if语句。

if构成的选择语句有3种类型。

(1)第一种类型是判断是否满足某个条件,满足则执行相应的动作。

其功能模型如下:

if(条件)

{

执行动作

}

 

(2)if语句的第二种类型是在第一种类型的基础之上,又加入了一个条件。

判断是否满足某个条件,满足则执行动作1,不满足,则执行动作2。

其功能模型如下:

if(条件)

{

执行动作A

}

else

{

执行动作B

}

 

if(条件A)

{执行动作A};

elseif(条件B)

{执行动作B};

elseif(条件C)

{执行动作C};

else

{执行动作D};

(3)if语句的第三种类型是有多种条件可供选择,执行某个条件下的相应指令,如果条件A满足,则执行动作A,然后退出,不满足则判断条件B是否满足,依次进行下去。

其功能模型如下:

 

另外执行动作语句只有一个,则{}可以省略。

三、任务实施

1、移位方式实现流水灯程序

#include

#defineucharunsignedchar

#defineuintunsignedint

sbitInput=P1^0;//外接电平输入端

voiddelay_ms(uintxms)//ms级延时函数

{

uinti,j;

for(i=0;i

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

}

voidmain()

{

uchari=0;

uchartemp;

while

(1)

{

if(keyy==1)//流水灯从右向左移动

{

temp=0x01;//temp初值

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

{

P2=~temp;//temp取反后,赋值给P2口

delay_ms(1000);//延时1000ms

temp=temp<<1;//temp左移一位

}

else//流水灯从左向右移动

{

temp=0x80;

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

{

P2=~temp;

delay_ms(1000);

temp=temp>>1;

}

}

}

 

程序解释:

例程中,根据输入IO的电平(P10引脚外接电平),分为流水灯向左移和向右移,外接高电平时,向左移,外接低电平时,向右移。

表2.3.5是向左移中temp变量和P2赋值的状态,表2.3.6是向右移中temp变量和P2赋值的状态。

表2.3.5流水灯左移表2.3.6流水灯右移

i

Temp(左移)

P2=~temp

0

0000,0001

1111,1110

1

0000,0010

1111,1101

2

0000,0100

1111,1011

3

0000,1000

1111,0111

4

0001,0000

1110,1111

5

0010,0000

1101,1111

6

0100,0000

1011,1111

7

1000,0000

0111,1111

i

Temp(右移)

P2=~temp

0

1000,0000

0111,1111

1

0100,0000

1011,1111

2

0010,0000

1101,1111

3

0001,0000

1110,1111

4

0000,1000

1111,0111

5

0000,0100

1111,1011

6

0000,0010

1111,1101

7

0000,0001

1111,1110

 

2、取表方式实现流水灯程序

#include

#defineucharunsignedchar

#defineuintunsignedint

sbitkeyy=P1^0;

//数组里存放LED发光二极管的8个状态所对应的码值

ucharcodetable[]={0xfe,0xfd,0xfb,0xf7,0xef,0

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

当前位置:首页 > 高等教育 > 艺术

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

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