单片微机原理P3:80C51外部拓展系统

发布者:BlossomBeauty最新更新时间:2024-08-21 来源: cnblogs关键字:单片微机  80C51 手机看文章 扫描二维码
随时随地手机看文章

外部拓展其实是个相对来说很好玩的章节,可以真正开始用单片机写程序了,比较重要的是外部存储器拓展,81C55拓展,矩阵键盘,动态显示,DAC和ADC。

 

0. IO接口电路概念与存储器拓展

1. 为什么需要IO电路?:1. 协调计算机与外设的速度的差异 2. 输入/输出过程中的状态信号 3. 解决计算机信号与外设信号之间不一致

2. IO传送方式三种:1. 无条件传送(灯,DAC),2. 查询,3. 中断(ADC)。

 

3. DMA存储方式(直接传输数据不通过CPU,这种方式实际上已经很古老了,都快要被淘汰了(当然还存在STM32,51这些低级产品中)。)

  工作流程:

  ①CPU通过指令,把要传送的数据块的长度、传送数据块在内存中的首地址等信息写入DMA控制器

  ②外设通过DMA控制器向CPU发出DMA请求。

  ③CPU接受DMA请求后,暂停正在执行的程序,并且放弃对总线的控制权,由DMA控制器来接管,外设的数据线和存储器的数据线经过DMA控制器的通道直接连通。

  ④DMA控制器通过地址总线向存储器发出传送数据的地址。

  ⑤如果是外设向存储器传送数据,DMA控制器向外设发出读信号,读出数据,DMA控制器向存储器发出写信号,则写入数据,由于两者的数据线是直接连接的,数据读、写的操作就可以连续进行,很快地完成一次数据传送。

  ⑥数据块长度计数器减1,然后重复以上进程,直到数据块传送完毕。

  ⑦DMA操作结束,CPU再次恢复对总线的控制,继续执行原来的程序。

以上的传送过程,一次数据传输一般只要几个时钟周期就可以完成。

 

4. 在无条件传送方式下,CPU和外设端口之间也要有接口电路。

  1. 在输入端口上会有一个输入缓冲器:

    在不做输入操作时,缓冲器处于高阻状态,CPU实际上和输入外设没有连接;

    需要做输入操作时,地址译码器的输出使缓冲器正常工作,输入设备的信息就可以通过缓冲器读入到CPU。

 

  2. 在输出的端口上一般会有一个输出锁存器:CPU将要输出的信息存入输出锁存器中,外设从锁存器读取信息。

 

  接口电路也至少需要两个端口:状态端口和数据端口,用以分别传送状态信息和数据信息。(这就是ADC芯片所设计的那样的。)

 

5. 单片机从逻辑上有3个存储器寻址空间

片内RAM空间:00H~FFH

片外RAM空间:0000H~FFFFH

片内外统一编址的ROM空间:0000H~FFFFH (注意是片外,如果是片内+片外为0000~0FFFH,然后片外再从1000H开始到FFFFH)

 

6. 扩展ROM时,用控制线PSEN,指令用MOVC

  扩展RAM时,用控制线RD和WR,指令用MOVX

  单片机是通过地址(AB)、数据(DB)和控制总线(CB)与外部交换信息的。

 

1. 存储器的拓展(ROM & RAM)

  1. 拓展程序存储器(以拓展2732为例)(一定要会)

  现在我们来解释一下这些引脚的意思:

  ALE引脚:和我们之前的说的是一样的,就是实现对P0口的分时复用,要注意这个ALE很坑的地方是他是在下降沿P0口的地址输出信号才有效,所以锁存芯片一定要选对(比如这里选的就是373,如果选那些上升沿触发的377之类的,请加个反相器再加上去)。

  PSEN引脚:引脚功能如其名:外部程序存储器选通信号PSEN,所以接2732的使能片很符合常理。(低电平有效)

  2732的CE引脚:片选信号端,用P2.5~2.7进行选通。

  关于时钟,ALE,PSEN,P2,P0的时序图:

  注意ALE和PSEN是同步开始的,P2和P0的信号相对于PSEN和ALE都是有延迟的

  

 

