矿石收音机论坛

 找回密码
 加入会员

QQ登录

只需一步,快速开始

搜索
查看: 20893|回复: 47

考拉聊单片机3

[复制链接]
发表于 2010-12-7 15:51:34 | 显示全部楼层 |阅读模式
上回聊了单片机的一些基本概念,见:

http://www.crystalradio.cn/bbs/thread-155177-1-1.html

这回聊聊单片机到底是如何干活的?也就是这个小玩意是如何工作的。

1、从哪里开始?

任何事情总有一个开头,单片机也不例外,怎么样的开头呢?想想一个小孩醒来第一件事作什么?一般情况是先找妈妈,然后妈妈告诉他要作什么事,如何去作(考拉喜欢用小孩来比单片机,因为单片机很象心智未开的小宝宝,什么都得你替他安排,教他去作)。如果我们把妈妈理解为小孩的程序(告诉他要作的每件事的每一个步骤),那么小孩子就必须先找到妈妈所在的地方。

单片机其实也一样,它只要一醒来(加上电源),首先也要到一个固定的地方找程序,看看有没有指令要执行。这个地方当然是位于单片机程序存储器内的某个地方,不同的单片机不一样,多数是程序存储器寻址空间的最开头(如0000H,这是16进制,概念和为啥要加个H后面再说),有的在其他地方(象PIC16C5x)。这个地址就是单片机运行程序开始的地方,也就是程序的入口地址,有些书上也叫复位矢量或复位向量

知道了单片机是从哪里开始的,那么我们也就清楚了一件事:如果要让单片机正确的运行,就必须把所编程序的第一条指令放在程序入口地址(复位矢量)处

2、如何自动工作?

有了开头下来单片机该干活了,怎么干呢?假如一个小孩子作事情每作一步都停下来等你的指示,你会不会有些烦?就象俗话说的碗里的芋头筷子拨一下动一下。我们当然希望能一次告诉他所有要作的事情,然后他自己按步骤去完成。能不能实现自动化呢?当然可以,但需要一些辅助手段。

当单片机在程序入口处找到了程序的第一条指令执行后,如果要实现自动运行而不是等你的命令,它就必须知道下一条指令在什么地方。同理,如果要保证整个程序的自动执行,单片机必须在取得一条指令并执行后知道下一条指令放在什么地方。怎么实现呢?最直接的办法当然是在当前指令里附上下一条指令的存放地址(早期的计算机就有这么干的),但这样一来指令会变得很长,费空间不说执行速度也慢。于是后来人们想了另外一个办法,在计算机内设置了一个程序计数器(Program Counter,缩写为PC),在PC里存入下一条要执行的指令的地址。单片机里也有一个PC,它每到PC里记录的地址处取一条指令,PC就自动加1指向下一条指令的地址,从而实现了程序的自动执行。但上面的这个设计只适应于程序的指令是按顺序指行的情况,如果因为某种需要不能按顺序执行需要跳转到程序的另一段怎么办呢?也简单,只要在需要跳转的地方由特殊的指令修改PC的值,变为要跳转执行的程序段的第一条指令存放地址就行了。

PC就象整个单片机运行的指挥官,指挥着单片机的自动运行。明白了这个前面讲的复位后的程序入口地址也就更好理解了,只要单片机在上电复位时给PC设置为程序入口的地址(复位矢量),单片机就自动到那里去找指令了。此外理解了PC的概念也就明白了单片机程序寻址空间的由来。PC的长度决定了可以存放地址的大小,所以由PC的字长就决定了程序寻址空间的大小。象标准51的PC是16位的,故51的程序寻址空间就是64K了。计算方法如下:16位2进制最大计数值是10进制的65535,加上0(因为是从0而不是从1开始计数的)是65536个,而计算机里的1K=1024(2的10次方),65536除以1024等于64,也就是64K了。

3、怎样步调一致?

从前面这些描述,你一定也已经明白单片机内部是一个挺复杂的结构,有很多东西在协同工作来完成各种功能。这就有了一个问题,这个不同的部件如何协同工作而不发生错误呢?比如当前一条指令还没取(地址还没用)但PC已经提前加1指向了下一条指令岂不乱套!也就是说这些部件有一个协同工作步调一致的问题。

