求单片机流水灯程序程序

单片机程序设计方法
第十六课 单片机程序设计方法
程序设计是单片机开发最重要的工作
程序设计就是利用单片机的指令系统
根据应用系统即
目标产品的要求编写单片机的应用程序
其实我们前面已经开始这样做过了
这一课我们不是讲如何 来设计具体的程序
而是教您设计单片机程序的基本方法
不过在讲解之前还是有必要先了解一下单片
机的程序设计语言
程序设计语言
这里的语言与我们通常理解的语言是有区别的
它指的是为开发单片机而设计的程序语言
如果 您没有学过程序设计可能不太明白
我给大家简单解释一下
您知道微软的 VB
VC 就是为 某些工程应用而设计的计算机程序语言
它是一种设计工具
只不过这种工具是用来设计计
算机程序的
要想设计单片机的程序当然也要有这样一种工具说设计语言更确切些单片机的设计 语言基本上有三类
完全面向机器的机器语言
机器语言就是能被单片机直接识别和执行的语言
计算机能识别什么
以前我们讲过--是数字
1所以机器语言就是用一连串的
来表示的数字
用机器语言 来表示就是
用机器语言来编写单片机的程序不太方便
也不好记忆
们必须想办法用更好的语言来编写单片机的程序
于是就有了专门为单片机开发而设计的语言
汇编语言也叫符号化语言
它使用助记符来代替二进制的
40H 就是汇编语言指令
显然用汇编语言写成的程序比机器语言好学也好记
所以单片机的指令普遍采 用汇编指令来编写
用汇编语言写成的程序我们就叫它源程序或源代码
可是计算机不能识别和执行用 汇编语言写成的程序啊
当然有办法
我们可以通过
把源代码译成机器语言
这个过 程就叫做汇编
汇编工作现在都是由计算机借助汇编程序自动完成的
不过在很早以前
它是靠手工来 做的
我也没经历过
值得注意的是
汇编语言也是面向机器的
它仍是一种低级语言
每一类计算机都有它自己的汇 编语言
51 系列有它的汇编语言
PIC 系列也有它的汇编语言
微机也有它自己的汇编语言
它 们的指令系统是各不相同的
不同的单片机有不同的指令系统
它们之间是不通用的
这就 是为什么世界上有很多单片机类型的缘故了
为了解决这个问题
人们想了很多的办法
设计了许多的 高级计算机语言
而现在最适合单片机编程的要数 C 语言
C 语言―高级单片机语言
语言是一种通用的计算机程序设计语言
它既可以用来编写通用计算机的系统程序
也可以用 来编写一般的应用程序
由于它具有直接操作计算机硬件的功能
所以非常适合用来编写单片机的程序
与其他的计算机高级程序设计语言相比
它具有以下的特点
1语言规模小
在现有的计算机设计程序中
C 语言的规模是最小的
ANSIC 标准的 C 语言一共只有 32 个关键字
9 种控制语句
然而它的书写形式却比较灵活
表达方式简洁
使用简单的方法就可以构造出相当复杂 的数据类型和程序结构
2可以直接操作计算机硬件
C 语言能够直接访问单片机的物理空间地址KEIL
C51 软件中的 C51 编译器更具有直接操作 51
单片机内部存储器和 I/O 口的能力亦可直接访问片内或片外存储器
还可以进行各种位操作
3表达能力强
表达方式灵活
C 语言有丰富的数据结构类型
可以采用整型
枚举类型等多种数据类型来实现各种复杂数据结构的运算
利用 C 语言提供的多种运算符
我们可以组成各种表达式
还可以采用多种方法来获得表达式的值
从而使程序设计具有更大的灵活性
----------------
4可进行结构化设计
结构化程序是单片机程序设计的组成部分
语言中的函数相当于汇编语言中的子程序
C51 的编译器提供了一个函数库
其中包含有许多标准函数
如各种数学函数
标准输入输出函数等
此外还可以根据用户需要编制满足某种特殊需要的自定义函数
C 语言程序就是由许多个函数组成的
一个函数即相当于一个程序模块
所以 C 语言可以很容易地进行结构化程序设计
前面我们讲过
由于单片机的结构不同
所以不同类型的单片机就要用不同的汇编语言来编写程
而 C 语言则不同
它是通过汇编来得到可执行代码的
所以不同的机器上有 80%的代码是公用的
下册中专门来讲解 C 语言的应用及其编程原理
不过作为单片机初学者想要学会 C 语言也并不是一件容易的事
因此对于大多数人来说
汇编语 言仍是编写单片机程序的主要语言
我们上册的教程将全部以汇编语言来编写单片机的程序
了解了单 片机编程的设计语言
下面我们来看单片机编程的基本过程和步骤
单片机程序设计的步骤
单片机的程序设计通常包括根据任务绘制程序流程图
编写程序及汇编等几个步骤
绘制流程图
所谓流程图
就是用各种符号
箭头把程序的流向及过程用图形表示出来
绘制流程图是 单片机程序编写前最重要的工作
通常我们的程序就是根据流程图的指向采用适当的指令来编写的
面的图形和箭头就是我们绘制流程图用的工具图中左边所示
绘制流程图时
首先画出简单的功能流程图粗框图再对功能流程图进行扩充和具体化
标志位等单元做具体的分配和说明
把功能图上的每一个粗框图转化为具体的存储器或地址单
从而绘制出详细的程序流程图
下面举个例子给大家演示一下
请看下面的程序
----------------
这是我们第四课中做过的 LED 灯闪烁的实验
以前我们曾对程序进行过分析
现在让 我们用流程图来把这段程序的主程序部分画出来
看上图的右边部分
这就是程序的流程图
在单片机 的编程过程中
绘制流程图能看清楚程序执行的步骤以及程序的流向
程序的编写就是根据流 程图的功能完成的
下面我们来把第十五课中的那个程序也用流程图画出来
P3.5 上接有一只按键
P3.6 上接有一只按键
自己画一下
看是不是同我画的一样
在实际的程序设计中
采用适当的
指令编写出实现流程图的源程序就是我们编写程序的最后工作
编写程序和汇编
程序编写完之后
我们要把它汇编成机器语言
这种机器语言就是十六进制文件
后缀名为*.HEX 文件
以前还要把它转换成二进制文件
后缀名为*.BIN 文件
不过现在的编程器都能直接读入十六进 制文件
就不需要转换了
最后用编程器把程序写入单片机
这些以前都讲过了
这里就不重复了
下 面来讲本课的主题―程序设计的方法
单片机程序设计的方法
要想搞清楚程序设计的方法
我们首先要知道单片机到底有哪几类程序
单片机的程序分为结构
----------------
在单片机的程序中
既有复杂的程序
也有简单的程序
但不论哪种程序
它们都是由一个个基 本的程序结构组成的
这些基本结构有顺序结构
分支结构和循环结构
1顺序结构程序的设计
顺序结构的程序一般用来处理比较简单的算术或逻辑问题
它的执行过程是按照程序存储器
的顺序执行的
主要用数据传递类指令和数据运算类指令来实现
比如我们前面第六课中的
I/O 口输入实验就是典型的顺序结构的程序
把这个程序的流程图写出来
下面再看一个例子
将内部 RAM 中 20H 单元和 30H 单元的无符号数相加
存入 R0高位和 R1低位中
先画出流程图
根据流程图编写源代码如下
这就是顺序结构程序
程序的原理就不分析了
我们接着讲分支结构的程序设计
这里说明一点
最近有朋友提出这一课的有些程序看不懂
这一课的有几个程序实例
----------------
我们从来没有学过
之所以放在这里
原本是为了让大家理解程序设计的方法
举几个示例证明一下
没想到反而增加了大家的难度
其实这些示例你不需要刻意的去理解它
只要明白它的设计方法就可以
因为这一课的主要内容是程序设计的方法
而不是程序执行的原理和结果
如果以后有更好的示例 我会修改一下
2分支结构程序的设计
所谓分支结构就是利用条件转移指令
使程序执行某一指令后
根据所给的条件是否满足来改变 程序执行的顺序
也就是本条指令执行完后
并不是象顺序结构那样执行下一条指令
而是看本条指令 所给的条件是否满足
如果满足条件就跳转到其他的指令
如果不满足就顺序执行
当然也可以是满足 条件顺序执行
而不满足条件跳转执行
看十五课实验程序中的下面两条
这就是分支结构的程序
如果 P3.5 为
反之就顺序执行
当然也可以改成 P3.5=0 顺序执行
而 P3.5=1 则转移
不过此时的程序就要用 JB 指令了
在 51 系列单片机中
可以直接用于 分支程序的指令有 JBJNBJCJNCJZJNZCJNE
JBC 等这几条
它们可以完成诸如正负判断
大小判断和溢出判断等等
在分支结构的指令设计中
大家必须注意
执行一条判断指令只可以形成 两路分支
如果要形成多路分支
就必须进行多次判断
也就是多条指令连续判断
下面给大家举两个 例子
单分支结构的程序实例
假设有两个数在内部 RAM 单元的 40H 和 41H 中
现在要求找出其中较大的一个数
并将较大的数 存入 40H 中
而将较小的一个数存入 41H 中
根据程序的要求
我们先画出程序的流程图左图
再根据流程图写出程序的源代码如下
----------------
程序的原理请大家自行分析一下
接下来再举一个多分支结构的实例
看下面的程序
自己画一下本例的流程图
再和上面的右图比较一下
看是不是一样
这里有一条指令给大家解 释一下
ACC.3 表示累加器 A 中的 D3 位
这条指令的意思就是看一下累加器中的
D3 位是正还是负
D3 是什么呢
在这里就是
20H 的二进制 上一课刚讲过
不要说又 忘了
接下来再讲第三种循环结构的程序设计
3循环结构程序的设计
循环程序是最常用的程序结构形式
在单片机的程序设计中
有时要碰到一段程序需要重复执行 多次的情况
此时就要用到循环结构程序
比如第四课中的实验--LED 灯闪烁程序的子程序
在这段程序中
为了延时需要多次执行 DJNZ 指令
此时若用循环结构程序就可以大大地简化程序
初始化部分主要用来设置循环的初始值
包括预值数
计数器和数据指针的初值
比如上例中的
#250 就是预值数初值
循环处理部分
循环处理部分是程序的主体部分
也称为程序体
通过它可以完成程序处理的任务
循环控制部分
循环控制部分可以控制程序循环的次数
并修改预值数或计数器和指针的值
检查该循环是否执 行了足够的次数
如果到了足够的次数
就采用条件转移指令或判断指令来控制循环的结束
4指令就是当 R6 或 R7 中的值为
循环结束部分
循环结束后必须返回
一般用 RET 或 RETI 指令
以上四个部分中
第一和第四部分 只能执行一次
而第二和第三部分可以执行多次
典型的循环结构程序的流程图可画成如下左图所示
也可以将处理部分和控制部分位置对调
在循环程序设计中
循环控制部分是程序设计的关键环节
常用的循环控制方式有计数器控制和
条件控制两种
计数器控制就是把要循环的次数即预值数放入计数器中
程序每循环一次
计数器 的值就减 1
一直到计数器的内容为零时
一般用 DJNZ 指令
而条件控制方式常预先不知
道要循环的次数
只知道循环的有关条件
此时就可以根据给定的条件标志位来判断程序是否继续
一 般参照分支结构方法中的条件来判别指令并执行
下面举几个例子来分别解释一下
希望大家能以此类
----------------
用计数器控制的单重循环程序
源程序如下
这段程序的作用是从 22H 单元开始存放一个数据块
其长度存放在 20H 单元中
将数据块求和
要求将和存放入 21H 单元中
和不超过 255
下面再举一个条件控制的循环程序
用条件控制的单重循环程序
设字符串存放在内部 RAM 的 21H 开始的单元中
以结束作标志
要求计算出该字符串的长度
并 将其存放在 20H 单元中
源程序如下
将地址指针指向 21H 单元 LOOP
0计数器加 1
修改地址指针
自己把上面两段程序的流程图画出来
下面再看一个例子
----------------
这是一段约 125mS 的延时程序
现在我们来把它改成下面表格中的程序右边的程序
从这里可以引出一个概念
程序的嵌套
什么是嵌套
比如早上我骑自行车从家里到单位去上班
当走到半路上时
太太叫我去孩子学校拿点东西
老师又叫我把学校的一台电脑修一下
一个朋友又打电话叫我去他那里拿了一本单片机与嵌入式系统杂志
完了之后再去上班
这就是生活中的嵌套
在单片机的程序设计中
也有类似的现象
有时为了达到某个目的
往往要在一
段循环程序中再加入另一段循环程序
这就是单片机的程序嵌套
通常我们把一个循环体中不再包含循 环的叫做单重嵌套
如果一个循环体中还包括有循环
则叫做多重嵌套
上面的表格中左边的程序就是 单重嵌套
而右边的程序则是多重嵌套
另外须注意
在多重嵌套中
不允许各个循环体互相交叉
也不允许从外循环跳入内循环
否则编译时会出错
了解了结构化程序的设计
下面再来看子程序的设 计方法
子程序的设计方法
什么是子程序
如何设计子程序
要解释这个问题
让我们先同样从生活中的一个例子说起
请 看下面的数学题目
28*33+65+47*33+65+875*33+65在这道题中
我们一般是怎么算的
也许大家都知道
一般总是先把33+65=98 代出来
然后再用28+47+875*98 来计算最后的结果
为什么会这样
这是因为在这道题中
我们多次用到了33+65这个中间结果
在单片机的程序设计
有时也有这样的情况
比如下面的程序
这是大家非常熟悉的 LED 灯延时程序
在这段程序中
两次调用到了 DELAY 这段程序
为了简 化程序的设计
我们就把 DELAY 这段程序单独地列了出来
这段列出的程序我们就叫它子程序
用子程序的程序我们则叫它主程序LOOP
的程序段在主程序执行时
每当要用到子程序时
我们 就用 LCALL 指令来调用子程序
子程序执行完之后
必须返回主程序
返回就用 RET 指令
以前都讲过了
这里不再重复
如果子程序执行的过程中
还要再次调用其他的子程序
这种现象我们就称它为子程序的 嵌套
看上面右边的图
就是一个两层子程序的嵌套结构图
这里有个问题
在子程序的执行过程中
有时可能要使用到累加器和某些工作寄存器
而在调用 子程序前
这些寄存器中可能已经存放有主程序的中间结果
它们在子程序返回后仍要使用
----------------
要在进入子程序之前
将要使用的累加器和寄存器中的内容预先转移到安全的地方保存起来
这叫现场 保护
当子程序执行完即将返回主程序之前
还要将这些内容先取出来
送回到累加器和原来的工作寄 存器中
这个过程叫恢复现场
保护现场和恢复现场通常使用堆栈
即在进入子程序之前
将需要保护的数据压入堆栈
在返回 之前再将压入的数据弹出到原来的工作单元中
恢复原来的状态
看下面的例子
将 03H 单元中的值压入堆栈保护
将累加器中的值压入堆栈保护
由于堆栈的操作是
先进后出所以编写指令时
必须把后压入堆栈的数据先弹出来 才能保证恢复到原来的状态
在实际的程序设计中
由于每个应用程序的不同
还必须根据具体的情况 来考虑是否需要保护
哪些数据需要保护等等
这就是单片机的堆栈为什么能够变化的原因
关于堆栈 的操作先讲这些
后面的实验中我们还将结合具体的实验来分析
接下来再看另一种程序--综合程序的 设计方法
综合程序的设计方法
综合程序有查表程序
数据排序程序
代码转换程序等等
作为初学者
要想全面的 掌握也确实有一定的难度
所以只给大家简单地提一下
详细的内容就留到下则的课程中再来解释
程序设计是单片机开发最重要的工作
掌握程序设计的基本步骤和方法对于单片机的软件编写是 至关重要的
这一课的内容较多
对于一时无法搞清的部分
大家可以结合以后的实际应用慢慢去理解
不要急于求成
千万记住一点
学习使用单片机绝不是一朝一夕的事
如果你不是天才
想速成单片机
我还是劝你赶紧改行
第 16 课习题
什么是单片机的程序设计语言
单片机的程序设计包括哪几个步骤
画出单片机的流程图符号并简述它的作用
单片机的分支结构程序指令有哪几条
什么是单片机的程序嵌套
想想生活中还有哪些现象与单片机的嵌套类似
----------------
单片机的定时/计数器
通过前面十几节课的学习
我们已经掌握了很多的单片机知识
也许您已经可以用它来开发具体
不过在有些工业及民用控制中
我们往往需要定时检测某个参数或按一定的时间间隔来进行 某项控制
比如家里的闹钟定时
此时您就要用到定时器或计数器
因此几 乎所有的单片机系统内部都有几个定时/计数器
89C51 有两个 16 位的定时/计数器
而 89C52 则有 3
定时/计数的概念
从选票的统计谈起
正这就是计数
生活中计数的例子处处可见
线缆行业在电线 生产出来之后要计米
也就是测量长度
怎么测量呢
要一边做一边量
行业中有很巧妙的方法
用一个周长是 1 米的轮子
将电缆绕在上面一周
由线带动轮子转
这样轮子转一周不就是线长 1 米嘛
所以只要记下轮子转了多少圈
就可以知道走过的线有多少米了
计数器的容量
从生活中的一个例子看起
一个水盆在水龙头下
水龙没关紧
水一滴一滴地滴入盆中
水滴不 断落下
盆的容量是有限的
过一段时间之后
水就会逐渐变满
计数是有容量的
片机中的计数器有多大的容量呢
89C51 的两个计数器
分别称之为 T0 和 T1
这两个计数器都是由两
个 8 位的 RAM 单元组成的
即每个计数器都是 16 位的计数器
最大的计数容量是 216=65536
从 0-65535
因为在计算机中
往往把 0 作为起始点
定时器的原理
单片机中的计数器除了可以作为计数用
还可以用作定时器
定时器的用途当然很大
如闹钟的 定时
手机的定时开关机等等
那么计数器是如何作为定时器来用的呢
如果我们将它定时
在 1 个小时后闹响
就相当于秒针走了 3600 次
在这里时间就转化成为了秒针走的次数
计数 的次数和时间之间的确有关
那么单片机的定时/计数器是怎么回事呢
请看下面的图
从图中我们可以得出这样的结论
只要计数脉冲的间隔相等
那么计数值就代表了时间的流逝
单片机中的定时器和计数器是一个东西
只不过计数器记录的是外界发生的事情
而定时器则是
由单片机提供一个非常稳定的计数源
然后把计数源的计数次数转化为定时器的时间
开 关就是起这个作用的
那么提供给定时器的计数源又是从哪里来的呢
继续看上面的图
原来它就是由
----------------
单片机的晶振经过 12 分频后获得的一个脉冲源
晶振的频率是很准的
所以这个计数脉冲 的时间间隔当然也很准
这里提个问题
一个 12M 的晶振
它提供给计数器的脉冲时间间隔是多少呢
不知大家是否还记
那就是 1us
也就是 1 个微秒
溢出的原理
继续让我们看水滴的例子
当盆中的水不断落下
最终会有一滴水使得盆中的水变满
再有一滴水落下
就会发生什么现象
水会溢出来
用个单片机的术语叫
水溢出是流到地上
而计数器溢出后会使得 TF0 由
至于 TF0 是什么我们稍后再谈一旦 TF0 由
1就是发生了变化
发生了变化就会引发事件
就象闹钟的定时时间一到
铃声就会响一样
那 么单片机的溢出会引发什么事件呢
我们下节课再具体介绍
这里我们来研究另一个问题
要有多少个
计数脉冲才会使 TF0 由
任意定时及计数的方法
刚才已经讲过
51 系列单片机的计数器是 16 位的
也就是最大的计数值范围是 0-65535
因此计 数器计到
个脉冲就会产生溢出
这个不是问题
问题是我们在实际应用中经常会有少于
65536 个计数脉冲的要求
如药品生产线上
一箱为 50 瓶
一瓶为 100 粒
怎么样才能满足这个要求呢
如果是一个空的盆要 1 万滴水滴进去才会满
我们在开始滴水之前就预先放入一勺水
还 需要 1 万滴嘛
单片机计数也是如此
如果我要计 5000 个脉冲
就先放进 60535 个
再来 5000 个
不 就到了 65535 了吗
定时器同样如此
每个脉冲是 1 微秒
则计满 65536 个脉冲需时 65.536 毫秒
但 现在我只要 10 毫秒就可以了
10 个毫秒为 10000 微秒
只要在计数器里预先放进 55536 就可以了
这种计数方法我们把它称之为预置数计数法
那么单片机的定时/计数器是由什么来控制的
下面就来讨论这个问题
定时/计数器的方式控制字
从上一节我们已经知道
单片机中的定时/计数器可以有两种用途
那么我们怎样才能让它们工作 于我们所需要的用途呢
这就需要通过定时/计数器的方式控制字实际上就是与定时/计数器有关的特
殊功能寄存器
在单片机中有两个特殊功能寄存器与定时/计数器有关
它们是 TMOD 和 TCON
顺便说一下
TMOD 和 TCON 是名称
我们在写程序时既可以直接用这个名称来指定它们
也可以直 接用它们的地址 89H 和 88H 来指定它们其实用名称也就是直接用地址
只不过汇编软件帮你翻译一
下而已具体使用稍后讲
现在先来看特殊功能寄存器 TMOD 的组成
特殊功能寄存器 TMOD89H
从表中可以看出
TMOD 被分成两部份
每部份 4 位
分别用于控制 T1 和 T0
至于这里面是什
我们稍后介绍
先看另一个与定时/计数器有关的特殊功能寄存器 TCON
特殊功能寄存器 TCON88H
用于定时/计数器
TCON 也被分成两部份
高 4 位用于定时/计数器
低 4 位则用于中断我们暂时不管而 TF0
我们前面已提到了
当计数溢出后 TF0 将由
1原来 TF0 在这儿
TR1 又是什
看前面的图
计数脉冲要想进入计数器还真不容易
有层层关要通过
1开关才能合上
脉冲才能过来
TR0 我们称之为运行控制位
当要使用 T0 时必须用指令
SETB 来置位以启动计数/定时器工作用指令 CLR 可关闭定时/计数器的工作这一切就在您的掌握 中了
知道了 TF0 和 TR0
TF1 和 TR1 的作用也清楚了
我们还是没有讲清楚单片机定时/
计数器是如何来工作的
接着往下看
定时/计数器的四种工作方式
----------------
单片机的定时/计数器共有四种工作方式
下面我们分别加以介绍
工作方式 0
定时/计数器的工作方式 0 称之为 13 位定时/计数器方式
它由 TL0/1的低 5 位和 TH0/1
的 8 位构成 13 位的计数器
此时 TL0/1的高 3 位未用
请看各位的功能
定时/计数器一共有四种工作方式
就是用 TMOD 的 M1M0 来控制的
两位正好是 4 种组合
前面我们说过
定时/计数器既可作定时器用也可作计数器用
到底作什么用
由我们根据需要自 行决定
也说是决定权在我们编程者手中
如果 C/T=0 就是用作定时器开关往上打如果 C/T=1 就
用作计数器开关往下打顺便提一下
一个定时/计数器同一时刻要么作定时用
要么作计数用
能同时使用
这一点请大家注意
当我们选择了定时/计数器工作方式后
定时/计数脉冲却不一定能到达计数器端
中间还有一个 开关
很显然如果这个开关不合上
计数脉冲就没法通过
那么开关什么时候合上呢
它有两种情况
分析一下逻辑
门总是输出
门的另一个输入端 INT0中断 0
什么是中断
先不去管它无关
在这种情况下
合上只取决于 TR0
只要 TR0=1
开关就合上
计数脉冲得以畅通无阻
而如果 TR0=0 则开关打
计数脉冲无法通过
因此定时/计数是否工作
在这里只取决于 TR0
在这种情况下
计数脉冲通路上的开关不仅要由 TR0 来控制
而且还要受到 INT0
引脚的控制
只有 TR0=1
且 INT0 也是高电平
开关才能合上
计数脉冲才得以通过
那么为什么在这种模式下只用 13 位呢
干吗不用 16 位
这是为了和 51 的前辈 48 系列兼容而设 的一种工作方式
如果你觉得用起来不顺手
那就干脆用工作方式 1 吧
工作方式 1
工作方式 1 是 16 位的定时/计数器方式
将 TMOD 的 M1M0 设为
其它特性与工作 方式 0 相同
这里就不详细介绍了
工作方式 2
在介绍这种工作方式之前先让我们思考一个问题
前面我们提到过任意计数及任意定时的问题
比如我要计 5000 个数
可是 16 位的计数器要计到 65535 才溢出
我们讨论后得出的办法是 采用预置数的办法--先在计数器里放上 60535 个
再来 5000 个脉冲
不就行了吗
但是计满了 之后我们又该怎么办呢
计数总是不断重复的
流水线上计满后马上又要开始下一次计数
下 一次的计数还是 5000 吗
当计满并溢出后
计数器里面的值又变成了
可以参考前面课
程的说明因此下一次将要计满 65535 后才会溢出
这可不符合要求
当然办法很简单
就 是每次一溢出时执行一段程序这通常是需要的
要不然要溢出干吗
可以在这段程序中做把预置数
60535 送入计数器中的工作
所以采用工作方式 0 或 1 都要在溢出后做一个重置预置数的工作
当然就得要时间
一般来说这点时间不算什么
可是有一些场合我们还是要计较的
所以就有了工作方
式 2--自动再装入预置数的工作方式
既然要自动装入预置数
那么预置数就得放在一个地方
要不然装什么呢
那么预置数放在什么 地方呢
它放在 T0或 T1的高 8 位中
那么这高 8 位不就不能参与计数了吗
在工作方式 2
只有低 8 位参与计数
而高 8 位是不参与计数的
用作预置数的存放
这样计数范围就小了当然 做任何事总是有代价的
关键看值不值
如果我根本不需要计那么多数
那就可以用这种工作方式了
看前面的图
每当计数溢出
就会打开 T0或 T1的高
低 8 位之间的开关
预置数就进入低 8 位
当然这是由硬件自动完成的
不需要我们去操心
通常工作方式
用于波特率发生器我们将在下册的串行接口中讲解对于这种用途
定时器 就是为了提供一个时间基准
计数溢出后不需做任何的事情
要做的仅仅只有一件
就是重新装入预置
再开始计数
而且中间不能有任何的延迟
可见这个任务用这种工作方式来完成是最妙不过了
----------------
工作方式 3
在这种工作方式下
T0 被拆成 2 个独立的定时/计数器来用
TL0 可以构成 8 位的定时器 或计数器工作方式
而 TH0 则只能作为定时器用
我们知道定时/计数器使用时需要有控制
计满后溢 出需要有溢出标记
T0 被分成两个来用
那就要两套控制及溢出标记了
从何而来呢
TL0 还是用原 来的 T0 的标记
而 TH0 则借用 T1 的标记
如此一来 T1 不是无标记
控制可用了吗
在一般 情况下
只有在 T1 以工作方式 2 运行时
才让 T0 工作于方式 3
定时器/计数器的定时/计数范围 那么单片机的这四种工作方式的计数范围是如何确定的呢
工作方式 0
13 位的定时/计数器工作方式
最多可以计到 2 的 13 次方
也就是 8192 次
工作方式 1
16 位的定时/计数器工作方式
最多可以计到 2 的 16 次方
也就是 65536 次
工作方式 2 和 3
工作方式 2 和工作方式 3 都是 8 位的定时/计数器工作方式
因此最多可以计到 2 的 8 次方
预置值计算
用最大计数量减去需要的计数次数即可
流水线上一个包装是
盒就产生一个动作
用单片机的工作方式
应当预置多大的值呢
以上是计数器的原理
明白了这个道理
定时器也一样
前面的课程已经提到过
就不再重复了
请大家参考前面的例子自行分析
本来想在这里做个实验
可有的问题可能还解释不清楚
所以等大家学完了下一课的中断后一块 儿来实验吧
请继续把下一课的内容看完
本课主要讲述了单片机的定时/计数器的原理和工作方式
定时/计数器是单片机的重要组成部
如果您在用单片机开发产品时需要用到定时器或计数器
那么本课的内容是必须掌握的
所以希望 大家能认真地看一下这一课的内容
后面我们还会结合具体的实验来讲解它们的使用方法
第 17 课习题
89C51 中有几个定时/计数器
它们的计数范围是多少
什么是单片机的溢出
溢出后会产生什么现象
定时/计数器有关的两个 SFR 是什么
它们的地址为什么
单片机有几种工作方式
它们的定时/计数范围是多少
----------------
版权所有: 2007
Email: qq:}

我要回帖

更多关于 单片机流水灯程序 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信