译码器法:(其实就是加了个译码器而已,简单)

  

 

2. 拓展外部RAM(以拓展6116为例)(一定要会)

  SRAM(51的内部内存都是SRAM)通常用于小于64KB的小系统,DRAM(我们的电脑内存是DRAM)用于大于64KB的大系统。

  拓展RAM和ROM的做法其实是差不多的,但是唯一的不一样是ROM是拓展的PSEN,所以PSEN要接ROM的OE,但是对于RAM来说,它读写双向的,所以我们只要拓展把80C51的RD端接6116的OE端,WR端接6116的WE端就可以了,同时注意,6116也是有片选端(CE)的,我们也可以像ROM那样对RAM进行片选。


 

3. 拓展FLASH(RAM + ROM)

  就是把ROM和RAM的拓展方式结合起来,既要接PSEN又要接WR和RD

  注意这里的PSEN,WR,RD,WE,CS和OE都是低电平有效的,一旦哪个引脚低电平了就可以把FLASH对应成相应存储器,比如当PSEN为低电平时,这个Flash就是个程序存储器,WR为低表示以外部RAM写,ED为低则表示以外部RAM读(可能这个电路有点复杂,其实只用仔细看一下就知道只要有一个是低电平CS就会是低,然后你就可以把它看成是什么都行了)。

  注意这里的拓展还用P1拓展了地址,输出的时候注意:


;(写)

MOV P1,#05H

MOV DPTR, #0AAAAH

MOV A, #3FH

MOVX @DPTR, A

 

;(读)

MOV P1,#02H

MOV DPTR, #0AAAAH

MOVX A, @DPTR

;地址由P0,P1.0~2,P2共同决定

当然了我们也可以不占用P1来拓展这个芯片,由于我们只用保证必须要有信号就可以了,所以我们可以用锁存器来继续拓展这个芯片,这样就可以只用P0~P2了(程序设计要麻烦一点而已)。

4. 奇葩拓展芯片2718(有BUSY和READY位告知CPU已经完成转换)

  仔细看下RD和PSEN,他们是通过一个与门来连接同样是低电平有效的OE,这个芯片的特别之处在于他有BUSY位(低电平有效)和RDY(Ready)位,看英文就知道是怎么回事。

 

5. IO口拓展

  这个有个很有趣的例子就是拓展开关和灯泡,拓展IO口可以很巧妙地里用WR和RD不同时为0的特性:

  还记得之前我们是怎么说的吗?输出部分要有锁存器,输入部分要有缓冲电路。74LS244为3态8位缓冲器,一般用作总线驱动器。74LS273是8位D触发器,常用作锁存器。这个图完美的切合了我们之前所说的,由于WR和RD不同时为低,所以我们可以仅用MOVX指令就可以完成IO拓展了(P2.0当总控制口)

上例中按下任意键,对应的LED发光。

CONT:

MOV DPTR, #0FEFFH ;数据指针指向口地址

MOVX A, @DPTR ;检测按键,向74LS244读入数据

MOVX @DPTR, A ;向74LS273输出数据,驱动LED

SJMP CONT ;循环

  总结一下,如果出了设计题,一定要先思考到WR和RD的问题,要记住WR和RD都是低电平有效的,一般和与门进行结合来控制CS端。

 

1. 81C55拓展

1. 81C55参数如下:(要熟记81C55的引脚的作用)

AD7~AD0:三态地址数据总线,用于传送数据、命令和状态字,分时复用线,P0口可以和AD0~AD7直接相连接。

CE:片选信号线。(80C51随便找个P口控制)

RD:存储器读信号线。(一般接80C51的RD线)

WR:存储器写信号线。(一般接80C51的WR线)

ALE:地址及片选信号锁存信号线,高电平有效,其后沿将地址及片选信号锁存到器件中。 (一般接80C51的ALE线)