想想舞台上的小乐队是如何同步的呢?一般是听鼓手的鼓点。而舞池里的众人如何一起跳舞呢?当然是听乐曲的节奏。也就是说生活中我们往往需要一个节奏来供大家协同,单片机其实也一样,这个节奏就是单片机的时钟。单片机内部的各个部件在时钟的统一节奏下按部就班的工作,保证了互相的配合与协同。同时时钟也决定了单片机工作的速度,时钟越快速度也就越快

单片机的时钟可以由外部提供,也可以由内部电路提供。外部提供时由一个专门的时钟脉冲电路产生时钟信号注入单片机。内部电路提供时有几种情况,最常见的是振荡电路内部已经集成,但晶振和微调电容需要外接。常用的晶振有4M/6M/8M等,51常用6M和12M,这和其内部的时序设计有关(后面再细说)。还有一些非整数晶振也常用,比如11.0592,为什么要用这种晶振呢?这是为了串行通讯的需要,这些频率分频后能够精确的产生串行通讯所需要的波特率(这个概念后面聊到串行异步通讯时再说)。一些比较新的单片机(如AVR M8)可以由内部集成的电路(一般是一个RC振荡电路)产生时钟信号,因此设置好后不用外接晶振也能工作。

4、正确的开始很重要

前面已经说了加电后单片机内部是怎么运作的。但熟悉模拟电路的都知道当电源启动后到电压上升达到稳定是有一个时间的,虽然时间很短但在这个期间还是会有一些波动以及电压达不到预定值等问题。从前面单片机用的时钟晶振就可以知道单片机运行的速度是很快的,虽然电源达到稳定的时间短,但这段时间已经足够单片机作很多事情了。假如电压不稳定而单片机已经开始干活,就可能因为电源的各种问题给单片机的工作带来干扰,甚至产生运行错误。

如何避免呢?最简单的办法当然是等电源电压稳定了再干活,因此单片机就需要一个上电复位电路。单片机一般都有一个复位引脚,叫作RESET/RST或其他名字,当这个引脚接上预定的高电平或低电平(这个词后面再解释)时,单片机就复位,回到刚加电的状态,进行内部初始化,并重新到复位矢量处去从头执行程序。因此只要在系统加电时让复位引脚保持在复位电平一段时间,等到电源稳定再撤销,就可以实现正确的上电复位。简单的上电复位电路可以用一个电容和一个电阻构成,上电时由于电容充电让复位引脚保持在复位电平,充满电后自动撤销进入正常运转。例如51是高电平复位,就可以让RST(51的复位引脚)通过电容(常用10uF或22uF)接VCC(电源正极),同时通过一只电阻(常用1K欧或10K欧)接到GND(电源负极,也即地线),上电时电容充电使RST保持高电平处于复位状态,充满电后由于接地的电阻使RST处于低电平进入正常运行,电容的容量和电阻的大小决定了上电复位的时间。只要电容和电阻构成复位电路的充电时间大于电源电压稳定所需要的时间,就可以保证单片机的正确复位

除了这种简单的电路还有一些专用的单片机复位集成电路,可以更可靠的为单片机提供上电复位服务。此外一些比较新的单片机如AVR M8和PIC等内部集成了上电复位电路,可以使单片机上电后延时一段时间再开始工作,因此这些单片机只要设置正确不用外部复位电路也能正常工作。

5、哪些是必须的?

从前面聊的这些我们已经知道单片机要干活除了电源还是需要一些外部条件的。首先需要一个时钟,比如51要外接一个晶振和俩微调电容(常用30PF);其次需要一个上电复位电路以保证可靠的复位。有了这些单片机就已经准备好可以接受程序工作了,因此以上这些就可以称为单片机的最小系统,基本是由单片机本身,时钟电路,上电复位电路三者构成。后面附了一张参考图,是网上找的。注意图上多接了一根线,EA脚(右边中间部位)也接了VCC电压,为什么要接这根线后面再说,这里不必深究。

注意最小系统不是一个固定的概念,不同的单片机可能最小系统构成不同,同样的单片机可能设置方式不同最小系统构成也不同。简单到极致时钟和上电复位全部用内部集成的,一个芯片就已经是最小系统了。所以最小系统应该理解为可以保证可靠的上电复位以及正常运行的最小系统构成

另外注意这里说的最小系统和一些市售最小系统板的区别。这里的最小系统是一个理论上的概念,而市售的最小系统是一个实验中的概念。这些最小系统板除了前面说的理论上的单片机最小系统外,一般还集成了供电系统、串行通讯系统、程序下载系统、以及总线驱动系统等(根据设计和需要会有一些取舍)。这些可以为你的实验提供可靠的保证,是一个实验应用中比较完备的单片机最小核心系统。


