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

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

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



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

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

3. DMA存储方式(直接传输数据不通过CPU(不需要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)

命令字(只能写)

状态字(只能读)

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

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

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

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

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

  我们知道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定时器的工作方式的:

  单负方波:计数期间输出为低电平,记满回“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. 矩阵键盘拓展



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

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

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

#include <reg51.h>

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:
                    selet_key= 2 + colum*4;
                    break;
                case 0x07:
                    selet_key= 3 + colum*4;
                    break;
            }
            while(in != (lower_key|0x0f))
            {
                in = P3;
                in &=(lower_key|0x0f);
            }
            display_key(selet_key);
        }
    }
}

void display_key(int selet)
{
    P0=0x00;                    //全部点亮
    encoder_selet=1;
    encoder_selet=0;

    P0=leddata[selet];
    numeric_display=1;
    numeric_display=0;
}

void delay(unsigned int xms)
{
    unsigned int i,j;
    for(i=xms;i>0;i--)              //i=xms即延时约xms毫秒
        for(j=112;j>0;j--);
}

这个真的很简单。。。某些垃圾视频教学把其列为重点来教学,不能理解。

3. DAC转换



  D/A转换的目的是把输入的数字信号转换成与此数字量大小成正比的模拟量

  DA转换:

1. DA转换性能指标:

  (1)D/A转换时间:D/A转换时间是指从一个数字量加载到DAC的数据输入端到DAC输出电压达到其最终电压的±1/2LSB范围内的时间。一般在几十纳秒到几百微秒的范围。

  (2)分辨率:输出电压值之间的最小差值就是DAC的分辨率。

  (3)D/A转换精度:D/A转换器实际输出电压与理论输出电压的偏差。通常以满输出电压VFS的百分数给出。

2. 重点例子:8位D/A转换器DAC0832(记住0832的一些引脚内容就可以了)

CS:片选信号输入端,低电平有效。

ILE:输入锁存使能信号,高电平有效。

WR1:输入锁存器写选通信号,低电平有效;为低,允许8位数据总线上的数据输入到输入锁存器中,为高,锁存输入锁存器中的数据。

WR2:DAC数据寄存器写控制信号,低电平有效。为低,且为低电平时,输入锁存器中的数据传输到DAC数据寄存器中,并自动开始进行D/A转换。

XFER:数据传输控制信号,低电平有效。与一起控制输入数据锁存器和DAC数据寄存器之间的数据传输。

DI7~DI0:8位数据输入总线。

其中由于这个芯片有一个缓冲器和一个寄存器,所以可以形成双缓冲模式,非常有趣

ORG 0000H
AJMP MAIN_START
ORG 0100H
MAIN_START:
MOV R0,#30H ;设置x数据指针
MOV R1,#50H ;设置y数据指针
MOV R2,#0 ;清计数器为零
;输出x数据到DAC0832 U2的输入寄存器
GOON:
MOV DPTR,#0DFFFH ;x数据DAC地址为DFFFH
MOV A, @R0
MOVX @DPTR,A ;写数据到DAC0832 U2
INC R0 ;x数据指针指向下一个数据
;输出y数据到DAC0832 U2的输入寄存器
MOV DPTR,#0BFFFH ;y数据DAC地址为BFFFH
MOV A,@R1
MOVX @DPTR,A ;写数据到DAC0832 U3
INC R1 ;y数据指针指向下一个数据
;把所有DAC0832的输入数据寄存器的数据写入到DAC转换寄存器,;1μs后同时输出数据到绘图仪
MOV DPTR,#7FFFH ;DAC转换寄存器地址为7FFFH
MOVX @DPTR,A ;使能和启动D/A转换
INC R2 ;统计输出数据个数
CJNE R2, #20,GOON ;输出20个数据后,绘图结束
SJMP $ ;停机
END

注意由于电路的WR接了WR1和WR2,所以只要是写操作并且开了CS都会让数据送到寄存器上,当P2.7 = 0时,XFER和WR2同时为低,就把数据一起输出了。这样就可以在不用外接锁存器的情况下实现双缓冲(Windows编程里面的双缓冲也是基于这个原理的)。