IO/M:I/O接口与存储器选择信号线,高电平表示选择I/O接口,低电平选择存储器RAM。(80C51随便找个P口控制)

PA7~PA0:A口输入/输出线。

PB7~PB0:B口输入/输出线。

PC3~PC0:C口输入/输出或控制信号线(A口和B口作为选通口时)。

TIMER IN:定时器/计数器输入端

TIMER OUT :定时器/计数器输出端

RESET:复位信号线

 

  81C55各端口地址分配(81C55一共7个端口)(注:那个C/S寄存器就是命令字/状态字寄存器(共用一个地址,但是是不同的两个寄存器),低电平有效)

引脚作用(注意0是操作RAM,1是操作IO)

9f9784482aae835cf71e1b29b73745b1_798615-20170109213406510-1786404102.png?imageView2/2/w/1000

命令字(只能写)

 94f72e0b5aa1c07d723c3add41ddcedf_798615-20170109213628119-1529835705.png?imageView2/2/w/1000

状态字(只能读)

0e51e9b272162452267db852666d5df7_798615-20170109213717213-1312731818.png?imageView2/2/w/1000

TIMER:定时/计数器中断请求标志,定时器/计数器记满时这个位为1,当CPU读取状态后,这个标志位为0

INTE:端口允许中断位,高电平表示允许对应口中断,低电平表示禁止对应端口中断

BF:对应端口的缓冲器状态标志位,高电平表示的是缓冲器填满,低电平表示的是可以接受外设或者单片机的数据。

 

2. 当81C55涉及C寄存器做联络线的问题

  其实这个问题是很简单的,C寄存器的6个口的功能如下

 97b9ab34b2da0aa36656a22b05a102ed_798615-20170109213943510-896882773.png?imageView2/2/w/1000

  我们知道81C55可以很方便地与慢速设备进行连接,当外设需要往PA或者PB输入数据时,外设首先先给BSTX端口一个低电平信号,向81C55表明需要读信号,然后81C55的PX就从外设中开始读数据,到读满端口寄存器时,给ABF/BBF置位(表明缓冲区满),并且向CPU发出中断。CPU(比如80C51)调用中断处理,只需要一条MOVX A,@DPTR(此时DPTR指向对应P口),就可以把数据读进来。

  当需要写数据时,只要80C51一条MOVX @DPTR, A,就可以给对应P口写数据,直到对应P口的寄存器满,对应的BF位置位,外设就可以从P口读数据了,读数据时,BSTB变成低电平。

 

3. 关于81C55的定时器

  81C55的定时器是14位的减1定时器

  定时器寄存器的地址上面有写,需要注意的是,定时器的高8位的最高两位是设定81C55定时器的工作方式的:

 06ceae22fc6b5d5b599b994bd4f1bd8b_798615-20170109214001994-138668238.png?imageView2/2/w/1000

  单负方波:计数期间输出为低电平,记满回“0”后输出高电平。

  连续方波:计数长度的前半部分输出高电平,后半部分输出低电平,如果计数值为奇数个,则高电平为(n+1/2)个,低电平为(n-1/2)个。连续方波输出方式能自 动恢复初值。

  单负脉冲:计数器记满回“0”后输出一个单负脉冲。

  连续脉冲:计数值回“0”后输出单负脉冲,然后自动重装初值,回“0”后又输出单负脉冲,如此循环。

 

  给命令字的TM0和TM1位设定对应值即可开启定时器~

 

  例题:81C55的命令字寄存器的地址是7F00H,要求设定81C55的A口为基本输入方式,B口定义为基本输出方式,C口输入,打开定时器,读取81C55,要求将立即数0AAH写入81C55 RAM的7E25H单元:(P2.0是接CE,P2.7接IO/M)


MOV DPTR,@7F00H

MOV A,#0C2H ;11000010,(打开了计时器A口为输入(0),B口为输出0,PC1:PC0 = 00(A/B基本输入输出,C口输入))