好了,单片机的基本运作模式已经把最基本的说差不多了,下面举一个实例具体说说单片机怎么干活。就举一个最简单的例子吧,单片机如何让一颗LED闪烁星星之火可以燎原,相信考拉,只要你能让单片机点亮一只LED,就一定能够让它干更多更复杂的事情!

如何让一只LED闪烁呢?答案很简单,只要打开、关闭,再打开、再关闭不断重复就是了。别把很多问题想得太复杂,其实有时就和怎样把大象放进冰箱里一样简单,哈哈。虽然答案很简单,但如果直接让单片机这么干你是肯定看不到想要的结果的,原因就是单片机运行的太快了,运行一条指令的时间是以微秒计的。如果只是简单的打开和关上,你肯定会看到LED仍然是一直亮着,最多由于高速的打开和关闭亮度变暗了一点。

如何才能看到闪烁呢?也很简单,只要让打开和关闭的时间都长一点就是了。也就是在打开和关闭LED的命令间插入一段延时就行了,比如半秒(也就是500毫秒,写为500ms)。这样我们就可以得到一个闪烁的工作步骤:

第一步:打开LED;
第二步:延时500ms;
第三步:关闭LED;
第四步:延时500ms;
…………

只要不断重复下去就可以看到LED闪烁了。但这也带来了一个问题,就是程序好象是无限延续的,这可不成,程序存储器可不是无限的呀。我们可以稍稍改动一下变成如下的样子:

第一步:打开LED;
第二步:延时500ms;
第三步:关闭LED;
第四步:延时500ms;
第五步:返回第一步;

这样我们就能在有限的程序长度内完成无限时长的事情了,这就是循环。计算机是最擅长循环的,它既不会觉得累也不是觉得烦,很多问题的解决都需要循环执行一段程序来完成,后面还会大量遇到。这段程序还有一个问题,就是延时500ms重复出现了,很浪费,因此我们可以把这段程序作为子程序(也就是一个标准模块)来调用,具体调用的机制和方法后面再说,这里只要知道个意思就行,最后就成了这个样子:

第一步:打开LED;
第二步:调用延时500ms子程序;
第三步:关闭LED;
第四步:调用延时500ms子程序;
第五步:返回第一步;

延时500ms子程序:…………

上面这个结构已经是一个可以实用的程序逻辑结构了,但这个东西单片机是不认识的,下面给出一个实现上述功能的51汇编例程,注意俺没有经过实际运行测试,这也只是一个汇编程序段而不是一个完整的51汇编程序,只用来表述逻辑结构。假设LED接在51的P1.0引脚(P1口的第1个引脚,是51芯片的左边从上向下数第1个引脚)上,低电平LED亮。例程如下:

begin:
        clr P1.0                      ;设置P1.0为低电平,点亮LED
        acall delay500ms       ;调500毫秒延时子程序
        setb P1.0                    ;设置P1.0为高电平,熄灭LED
        acall delay500ms       ;调500毫秒延时子程序
        ajmp begin                 ;重头再来
;===============================
delay500ms:                       ;6M下延时500ms子程序,实际程序多延时48微秒
        mov temp0,#05h         ;temp=5
delay500ms_1:
        mov temp1,#64h         ;temp1=100
delay500ms_2:
        mov temp2,#0f8h        ;temp2=248,外层循环DJNZ补上后循环体刚好1ms
        djnz temp2,$
        djnz temp1,delay500ms_2
        djnz temp0,delay500ms_1
        ret                               ;返回调用处继续执行
;===============================
        end

稍说明几句,因为51上电复位后I/O口是都是高电平,而前面已经说明LED是低电平点亮,所以上电后LED是不亮的。而clr P1.0这句是把这个引脚设置为低电平,这样LED就亮了,setb P1.0则是把这个引脚设置为高电平,LED也就灭了。其他指令不必深究,后面再细说,大致明白单片机是这么干活的就行了。

今天就先说到这里了,下次聊聊用什么来指挥单片机干活,且听下回分解。

http://www.crystalradio.cn/bbs/viewthread.php?tid=156114

[ 本帖最后由 cosine 于 2010-12-11 14:03 编辑 ]

51单片机最小系统

51单片机最小系统
 楼主| 发表于 2010-12-7 15:52:59 | 显示全部楼层