AD转换:

1. A/D转换的技术指标:

  量程:指A/D转换芯片所能转换的模拟输入电压的范围

  分辨率:对微小输入量变化敏感程度的度量。

  转换时间与转换速率:指从模拟量输入到转换结束输出数字量所需要的时间 ,转换速率则是转换时间的倒数。

2. 重点例子8位A/D转换器ADC0809:

  IN0~IN7:8路模拟信号输入引脚。

  D0~D7:8位A/D转换输出数据总线。输出数据与输入电压的关系式为

  其中,[ ]表示取整运算。

  A、B、C:模拟通道地址选择信号,A为最低位,C为最高位。

  SC:转换开始引脚,正脉冲有效。

  EOC:转换结束标志信号,高电平有效,表示转换结束。在与处理器连接时,此引脚可以用来向处理器发出中断,或者是供处理器软件查询。

  转换步骤:(直接看代码就好了)

  第一步:地址信号到ABC;ALE地址锁存信号输出高电平,在ALE的上升沿,ADC0809锁存地址信息,选定通道;

  第二步:模拟信号输入到ADC的模拟输入脚,使SC高电平,在一定的延时时间内,EOC变成低电平,表示转换开始;接着,外接处理器发出SC低电平信号,ADC0809开始在时钟信号的控制下,进行转换,经过tC时间后,转换完成,EOC输出高电平,并保持高电平,直到下次SC上升沿才变低。从SC变成高电平直到EOC输出电平的时间内,模拟输入信号的电压值必须保持不变。

  第三步:处理器查询到EOC变高后,或者是在EOC申请中断后(所以一般要接外部中断),处理器控制OE信号,使其变高,ADC0809输出数据,数据线在OE下降沿到来后变成高阻态。在OE为低电平时,数据线一直保持为高阻态,因此ADC0809的数据线可以直接连接到系统数据总线上。

3. 单片机与ADC0809的两种连接方法:

;通道1的选择及启动转换
MOV DPTR, #8001H
MOVX @DPTR, A
;此处A的值无关紧要

MOV DPTR, #8000H
MOV A, #01H
MOVX @DPTR,A;此处A的低3位为ADC0809的地址信号

小例题:锯齿波输出:

ORG 0000H
LJMP START
ORG 0100H
START:
MOV DPTR, #07FFFH
MOV A,#0
MOV R1,#0

OUTPUT_UP:
MOVX @DPTR,A
ADD A,#4
INC R1
NOP
NOP
NOP
NOP
CJNE R1,#51,OUTPUT_UP
MOV A,#0
MOVX @DPTR,A
LJMP START
END

结果:

4. 例题



  1. 动态显示(C51)

#include <reg51.h>
#define SUM 4

typedef struct _PanelNumber
{
    unsigned char digitalNum;
    unsigned char port;
}PanelNumber;

void delay(void);

int main(void)
{
    PanelNumber numberSet[SUM]={{0xF9,0x70},    //num:1 port:P2^7
                                {0xA4,0xb0},    //num:2 port:P2^6
                                {0xB0,0xd0},    //num:3 port:P2^5
                                {0x99,0xe0}};    //num:4 port:P2^4
    int i;
    while(1)
    {
        for(i = 0;i!=SUM;i++)
        {
            P2 = 0xff;
            P2 = numberSet[i].port;
            P0 = numberSet[i].digitalNum;
            delay();
        }
    }
    return 0;
}

void delay(void)
{
    unsigned char i,j;
    for (i=0;i<30;i++)
    {
        for (j=0;j<170;j++);
    }
}

2. 电压表(C51)