MOVX @DPTR,A

MOV A,#0AAH

MOV DPTR,#7E25H ;写入的是内存,地址是7E25H,刚好符合写入RAM的要求(81C55的RAM只有256B)

MOVX @DPTR,A


2. 矩阵键盘拓展

  矩阵键盘只要记住矩阵键盘的样子:

10d42d994cc74294bb921536b3abd961_798615-20170109214143166-42183383.png?imageView2/2/w/1000

  你就能想到矩阵键盘的扫描方法了(必须按行和列来扫,因为本质上是通过给行/列全部低电平来让判断按钮有没有按下,当某行某列有按钮按下,对应电阻就会产生电压降,我们就可以找到对应的按钮了)。

  来一段我以前写过的C的代码:

#include


sbit encoder_selet=P2^7;

sbit numeric_display=P2^6;


unsigned char leddata[]={ 

                0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07,0x7F, 0x6F, 0x77, 0x7C, 0x39, 0x5E, 

                0x79, 0x71, 0x76, 0x38, 0x37, 0x3E, 0x73, 0x5C,0x40, 0x00, 0x00  

                };

                

unsigned char lower_key_set[4]={0x0e,0x0d,0x0b,0x07};

unsigned char lower_key_set_colum[4]={0xe0,0xd0,0xb0,0x70};


void delay(unsigned int);

void scan_keyboard(int);

void scan_keyboard_col(int);

void display_key(int);


static int pos= 0;


int main(void)

{

    int pos = 0;

    bstv51_init();

    while(1)

    {

        scan_keyboard_col(0);

        scan_keyboard_col(1);

        scan_keyboard_col(2);

        scan_keyboard_col(3);

    }

    return 0;

}


void scan_keyboard(int line)

{

    unsigned char in, lower_key,in_tmp;

    int selet_key;

    

    lower_key = lower_key_set[line];

    P3 = lower_key|0xf0;                            

    

    in = P3;

    in_tmp= in & 0x0f;

    

    in &= 0xf0;

    in |= lower_key;

    if(in!= (lower_key|0xf0))

    {

        delay(5);

        P3 = lower_key|0xf0;

        in = P3;

        in &= 0xf0;

        in |= lower_key;

        if(in != (lower_key|0xf0))                //软件防抖

        {

            in_tmp = in & 0xf0;

            switch(in_tmp)                        //找到相应的坐标

            {

                case 0xe0:

                    selet_key= 0 + line*4;        

                    break;

                case 0xd0:

                    selet_key= 1 + line*4;

                    break;

                case 0xb0:

                    selet_key= 2 + line*4;

                    break;

                case 0x70:

                    selet_key= 3 + line*4;

                    break;    

            }

            while(in != (lower_key|0xf0))

            {

                in = P3;

                in &=(lower_key|0xf0);

            }

            display_key(selet_key);

        }

    }

}


void scan_keyboard_col(int colum)