先占一层楼备用.

可能有些错误,要出门去买点东西,回来再修订一遍.

评分

1

查看全部评分

回复 支持 反对

使用道具 举报

     
发表于 2010-12-7 17:25:57 | 显示全部楼层
继续坐在沙发上听课。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2010-12-7 18:06:30 | 显示全部楼层
原帖由 九段 于 2010-12-7 17:25 发表
继续坐在沙发上听课。


刚刚修订了一下,有些小改动,加了一张图。
回复 支持 反对

使用道具 举报

发表于 2010-12-7 19:00:30 | 显示全部楼层
坐在前排认真听讲 .听懂和记住就要努力了
回复 支持 反对

使用道具 举报

发表于 2010-12-7 19:59:22 | 显示全部楼层
好好学习一下.请问版主这个是每日一讲吗?
回复 支持 反对

使用道具 举报

     
发表于 2010-12-7 20:48:59 | 显示全部楼层
学习。请教下版主,用单片机控制led的问题。
单片机i/o口输出是5v电压,但因为led很多串联并联在一起,要用12v电压供电,我想用2个电源,一个给单片机(5v),一个给led灯(12v),电路要怎么设计好呢?上网找了些资料,场效应管,继电器,。。。不知道用哪个好,要怎么接线?
led灯是从 http://www.crystalradio.cn/bbs/thread-133523-1-1.html 买的,一板有63个led。4根线,1根正,3根控制显示红绿蓝三种灯(接i/o口)。


[ 本帖最后由 creatoryy 于 2010-12-7 20:52 编辑 ]
回复 支持 反对

使用道具 举报

 楼主| 发表于 2010-12-7 20:53:44 | 显示全部楼层
原帖由 不山不市 于 2010-12-7 19:59 发表
好好学习一下.请问版主这个是每日一讲吗?


不定期,有空了就写一点,这两天时间多两三天写一次,后面忙了可能就成周刊月刊了.
回复 支持 反对

使用道具 举报

 楼主| 发表于 2010-12-7 20:59:34 | 显示全部楼层
原帖由 creatoryy 于 2010-12-7 20:48 发表
学习。请教下版主,用单片机控制led的问题。
单片机i/o口输出是5v电压,但因为led很多串联并联在一起,要用12v电压供电,我想用2个电源,一个给单片机(5v),一个给led灯(12v),电路要怎么设计好呢?上网找了些资料, ...


这个应该不难,12V和5V共地,用9013/8050这类NPN三极管,发射极接地,集电集接LED的控制端(用三只三极管),基极通过1只电阻接单片机I/O,单片机输出正电平时导通.不过单片机复位时I/O是高电平,所以一通电LED肯定会亮一下.基极接的电阻你先接4.7K试试行不行,不行再减小试试.这些就是模电计算了,看看LED的工作电流是多大,三极管放大倍数是多少.三极管是当开关管用的.
回复 支持 反对

使用道具 举报

     
发表于 2010-12-7 21:07:20 | 显示全部楼层
谢谢版主,先回去试试。
回复 支持 反对

使用道具 举报

发表于 2010-12-7 21:07:58 | 显示全部楼层
不错!通俗易懂!
回复 支持 反对

使用道具 举报

     
发表于 2010-12-7 21:33:26 | 显示全部楼层
看楼书的图片怎么像是杜洋的啊???
回复 支持 反对

使用道具 举报

 楼主| 发表于 2010-12-7 22:06:49 | 显示全部楼层
原帖由 lxa000 于 2010-12-7 21:33 发表
看楼书的图片怎么像是杜洋的啊???


用GOOGLE在网直接找了一张,觉得合用就贴上了,没看原始出处.有版权纠纷吗?如果有的话我换一张就是了.
回复 支持 反对

使用道具 举报

     
发表于 2010-12-7 22:37:50 | 显示全部楼层
很弱智的问一下~电容有极性么?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2010-12-7 22:40:31 | 显示全部楼层
原帖由 生活的旋律 于 2010-12-7 22:37 发表
很弱智的问一下~电容有极性么?


有的有,有的没有.大容量的多数有,象铝电解和钽电容.小容量的一般没有,象常用的磁片和独石.
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 加入会员

本版积分规则

小黑屋|手机版|矿石收音机 ( 蒙ICP备05000029号-1 )

蒙公网安备 15040402000005号

GMT+8, 2024-3-28 23:27

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表