voltmeter.c

 1 #include <reg51.h>
 2 #include "voltmeter.h"
 3
 4 static NumberPanel numberPanel[3];
 5
 6 int main(void)
 7 {
 8     IT0 = 1;//failling edge trigger
 9     EX0 = 1;//enable interrupt 0
10     EA = 1;//enable global interrupt
11
12     numberPanel[0].outputPort = 0xfbff;
13     numberPanel[1].outputPort = 0xfdff;
14     numberPanel[2].outputPort = 0xfeff;
15
16     START_ADC(adcAddress);//start adc transformation
17
18     while(1);
19     return 0;
20 }
21
22 void OnADCTransform_Completed()
23     interrupt INT0 using REGISTER_0
24 {
25     unsigned char result = 0;
26     float rResult;
27
28     READ_DATA(result,adcAddress);
29
30     rResult = (float)result * 0.0196078;
31     rResult *= 100;
32
33     translateResult((int)(rResult));
34
35     START_ADC(adcAddress);//restart adc transformation
36 }
37
38 void translateResult(int result)
39 {
40     int dividend = 100,i = 2;
41     unsigned char number;
42
43     for(;dividend != 0; dividend /= 10, i--)
44     {
45         number = digitalNumberSet[result/ dividend];
46         result %= dividend;
47
48         //open WD and output the data,
49         //the data will lock in the register while WD is low level
50         OUTPUT_DATA(i,number);
51     }
52 }

voltmeter.h

 1 #define INT0 0
 2 #define REGISTER_0 0
 3 #define START_ADC(a) ((*a) = 0)
 4 #define OUTPUT_DATA(i,data) ((*(numberPanel[i].outputPort)) = data)
 5 #define READ_DATA(data,add) (data = (*add))
 6
 7 //choose channel 0, while P2.7 is low level
 8 unsigned char xdata *const adcAddress = 0x0ff8;
 9
10 typedef struct _NumberPanel
11 {
12     unsigned char xdata *outputPort;
13 }NumberPanel;
14
15 unsigned char const digitalNumberSet[]
16                     = {0xC0, 0xF9, 0xA4, 0xB0,
17                        0x99, 0x92, 0x82, 0xF8,
18                        0x00, 0x90, 0x88, 0x83,
19                        0xC6, 0xA1, 0x86, 0x8E};
20
21 void translateResult(unsigned char result);

仿真:http://pan.baidu.com/s/1jHLCZrC

时间: 2024-12-20 13:05:40

单片微机原理P3:80C51外部拓展系统的相关文章

单片微机原理P2:80C51外部中断与定时器系统

0. 外部中断 书上的废话当然是很多的了,对于中断我想大家应该早就有一个很直观的认识,就是"设置断点,执行外部外码,然后返回断点"这样的三个过程.中断给系统提供了一个良好的响应模式.当然了,响应中断的时候记得保护现场,这是写汇编的良好习惯. 80C51一共是5个中断源,这五个中断源分别是外部中断0,1定时器中断0,1,串口中断. 1. 我们现在先来看外部中断: 一般开外部中断分为4个步骤(不用查询的方式的话): 1. 设置触发方式(IT0/IT1) 2. 开启外部中断(EX0/EX1)

单片微机原理P4:80C51串口与串行总线拓展

0. 串口通讯 0. 串口通讯的数据传输方式:单工(单向传输数据),半双工(非同时双向传输),全双工(同时,双向传输) 1. 根据通信方式的不同又分为同步通讯和异步通讯. 同步通讯:所有设备都使用同一个时钟,称为同步时钟.在数据传送时,以若干个数据字符(称为数据块)为单位进行传输,每个数据块包括同步字符.数据块和校验字符CRC. 异步通信是指在串行通信中,接收设备和发送设备有各自的时钟信号,异步通信以字符为单位进行数据传送,不过通信中这些时钟频率必须保持一致. 2. 波特率和比特率 波特率是每秒

微机原理与接口(1)——基础知识

 微机的基本构成:     硬件设备:         由运算器.控制器.存储器.输入.输出设备: 软件    :         系统软件.程序设计语言.应用软件: CPU:整个计算机硬件的控制指挥中心.     构成:        运算:算术逻辑单元(Arithmetic Logic Unit,ALU).Acc(Accumulator)累加器.状态寄存器(Flag Register,FR)和寄存器组(Register Set,RS).        控制:程序计数器(Program Cou

连载:(二)循序渐进,通过XML配置,实现通用于WinForm(.Net)、WebForm(Asp.Net+JQuery+EasyUI)表单、报表--原理

连载:(二)循序渐进,通过XML配置,实现通用于WinForm(.Net).WebForm(Asp.Net+JQuery+EasyUI)表单.报表 --原理 作者:长江支流 本原理,适用于Window Form的CS,也适用于ASP.Net的BS. 在描述原理之前,先来看个传统的ORM写代码的例子. 实体映射 现在很多架构实现ORM,去动态的生成代码,实现数据增.删.改.查的功能. 实体的映射关系,是通过代码的方式进行映射的,是否可以通过XML文件,来配置实例的映射关系,答案是肯定的. 代码映射

“小程序+”时代——公众号拓展系统

如今,微信已经成为全球使用人数最多的移动通讯应用,用户数量呈爆发式增长,是当前中国最重要的智能手机应用终端之一.而微信公众号于2012年8月诞生,至今约有上千万个微信公众号. 而微信小程序于2017年1月9日凌晨正式上线.小程序一开始作为微信生态万物互联的连接器出现,具备链接线上与线下的诸多能力.因此,大量的线下传统企业为了实现互联网+,提升企业效率,就刚好找到这个需要合适的渠道连接器. 在这种国内小程序蓬勃发展的大前提下,11月22日,在微盟小程序沙龙长沙站上,微盟创始人兼CEO孙涛勇现场就小

OSPF路由协议之单域的原理与配置

在上一章我们学习了动态路由协议RIP,但是对于某些应用来说,RIP路由协议还有些不足.例如:计算路径的成本以跳数作为唯一的度量值,不能根据带宽来计算成本:跳数最大为15跳,限制了网络的规模:收敛慢等.而OSPF适用于更大型的网络.收敛快.根据带宽计算路径成本等优点,因此在实际应用中,OSPF应用更广泛. 开放式最短路径优先协议(OSFP)是基于开放标准的链路状态路由选择协议,它完成各路由选择协议算法的两大主要功能:路径选择和路径交换. OSPF路由协议概述 1. OSPF是内部网关路由协议 在共

AJAX练习(一):制作可以自动校验的表单(从原理上分析ajax的作用)

继上文(AJAX(一)AJAX的简介和基础)作为联系. 传统网页在注册时检测用户名是否被占用,传统的校验显然缓慢笨拙. 当ajax出现后,这种体验有了很大的改观,因为在用户填写表单时,签名的表单项已经发送给了服务器,然后根据用户填写好的内容进行数据查询.在查询号无需页面刷新就自动给了提示.类似这样的应用大大的提高了用户的体验,本节简单介绍自动校验表单制作方法.从原理上分析ajax的作用. 1.搭建框架 首先为html框架 <form name="register"> <

微机原理(2)8086

********8086******* 16位机 20根地址线寻址1MB内存(20的20次) 2的16次I/O端口 CPU内部结构 8086:BIU(Bus Interface Unit)总线接口单元 EU (Execution Unit)执行单元 8088:外部8位 只有4字节指令缓冲器 工作原理: 1.BIU从内部寄存器中取地址:如CS:IP的地址为CS*16+IP发送到6字节的指令缓冲器中 2.EU从指令缓冲区中取出地址,并执行相应的I/O周期操作. 3.当6字节的指令存满,BIU处于空闲

微机原理与接口技术一

1.1946年2月14日世界上第一台电脑ENIAC在美国宾夕法尼亚大学诞生. 2.第一台微机   出现于1971年的 Intel公司,微处理器是4004,6万次/秒. 3.内存4GB(1G=1024M,1M=1024K,1K=1024B), 主频:4GHZ(1G=1000M,1M=1000K,1K=1000HZ) 4.字长:cup一次能处理二进制信息的位数. 5.按照cpu个数的不同分为巨型机,大型机,中型机,小型机,微机 微机:一台机一个cpu 小型机:cpu〉=4 大型机:cpu〉=128