{

    unsigned char in, lower_key,in_tmp;

    int selet_key;

    

    lower_key = lower_key_set_colum[colum];

    P3 = lower_key|0x0f;                                

    in = P3;

    in_tmp= in & 0x0f;

    

    in &= 0x0f;

    in |= lower_key;

    if(in!= (lower_key|0x0f))

    {

        delay(5);

        P3 = lower_key|0x0f;

        in = P3;

        in &= 0x0f;

        in |= lower_key;

        if(in != (lower_key|0x0f))                //软件防抖

        {

            in_tmp = in & 0x0f;

            switch(in_tmp)                        //找到相应的坐标

            {

                case 0x0e:

                    selet_key= 0 + colum*4;        

                    break;

                case 0x0d:

                    selet_key= 1 + colum*4;

                    break;

                case 0x0b:

[1] [2]
关键字:单片微机  80C51 引用地址:单片微机原理P3:80C51外部拓展系统

上一篇:基于80C51单片机的出租车计费器设计
下一篇:单片微机原理P4:80C51串口与串行总线拓展

推荐阅读最新更新时间:2026-03-21 11:09

单片微机原理P2:80C51外部中断与定时器系统
0. 外部中断   书上的废话当然是很多的了,对于中断我想大家应该早就有一个很直观的认识,就是“设置断点,执行外部外码,然后返回断点”这样的三个过程。中断给系统提供了一个良好的响应模式。当然了,响应中断的时候记得保护现场,这是写汇编的良好习惯。   80C51一共是5个中断源,这五个中断源分别是外部中断0,1定时器中断0,1,串口中断。 1. 我们现在先来看外部中断: 一般开外部中断分为4个步骤(不用查询的方式的话): 1. 设置触发方式(IT0/IT1) 2. 开启外部中断(EX0/EX1) 3. 设定优先级(IP寄存器) 4. 开启总中断(EA) 查询方式只是多了一步看IE的值而已   代码(汇编代码) SETB IT1
[单片机]
<font color='red'>单片</font><font color='red'>微机</font>原理P2:<font color='red'>80C51</font><font color='red'>外部</font>中断与定时器<font color='red'>系统</font>
单片微机原理P4:80C51串口与串行总线拓展
0. 串口通讯 0. 串口通讯的数据传输方式:单工(单向传输数据),半双工(非同时双向传输),全双工(同时,双向传输) 1. 根据通信方式的不同又分为同步通讯和异步通讯。 同步通讯:所有设备都使用同一个时钟,称为同步时钟。在数据传送时,以若干个数据字符(称为数据块)为单位进行传输,每个数据块包括同步字符、数据块和校验字符CRC。 异步通信是指在串行通信中,接收设备和发送设备有各自的时钟信号,异步通信以字符为单位进行数据传送,不过通信中这些时钟频率必须保持一致。 2. 波特率和比特率 波特率是每秒传输的信号量(单位波特B),比特率是每秒传输的信号量(单位bps),在单片机中,这两个东西是一样的。 例如,通信双方每秒钟所传送数据
[单片机]
<font color='red'>单片</font><font color='red'>微机</font>原理P4:<font color='red'>80C51</font>串口与串行总线<font color='red'>拓展</font>
微机基础与89C51单片机部分知识
1,微机基础知识 微机: 具有完整运算及控制能力的计算机。包括微处理器,储存器,接口适配器,输入输出设备。 微处理器: 控制器:由程序计数器,指令寄存器,指令译码器,时序发生器,操作控制器等组成,是发布命令,协调指挥计算机系统的器件。①从内存取出指令,并指向下一个指令。②对命令进行译码或测试。③指挥并控制CPU,内存和输入输出的数据流。 运算器:由算数逻辑单元(ALU)可完成来自累加器和数据寄存器数据的加减运算,累加器,数据寄存器组成。 寄存器: 累加器(A):用运算前于保存操作数。运算后保存所得的和,差,逻辑运算结果 数据寄存器(DR):保存译码指令和数据字节。 指令寄存器(
[单片机]
<font color='red'>微机</font>基础与89C51<font color='red'>单片</font>机部分知识
单片机在电力系统微机保护模块中的应用
0 引 言 电力系统的飞速发展对继电保护不断提出新的要求,电子技术、计算机技术与通信技术的飞速发展又为继电保护技术的发展不断注入了新的活力。随着微机保护装置的研究,在微机保护软件、算法等方面也取得了很多理论成果。从20世纪90年代开始我国继电保护技术已进入了微机保护的时代。 电力系统对微机保护的要求不断提高,除了保护的基本功能外,还应具有大容量故障信息和数据的长期存放空间,快速的数据处理功能,强大的通信能力,与其他保护、控制装置和调度联网,以共享全系统数据、信息和网络资源的能力、高级语言编程等。这就要求微机保护装置具有相当于一台PC机的功能。 计算机网络可从网上获取电力系统运行和故障的任何信息和数据,也可将它所获得的被
[单片机]
<font color='red'>单片</font>机在电力<font color='red'>系统</font><font color='red'>微机</font>保护模块中的应用
异种单片机共享片外存储器及其与微机通信方法
TMS320系列数字信号处理单片机(DSP)在测控、仪器仪表、图象处理、计算机视觉与声信号处理等领域得到了越来越广泛的应用。DSP获取原始采集数据和输出处理结果一般有两种途径:一是通过串行口,另一是通过数据总线读写片外存储器。本文介绍了基于DSP的信号处理目标板与基于单片机AT89C51的多路同步数据采集板通过共享片外随机存储器实现板间通信,来获取原始采集数据的方法,并给出了总线隔离硬件电路与软件控制流程。并介绍了把DSP的处理结果传送给基于MCS-51单片机或基于微机的控制系统的方法。文中还简要分析了AT89C51与微机进行串口通信的软硬件设计,通过扩展AT89C51间接实现了TMS320C32与单片机或微机之间的通信,比直接通
[单片机]
异种<font color='red'>单片</font>机共享片外存储器及其与<font color='red'>微机</font>通信方法
51单片机在微机自动交换系统中稳定运行的设计方法
在电力线载波通信中,微机自动盘的功能多,逻辑性强,MCS—51单片机在该系统中处理任务时的实时性尤为突出。由于该系统整机配置的主要服务对象是电力调度,且它的使用环境将来多为无人值守站,所以系统工作是否稳定直接影响到电力线载波机的整机性能。针对电力通信特点,在考虑稳定运行方面我们采取了以下几项措施。   1 设置上电延时复位电路   1.1 为什么要进行上电复位46   计算机在启动运行时都要进行复位。作为在控制领域中应用最广泛的单片机,复位处理更是设计中的关键。单片机内部的各个功能部件均受特殊功能寄存器控制,程序运行直接受程序计数器指挥,寄存器的复位状态决定了单片机内有关功能部件工作用的初始状态,而程序的正常运行就是从这
[工业控制]
51<font color='red'>单片</font>机在<font color='red'>微机</font>自动交换<font color='red'>系统</font>中稳定运行的设计方法
51单片机在微机自动交换系统中稳定运行的设计方法
  MCS—51 单片机 在电力线载波通信中处理任务时的实时性尤为突出。由于该系统整机配置的主要服务对象是电力调度,且它的使用环境将来多为无人值守站,所以系统工作是否稳定直接影响到电力线载波机的整机性能。针对电力通信特点,在考虑稳定运行方面我们采取了以下几项措施。   1 设置上电延时复位电路   1.1 为什么要进行上电复位46   计算机在启动运行时都要进行复位。作为在控制领域中应用最广泛的单片机,复位处理更是设计中的关键。单片机内部的各个功能部件均受特殊功能寄存器控制,程序运行直接受程序计数器指挥,寄存器的复位状态决定了单片机内有关功能部件工作用的初始状态,而程序的正常运行就是从这个状态开始的。如果上电时没有做到正
[单片机]
51<font color='red'>单片</font>机在<font color='red'>微机</font>自动交换<font color='red'>系统</font>中稳定运行的设计方法
单片机共享片外存储器及其与微机通信的方法
1 板间共享存储器的硬件接口电路和软件 控制 流程 1.1 信号 处理板硬件接口电路 基于DSP的信号处理板可以根据应用要求运行许多信号处理算法,如信号预处理、目标识别与跟踪定位、Kalman滤波等。待处理的原始信号 数据 通过板间 通信 从数据采集板获得。这里采用板间共享存储器的方法来完成数据交换,DSP既可以从共享存储器读取采集数据,也可以把处理结果(如新的程控放大倍数值,跟踪定位结果等)写到共享存储器中供MCU读取。 TMS320C32有一个双向串行口,可以设置每帧同时收发8/16/24/32位数据,同步时钟可以由内部串口定时器产生或由外部输入。通过设置串口全局控制寄存器来控制串口的总体功能和工作模式;通过
[应用]
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved