注册忘记密码

长清大学城论坛

    查看: 6440|回复: 28

    6个单片机实验

      [复制链接]
    发表于 2011-5-8 19:47:56 | 显示全部楼层 |阅读模式
    1. 闪烁灯
    1.  实验任务
    如图4.1.1所示:在P1.0端口上接一个发光二极管L1,使L1在不停地一亮一灭,一亮一灭的时间间隔为0.2秒。
    2.  电路原理图
    file:///C:/Users/asus/AppData/Local/Temp/ksohtml/wps_clip_image-23048.png
    图4.1.1
    3.  系统板上硬件连线
    把“单片机系统”区域中的P1.0端口用导线连接到“八路发光二极管指示模块”区域中的L1端口上。
    4.  程序设计内容
    (1). 延时程序的设计方法
    作为单片机的指令的执行的时间是很短,数量大微秒级,因此,我们要求的闪烁时间间隔为0.2秒,相对于微秒来说,相差太大,所以我们在执行某一指令时,插入延时程序,来达到我们的要求,但这样的延时程序是如何设计呢?下面具体介绍其原理:
    如图4.1.1所示的石英晶体为12MHz,因此,1个机器周期为1微秒
    机器周期 微秒
    MOV R6,#20 2个机器周期  2
    file:///C:/Users/asus/AppData/Local/Temp/ksohtml/wps_clip_image-26623.pngD1: MOV R7,#248 2个机器周期  2       2+2×248=498 20×
    file:///C:/Users/asus/AppData/Local/Temp/ksohtml/wps_clip_image-23052.pngfile:///C:/Users/asus/AppData/Local/Temp/ksohtml/wps_clip_image-4603.pngDJNZ R7,$ 2个机器周期  2×248             498
    DJNZ R6,D1 2个机器周期   2×20=40         10002
    因此,上面的延时程序时间为10.002ms。
    由以上可知,当R6=10、R7=248时,延时5ms,R6=20、R7=248时,延时10ms,以此为基本的计时单位。如本实验要求0.2秒=200ms,10ms×R5=200ms,则R5=20,延时子程序如下:
    DELAY: MOV R5,#20
    D1: MOV R6,#20
    D2: MOV R7,#248
    DJNZ R7,$
    DJNZ R6,D2
    DJNZ R5,D1
    RET
    (2). 输出控制
    如图1所示,当P1.0端口输出高电平,即P1.0=1时,根据发光二极管的单向导电性可知,这时发光二极管L1熄灭;当P1.0端口输出低电平,即P1.0=0时,发光二极管L1亮;我们可以使用SETB P1.0指令使P1.0端口输出高电平,使用CLR P1.0指令使P1.0端口输出低电平。
    5. 程序框图
       如图4.1.2所示
     
    file:///C:/Users/asus/AppData/Local/Temp/ksohtml/wps_clip_image-20826.png 
     
     
     
     
     
     

    7. C语言源程序
    #include <AT89X51.H>
    sbit L1=P1^0;

    void delay02s(void) //延时0.2秒子程序
    {
    unsigned char i,j,k;
    for(i=20;i>0;i--)
    for(j=20;j>0;j--)
    for(k=248;k>0;k--);
    }


    void main(void)
    {
    while(1)
    {
    L1=0;
    delay02s();
    L1=1;
    delay02s();
    }
    }
    2. 模拟开关灯
    1. 实验任务
    如图4.2.1所示,监视开关K1(接在P3.0端口上),用发光二极管L1(接在单片机P1.0端口上)显示开关状态,如果开关合上,L1亮,开关打开,L1熄灭。
    2. 电路原理图
    file:///C:/Users/asus/AppData/Local/Temp/ksohtml/wps_clip_image-23182.png
    图4.2.1
    3. 系统板上硬件连线
    (1). 把“单片机系统”区域中的P1.0端口用导线连接到“八路发光二极管指示模块”区域中的L1端口上;
    (2). 把“单片机系统”区域中的P3.0端口用导线连接到“四路拨动开关”区域中的K1端口上;
    4. 程序设计内容
    (1). 开关状态的检测过程
    单片机对开关状态的检测相对于单片机来说,是从单片机的P3.0端口输入信号,而输入的信号只有高电平和低电平两种,当拨开开关K1拨上去,即输入高电平,相当开关断开,当拨动开关K1拨下去,即输入低电平,相当开关闭合。单片机可以采用JB BIT,REL或者是JNB BIT,REL指令来完成对开关状态的检测即可。
    (2). 输出控制
    如图3所示,当P1.0端口输出高电平,即P1.0=1时,根据发光二极管的单向导电性可知,这时发光二极管L1熄灭;当P1.0端口输出低电平,即P1.0=0时,发光二极管L1亮;我们可以使用SETB P1.0指令使P1.0端口输出高电平,使用CLR P1.0指令使P1.0端口输出低电平。
    5. 程序框图
    file:///C:/Users/asus/AppData/Local/Temp/ksohtml/wps_clip_image-8556.png
    图4.2.2
    6. 汇编源程序 ORG 00H
    START: JB P3.0,LIG
    CLR P1.0
    SJMP START
    LIG: SETB P1.0
    SJMP START
    END
    7. C语言源程序
    #include <AT89X51.H>
    sbit K1=P3^0;
    sbit L1=P1^0;
    void main(void)
    {
    while(1)
    {
    if(K1==0)
    {
    L1=0; //灯亮
    }
    else
    {
    L1=1; //灯灭
    }
    }
    }

        3. 多路开关状态指示
    1. 实验任务
    如图4.3.1所示,AT89S51单片机的P1.0-P1.3接四个发光二极管L1-L4,P1.4-P1.7接了四个开关K1-K4,编程将开关的状态反映到发光二极管上。(开关闭合,对应的灯亮,开关断开,对应的灯灭)。
    2. 电路原理图
    file:///C:/Users/asus/AppData/Local/Temp/ksohtml/wps_clip_image-23238.png
    图4.3.1
    3. 系统板上硬件连线
    (1. 把“单片机系统”区域中的P1.0-P1.3用导线连接到“八路发光二极管指示模块”区域中的L1-L4端口上;
    (2. 把“单片机系统”区域中的P1.4-P1.7用导线连接到“四路拨动开关”区域中的K1-K4端口上;
    4. 程序设计内容
    (1. 开关状态检测
    对于开关状态检测,相对单片机来说,是输入关系,我们可轮流检测每个开关状态,根据每个开关的状态让相应的发光二极管指示,可以采用JB P1.X,REL或JNB P1.X,REL指令来完成;也可以一次性检测四路开关状态,然后让其指示,可以采用MOV A,P1指令一次把P1端口的状态全部读入,然后取高4位的状态来指示。
    (2. 输出控制
    根据开关的状态,由发光二极管L1-L4来指示,我们可以用SETB P1.X和CLR P1.X指令来完成,也可以采用MOV P1,#1111XXXXB方法一次指示。
    5. 程序框图
     
    读P1口数据到ACC中
    ACC内容右移4次
    ACC内容与F0H相或
    ACC内容送入P1口
    <![endif]--> file:///C:/Users/asus/AppData/Local/Temp/ksohtml/wps_clip_image-27439.png
    图4.3.2
    6. 方法一(汇编源程序)
    ORG 00H
    START: MOV A,P1
    ANL A,#0F0H
    RR A
    RR A
    RR A
    RR A
    ORl A,#0F0H
    MOV P1,A
    SJMP START
    END
    7. 方法一(C语言源程序)
    #include <AT89X51.H>
    unsigned char temp;

    void main(void)
    {
    while(1)
    {
    temp=P1>>4;
    temp=temp | 0xf0;
    P1=temp;
    }
    }
    8. 方法二(汇编源程序)
    ORG 00H
    START: JB P1.4,NEXT1
    CLR P1.0
    SJMP NEX1
    NEXT1: SETB P1.0
    NEX1: JB P1.5,NEXT2
    CLR P1.1
    SJMP NEX2
    NEXT2: SETB P1.1
    NEX2: JB P1.6,NEXT3
    CLR P1.2
    SJMP NEX3
    NEXT3: SETB P1.2
    NEX3: JB P1.7,NEXT4
    CLR P1.3
    SJMP NEX4
    NEXT4: SETB P1.3
    NEX4: SJMP START
    END
    9. 方法二(C语言源程序)
    #include <AT89X51.H>

    void main(void)
    {
    while(1)
    {
    if(P1_4==0)
    {
    P1_0=0;
    }
    else
    {
    P1_0=1;
    }
    if(P1_5==0)
    {
    P1_1=0;
    }
    else
    {
    P1_1=1;
    }
    if(P1_6==0)
    {
    P1_2=0;
    }
    else
    {
    P1_2=1;
    }
    if(P1_7==0)
    {
    P1_3=0;
    }
    else
    {
    P1_3=1;
    }
    }
    }
    4
        3. 多路开关状态指示
    1. 实验任务
    如图4.3.1所示,AT89S51单片机的P1.0-P1.3接四个发光二极管L1-L4,P1.4-P1.7接了四个开关K1-K4,编程将开关的状态反映到发光二极管上。(开关闭合,对应的灯亮,开关断开,对应的灯灭)。
    2. 电路原理图
    file:///C:/Users/asus/AppData/Local/Temp/ksohtml/wps_clip_image-23238.png
    图4.3.1
    3. 系统板上硬件连线
    (1. 把“单片机系统”区域中的P1.0-P1.3用导线连接到“八路发光二极管指示模块”区域中的L1-L4端口上;
    (2. 把“单片机系统”区域中的P1.4-P1.7用导线连接到“四路拨动开关”区域中的K1-K4端口上;
    4. 程序设计内容
    (1. 开关状态检测
    对于开关状态检测,相对单片机来说,是输入关系,我们可轮流检测每个开关状态,根据每个开关的状态让相应的发光二极管指示,可以采用JB P1.X,REL或JNB P1.X,REL指令来完成;也可以一次性检测四路开关状态,然后让其指示,可以采用MOV A,P1指令一次把P1端口的状态全部读入,然后取高4位的状态来指示。
    (2. 输出控制
    根据开关的状态,由发光二极管L1-L4来指示,我们可以用SETB P1.X和CLR P1.X指令来完成,也可以采用MOV P1,#1111XXXXB方法一次指示。
    5. 程序框图
     
    读P1口数据到ACC中
    ACC内容右移4次
    ACC内容与F0H相或
    ACC内容送入P1口
    <![endif]--> file:///C:/Users/asus/AppData/Local/Temp/ksohtml/wps_clip_image-27439.png
    图4.3.2
    6. 方法一(汇编源程序)
    ORG 00H
    START: MOV A,P1
    ANL A,#0F0H
    RR A
    RR A
    RR A
    RR A
    ORl A,#0F0H
    MOV P1,A
    SJMP START
    END
    7. 方法一(C语言源程序)
    #include <AT89X51.H>
    unsigned char temp;

    void main(void)
    {
    while(1)
    {
    temp=P1>>4;
    temp=temp | 0xf0;
    P1=temp;
    }
    }
    8. 方法二(汇编源程序)
    ORG 00H
    START: JB P1.4,NEXT1
    CLR P1.0
    SJMP NEX1
    NEXT1: SETB P1.0
    NEX1: JB P1.5,NEXT2
    CLR P1.1
    SJMP NEX2
    NEXT2: SETB P1.1
    NEX2: JB P1.6,NEXT3
    CLR P1.2
    SJMP NEX3
    NEXT3: SETB P1.2
    NEX3: JB P1.7,NEXT4
    CLR P1.3
    SJMP NEX4
    NEXT4: SETB P1.3
    NEX4: SJMP START
    END
    9. 方法二(C语言源程序)
    #include <AT89X51.H>

    void main(void)
    {
    while(1)
    {
    if(P1_4==0)
    {
    P1_0=0;
    }
    else
    {
    P1_0=1;
    }
    if(P1_5==0)
    {
    P1_1=0;
    }
    else
    {
    P1_1=1;
    }
    if(P1_6==0)
    {
    P1_2=0;
    }
    else
    {
    P1_2=1;
    }
    if(P1_7==0)
    {
    P1_3=0;
    }
    else
    {
    P1_3=1;
    }
    }
    }
    4. 广告灯的左移右移
    1. 实验任务
    做单一灯的左移右移,硬件电路如图4.4.1所示,八个发光二极管L1-L8分别接在单片机的P1.0-P1.7接口上,输出“0”时,发光二极管亮,开始时P1.0→P1.1→P1.2→P1.3→┅→P1.7→P1.6→┅→P1.0亮,重复循环。
    2. 电路原理图
    file:///C:/Users/asus/AppData/Local/Temp/ksohtml/wps_clip_image-23404.png
    图4.4.1
    3. 系统板上硬件连线
    把“单片机系统”区域中的P1.0-P1.7用8芯排线连接到“八路发光二极管指示模块”区域中的L1-L8端口上,要求:P1.0对应着L1,P1.1对应着L2,……,P1.7对应着L8。
    4. 程序设计内容
    我们可以运用输出端口指令MOV P1,A或MOV P1,#DATA,只要给累加器值或常数值,然后执行上述的指令,即可达到输出控制的动作。
    每次送出的数据是不同,具体的数据如下表1所示 :
    P1.7
    P1.6
    P1.5
    P1.4
    P1.3
    P1.2
    P1.1
    P1.0
    说明
    L8
    L7
    L6
    L5
    L4
    L3
    L2
    L1
     
    1
    1
    1
    1
    1
    1
    1
    0
    L1亮
    1
    1
    1
    1
    1
    1
    0
    1
    L2亮
    1
    1
    1
    1
    1
    0
    1
    1
    L3亮
    1
    1
    1
    1
    0
    1
    1
    1
    L4亮
    1
    1
    1
    0
    1
    1
    1
    1
    L5亮
    1
    1
    0
    1
    1
    1
    1
    1
    L6亮
    1
    0
    1
    1
    1
    1
    1
    1
    L7亮
    0
    1
    1
    1
    1
    1
    1
    1
    L8亮
    表1
    file:///C:/Users/asus/AppData/Local/Temp/ksohtml/wps_clip_image-18551.png5. 程序框图
     
     
     
     
     
     
    图4.4.2
    6. 汇编源程序
    ORG 0
    START: MOV R2,#8
    MOV A,#0FEH
    SETB C
    LOOP: MOV P1,A
    LCALL DELAY
    RLC A
    DJNZ R2,LOOP
    MOV R2,#8
    LOOP1: MOV P1,A
    LCALL DELAY
    RRC A
    DJNZ R2,LOOP1
    LJMP START
    DELAY: MOV R5,#20 ;
    D1: MOV R6,#20
    D2: MOV R7,#248
    DJNZ R7,$
    DJNZ R6,D2
    DJNZ R5,D1
    RET
    END
    7. C语言源程序
    #include <AT89X51.H>
    unsigned char i;
    unsigned char temp;
    unsigned char a,b;

    void delay(void)
    {
    unsigned char m,n,s;
    for(m=20;m>0;m--)
    for(n=20;n>0;n--)
    for(s=248;s>0;s--);
    }
    void main(void)
    {
    while(1)
    {
    temp=0xfe;
    P1=temp;
    delay();
    for(i=1;i<8;i++)
    {
    a=temp<<i;
    b=temp>>(8-i);
    P1=a|b;
    delay();
    }
    for(i=1;i<8;i++)
    {
    a=temp>>i;
    b=temp<<(8-i);
    P1=a|b;
    delay();
    }
    }
    }

    5. 广告灯(利用取表方式)
    1. 实验任务
    利用取表的方法,使端口P1做单一灯的变化:左移2次,右移2次,闪烁2次(延时的时间0.2秒)。
    2. 电路原理图
    file:///C:/Users/asus/AppData/Local/Temp/ksohtml/wps_clip_image-23457.png
    图4.5.1
    3. 系统板上硬件连线
      把“单片机系统”区域中的P1.0-P1.7用8芯排线连接到“八路发光二极管指示模块”区域中的L1-L8端口上,要求:P1.0对应着L1,P1.1对应着L2,……,P1.7对应着L8。
    4. 程序设计内容
    在用表格进行程序设计的时候,要用以下的指令来完成
    (1). 利用MOV DPTR,#DATA16的指令来使数据指针寄存器指到表的开头。
    (2). 利用MOVC A,@A+DPTR的指令,根据累加器的值再加上DPTR的值,就可以使程序计数器PC指到表格内所要取出的数据。
    因此,只要把控制码建成一个表,而利用MOVC A,@A+DPTR做取码的操作,就可方便地处理一些复杂的控制动作,取表过程如下图所示:
    5. 程序框图
    file:///C:/Users/asus/AppData/Local/Temp/ksohtml/wps_clip_image-26686.png 
     
     
     
     
     
     
     
     
     
     
    图4.5.2
    6. 汇编源程序
    ORG 0
    START: MOV DPTR,#TABLE
    LOOP: CLR A
    MOVC A,@A+DPTR
    CJNE A,#01H,LOOP1
    JMP START
    LOOP1: MOV P1,A
    MOV R3,#20
    LCALL DELAY
    INC DPTR
    JMP LOOP
    DELAY: MOV R4,#20
    D1: MOV R5,#248
    DJNZ R5,$
    DJNZ R4,D1
    DJNZ R3,DELAY
    RET
    TABLE: DB 0FEH,0FDH,0FBH,0F7H
    DB 0EFH,0DFH,0BFH,07FH
    DB 0FEH,0FDH,0FBH,0F7H
    DB 0EFH,0DFH,0BFH,07FH
    DB 07FH,0BFH,0DFH,0EFH
    DB 0F7H,0FBH,0FDH,0FEH
    DB 07FH,0BFH,0DFH,0EFH
    DB 0F7H,0FBH,0FDH,0FEH
    DB 00H, 0FFH,00H, 0FFH
    DB 01H
    END
    7. C语言源程序
    #include <AT89X51.H>
    unsigned char code table[]={0xfe,0xfd,0xfb,0xf7,
    0xef,0xdf,0xbf,0x7f,
    0xfe,0xfd,0xfb,0xf7,
    0xef,0xdf,0xbf,0x7f,
    0x7f,0xbf,0xdf,0xef,
    0xf7,0xfb,0xfd,0xfe,
    0x7f,0xbf,0xdf,0xef,
    0xf7,0xfb,0xfd,0xfe,
    0x00,0xff,0x00,0xff,
    0x01};
    unsigned char i;

    void delay(void)
    {
    unsigned char m,n,s;
    for(m=20;m>0;m--)
    for(n=20;n>0;n--)
    for(s=248;s>0;s--);
    }

    void main(void)
    {
    while(1)
    {
    if(table!=0x01)
    {
    P1=table;
    i++;
    delay();
    }
    else
    {
    i=0;
    }
    }
    }
    6. 报警产生器
    1. 实验任务
    用P1.0输出1KHz和500Hz的音频信号驱动扬声器,作报警信号,要求1KHz信号响100ms,500Hz信号响200ms,交替进行,P1.7接一开关进行控制,当开关合上响报警信号,当开关断开告警信号停止,编出程序。
    2. 电路原理图
    file:///C:/Users/asus/AppData/Local/Temp/ksohtml/wps_clip_image-23515.png
    图4.6.1
    3. 系统板上硬件连线
    (1. 把“单片机系统”区域中的P1.0端口用导线连接到“音频放大模块”区域中的SPK IN端口上;
    (2. 在“音频放大模块”区域中的SPK OUT端口上接上一个8欧的或者是16欧的喇叭;
    (3. 把“单片机系统”区域中的P1.7/RD端口用导线连接到“四路拨动开关”区域中的K1端口上;
    4. 程序设计内容
    (1. 信号产生的方法
    500Hz信号周期为2ms,信号电平为每1ms变反1次,1KHz的信号周期为1ms,信号电平每500us变反1次;
     
    5. 程序框图
    file:///C:/Users/asus/AppData/Local/Temp/ksohtml/wps_clip_image-23549.png
    图4.6.2
    6. 汇编源程序
    FLAG BIT 00H
    ORG 00H
    START: JB P1.7,START
    JNB FLAG,NEXT
    MOV R2,#200
    DV: CPL P1.0
    LCALL DELY500
    LCALL DELY500
    DJNZ R2,DV
    CPL FLAG
    NEXT: MOV R2,#200
    DV1: CPL P1.0
    LCALL DELY500
    DJNZ R2,DV1
    CPL FLAG
    SJMP START
    DELY500: MOV R7,#250
    LOOP: NOP
    DJNZ R7,LOOP
    RET
    END
    7. C语言源程序
    #include <AT89X51.H>
    #include <INTRINS.H>

    bit flag;
    unsigned char count;

    void dely500(void)
    {
    unsigned char i;
    for(i=250;i>0;i--)
    {
    _nop_();
    }
    }

    void main(void)
    {
    while(1)
    {
    if(P1_7==0)
    {
    for(count=200;count>0;count--)
    {
    P1_0=~P1_0;
    dely500();
    }
    for(count=200;count>0;count--)
    {
    P1_0=~P1_0;
    dely500();
    dely500();
    }
    }
    }
    7. I/O并行口直接驱动LED显示
    1. 实验任务
    如图13所示,利用AT89S51单片机的P0端口的P0.0-P0.7连接到一个共阴数码管的a-h的笔段上,数码管的公共端接地。在数码管上循环显示0-9数字,时间间隔0.2秒。
    2. 电路原理图
    file:///C:/Users/asus/AppData/Local/Temp/ksohtml/wps_clip_image-23577.png
    图4.7.1
    3. 系统板上硬件连线
    把“单片机系统”区域中的P0.0/AD0-P0.7/AD7端口用8芯排线连接到“四路静态数码显示模块”区域中的任一个数码管的a-h端口上;要求:P0.0/AD0与a相连,P0.1/AD1与b相连,P0.2/AD2与c相连,……,P0.7/AD7与h相连。
    4. 程序设计内容
    (1. LED数码显示原理
    七段LED显示器内部由七个条形发光二极管和一个小圆点发光二极管组成,根据各管的极管的接线形式,可分成共阴极型和共阳极型。
    LED数码管的g~a七个发光二极管因加正电压而发亮,因加零电压而不以发亮,不同亮暗的组合就能形成不同的字形,这种组合称之为字形码,下面给出共阴极的字形码见表2
    “0”
    3FH
     
    “8”
    7FH
     
    “1”
    06H
     
    “9”
    6FH
     
    “2”
    5BH
     
    “A”
    77H
     
    “3”
    4FH
     
    “b”
    7CH
     
    “4”
    66H
     
    “C”
    39H
     
    “5”
    6DH
     
    “d”
    5EH
     
    “6”
    7DH
     
    “E”
    79H
     
    “7”
    07H
     
    “F”
    71H
     
    (2. 由于显示的数字0-9的字形码没有规律可循,只能采用查表的方式来完成我们所需的要求了。这样我们按着数字0-9的顺序,把每个数字的笔段代码按顺序排好!建立的表格如下所示:TABLE DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH
    file:///C:/Users/asus/AppData/Local/Temp/ksohtml/wps_clip_image-31161.png5.程序框图
     
     
     
     
     
     
     
     
    图4.7.2
    6. 汇编源程序
    ORG 0
    START: MOV R1,#00H
    NEXT: MOV A,R1
    MOV DPTR,#TABLE
    MOVC A,@A+DPTR
    MOV P0,A
    LCALL DELAY
    INC R1
    CJNE R1,#10,NEXT
    LJMP START
    DELAY: MOV R5,#20
    D2: MOV R6,#20
    D1: MOV R7,#248
    DJNZ R7,$
    DJNZ R6,D1
    DJNZ R5,D2
    RET
    TABLE: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH
    END
    7. C语言源程序
    #include <AT89X51.H>
    unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,
    0x6d,0x7d,0x07,0x7f,0x6f};
    unsigned char dispcount;

    void delay02s(void)
    {
    unsigned char i,j,k;
    for(i=20;i>0;i--)
    for(j=20;j>0;j--)
    for(k=248;k>0;k--);
    }

    void main(void)
    {
    while(1)
    {
    for(dispcount=0;dispcount<10;dispcount++)
    {
    P0=table[dispcount];
    delay02s();
    }
    }
    }
    8. 按键识别方法之一
    1. 实验任务
    每按下一次开关SP1,计数值加1,通过AT89S51单片机的P1端口的P1.0到P1.3显示出其的二进制计数值。
    2. 电路原理图
    file:///C:/Users/asus/AppData/Local/Temp/ksohtml/wps_clip_image-23620.png
    图4.8.1
    3. 系统板上硬件连线
    (1. 把“单片机系统”区域中的P3.7/RD端口连接到“独立式键盘”区域中的SP1端口上;
    (2. 把“单片机系统”区域中的P1.0-P1.4端口用8芯排线连接到“八路发光二极管指示模块”区域中的“L1-L8”端口上;要求,P1.0连接到L1,P1.1连接到L2,P1.2连接到L3,P1.3连接到L4上。
    4. 程序设计方法
    (1. 其实,作为一个按键从没有按下到按下以及释放是一个完整的过程,也就是说,当我们按下一个按键时,总希望某个命令只执行一次,而在按键按下的 过程中,不要有干扰进来,因为,在按下的过程中,一旦有干扰过来,可能造成误触发过程,这并不是我们所想要的。因此在按键按下的时候,
    file:///C:/Users/asus/AppData/Local/Temp/ksohtml/wps_clip_image-7050.png 
    图4.8.2
    要把我们手上的干扰信号以及按键的机械接触等干扰信号给滤除掉,一般情况下,我们可以采用电容来滤除掉这些干扰信号,但实际上,会增加硬件成本及硬件电路的体积,这是我们不希望,总得有个办法解决这个问题,因此我们可以采用软件滤波的方法去除这些干扰
    信号,一般情况下,一个按键按下的时候,总是在按下的时刻存在着一定的干扰信号,按下之后就基本上进入了稳定的状态。具体的一个按键从按下到释放的全过程的信号图如上图所示:
    从图中可以看出,我们在程序设计时,从按键被识别按下之后,延时5ms以上,从而避开了干扰信号区域,我们再来检测一次,看按键是否真得已经按下,若真得已经按下,这时肯定输出为低电平,若这时检测到的是高电平,证明刚才是由于干扰信号引起的误触发,CPU就认为是误触发信号而舍弃这次的按键识别过程。从而提高了系统的可靠性。
    由于要求每按下一次,命令被执行一次,直到下一次再按下的时候,再执行一次命令,因此从按键被识别出来之后,我们就可以执行这次的命令,所以要有一个等待按键释放的过程,显然释放的过程,就是使其恢复成高电平状态。
    (1. 对于按键识别的指令,我们依然选择如下指令JB BIT,REL指令是用来检测BIT是否为高电平,若BIT=1,则程序转向REL处执行程序,否则就继续向下执行程序。或者是 JNB BIT,REL指令是用来检测BIT是否为低电平,若BIT=0,则程序转向REL处执行程序,否则就继续向下执行程序。
    (2. 但对程序设计过程中按键识别过程的框图如右图所示:file:///C:/Users/asus/AppData/Local/Temp/ksohtml/wps_clip_image-16232.png                 图4.8.3
    5. 程序框图
    file:///C:/Users/asus/AppData/Local/Temp/ksohtml/wps_clip_image-2284.png
    图4.8.4
    6. 汇编源程序
    ORG 0
    START: MOV R1,#00H ;初始化R1为0,表示从0开始计数
    MOV A,R1 ;
    CPL A ;取反指令
    MOV P1,A ;送出P1端口由发光二极管显示
    REL: JNB P3.7,REL ;判断SP1是否按下
    LCALL DELAY10MS ;若按下,则延时10ms左右
    JNB P3.7,REL ;再判断SP1是否真得按下
    INC R1 ;若真得按下,则进行按键处理,使
    MOV A,R1 ;计数内容加1,并送出P1端口由
    CPL A ;发光二极管显示
    MOV P1,A ;
    JNB P3.7,$ ;等待SP1释放
    SJMP REL ;继续对K1按键扫描
    DELAY10MS: MOV R6,#20 ;延时10ms子程序
    L1: MOV R7,#248
    DJNZ R7,$
    DJNZ R6,L1
    RET
    END




    7. C语言源程序
    #include <AT89X51.H>

    unsigned char count;

    void delay10ms(void)
    {
    unsigned char i,j;
    for(i=20;i>0;i--)
    for(j=248;j>0;j--);
    }

    void main(void)
    {
    while(1)
    {
    if(P3_7==0)
    {
    delay10ms();
    if(P3_7==0)
    {
    count++;
    if(count==16)
    {
    count=0;
    }
    P1=~count;
    while(P3_7==0);
    }
    }
    }
    }
    9. 一键多功能按键识别技术
    1.实验任务
    如图4.9.1所示,开关SP1接在P3.7/RD管脚上,在AT89S51单片机的P1端口接有四个发光二极管,上电的时候,L1接在P1.0管脚上的发光二极管在闪烁,当每一次按下开关SP1的时候,L2接在P1.1管脚上的发光二极管在闪烁,再按下开关SP1的时候,L3接在P1.2管脚上的发光二极管在闪烁,再按下开关SP1的时候,L4接在P1.3管脚上的发光二极管在闪烁,再按下开关SP1的时候,又轮到L1在闪烁了,如此轮流下去。
    2.电路原理图
    file:///C:/Users/asus/AppData/Local/Temp/ksohtml/wps_clip_image-23662.png
    图4.9.1
    3.系统板上硬件连线
    (1. 把“单片机系统”区域中的P3.7/RD端口连接到“独立式键盘”区域中的SP1端口上;
    (2. 把“单片机系统”区域中的P1.0-P1.4端口用8芯排线连接到“八路发光二极管指示模块”区域中的“L1-L8”端口上;要求,P1.0连接到L1,P1.1连接到L2,P1.2连接到L3,P1.3连接到L4上。
    4.程序设计方法
    (1. 设计思想由来
    在我们生活中,我们很容易通过这个叫张三,那个叫李四,另外一个是王五;那是因为每个人有不同的名子,我们就很快认出,同样,对于要通过一个按键来识别每种不同的功能,我们给每个不同的功能模块用不同的ID号标识,这样,每按下一次按键,ID的值是不相同的,所以单片机就很容易识别不同功能的身份了。
    (2. 设计方法
    从上面的要求我们可以看出,L1到L4发光二极管在每个时刻的闪烁的时间是受开关SP1来控制,我们给L1到L4闪烁的时段定义出不同的ID号,当L1在闪烁时,ID=0;当L2在闪烁时,ID=1;当L3在闪烁时,ID=2;当L4在闪烁时,ID=3;很显然,只要每次按下开关K1时,分别给出不同的ID号我们就能够完成上面的任务了。下面给出有关程序设计的框图。
    5.程序框图
    file:///C:/Users/asus/AppData/Local/Temp/ksohtml/wps_clip_image-15707.png 
     
     
     
     
     
     
     
     
     
     
    图4.9.2
    6. 汇编源程序
    ID EQU 30H
    SP1 BIT P3.7
    L1 BIT P1.0
    L2 BIT P1.1
    L3 BIT P1.2
    L4 BIT P1.3
    ORG 0
    MOV ID,#00H
    START: JB K1,REL
    LCALL DELAY10MS
    JB K1,REL
    INC ID
    MOV A,ID
    CJNE A,#04,REL
    MOV ID,#00H
    REL: JNB K1,$
    MOV A,ID
    CJNE A,#00H,IS0
    CPL L1
    LCALL DELAY
    SJMP START
    IS0: CJNE A,#01H,IS1
    CPL L2
    LCALL DELAY
    SJMP START
    IS1: CJNE A,#02H,IS2
    CPL L3
    LCALL DELAY
    SJMP START
    IS2: CJNE A,#03H,IS3
    CPL L4
    LCALL DELAY
    SJMP START
    IS3: LJMP START
    DELAY10MS: MOV R6,#20
    LOOP1: MOV R7,#248
    DJNZ R7,$
    DJNZ R6,LOOP1
    RET
    DELAY: MOV R5,#20
    LOOP2: LCALL DELAY10MS
    DJNZ R5,LOOP2
    RET
    END
    7. C语言源程序
    #include <AT89X51.H>
    unsigned char ID;
    void delay10ms(void)
    {
    unsigned char i,j;
    for(i=20;i>0;i--)
    for(j=248;j>0;j--);
    }

    void delay02s(void)
    {
    unsigned char i;
    for(i=20;i>0;i--)
    {delay10ms();
    }
    }

    void main(void)
    { while(1)
    { if(P3_7==0)
    {delay10ms();
    if(P3_7==0)
    {
    ID++;
    if(ID==4)
    {
    ID=0;
    }
    while(P3_7==0);
    }
    }
    switch(ID)
    { case 0:
    P1_0=~P1_0;
    delay02s();
    break;
    case 1:
    P1_1=~P1_1;
    delay02s();
    break;
    case 2:
    P1_2=~P1_2;
    delay02s();
    break;
    case 3:
    P1_3=~P1_3;
    delay02s();
    break;
    }
    }
    }
    10. 00-99计数器
    1. 实验任务
    利用AT89S51单片机来制作一个手动计数器,在AT89S51单片机的P3.7管脚接一个轻触开关,作为手动计数的按钮,用单片机的P2.0-P2.7接一个共阴数码管,作为00-99计数的个位数显示,用单片机的P0.0-P0.7接一个共阴数码管,作为00-99计数的十位数显示;硬件电路图如图19所示。
    2. 电路原理图
    file:///C:/Users/asus/AppData/Local/Temp/ksohtml/wps_clip_image-23688.png
    图4.10.1
    3. 系统板上硬件连线
    (1. 把“单片机系统”区域中的P0.0/AD0-P0.7/AD7端口用8芯排线连接到“四路静态数码显示模块”区域中的任一个a-h端口上;要求:P0.0/AD0对应着a,P0.1/AD1对应着b,……,P0.7/AD7对应着h。
    (2. 把“单片机系统”区域中的P2.0/A8-P2.7/A15端口用8芯排线连接到“四路静态数码显示模块”区域中的任一个数码管的a-h端口上;
    (3. 把“单片机系统”区域中的P3.7/RD端口用导线连接到“独立式键盘”区域中的SP1端口上;
    4. 程序设计内容
    (1. 单片机对按键的识别的过程处理
    (2. 单片机对正确识别的按键进行计数,计数满时,又从零开始计数;
    (3. 单片机对计的数值要进行数码显示,计得的数是十进数,含有十位和个位,我们要把十位和个位拆开分别送出这样的十位和个位数值到对应的数码管上显示。如何拆开十位和个位我们可以把所计得的数值对10求余,即可得个位数字,对10整除,即可得到十位数字了。
    (4. 通过查表方式,分别显示出个位和十位数字。
    file:///C:/Users/asus/AppData/Local/Temp/ksohtml/wps_clip_image-3391.png5. 程序框图
     
     
     
     
     
     
     
    图4.10.2
    6. 汇编源程序
    Count EQU 30H
    SP1 BIT P3.7
    ORG 0
    START: MOV Count,#00H
    NEXT: MOV A,Count
    MOV B,#10
    DIV AB
    MOV DPTR,#TABLE
    MOVC A,@A+DPTR
    MOV P0,A
    MOV A,B
    MOVC A,@A+DPTR
    MOV P2,A
    WT: JNB SP1,WT
    WAIT: JB SP1,WAIT
    LCALL DELY10MS
    JB SP1,WAIT
    INC Count
    MOV A,Count
    CJNE A,#100,NEXT
    LJMP START
    DELY10MS: MOV R6,#20
    D1: MOV R7,#248
    DJNZ R7,$
    DJNZ R6,D1
    RET
    TABLE: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH
    END
    7. C语言源程序
    #include <AT89X51.H>
    unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,
    0x6d,0x7d,0x07,0x7f,0x6f};
    unsigned char Count;

    void delay10ms(void)
    {
    unsigned char i,j;
    for(i=20;i>0;i--)
    for(j=248;j>0;j--);
    }

    void main(void)
    {
    Count=0;
    P0=table[Count/10];
    P2=table[Count%10];
    while(1)
    {
    if(P3_7==0)
    {
    delay10ms();
    if(P3_7==0)
    {
    Count++;
    if(Count==100)
    {
    Count=0;
    }
    P0=table[Count/10];
    P2=table[Count%10];
    while(P3_7==0);
    }
    }
    }
    }









     楼主| 发表于 2011-5-8 19:48:33 | 显示全部楼层

    0

    主题

    4

    帖子

    14

    积分

    新手区

    Rank: 1

    性别
    保密
    发表于 2011-10-6 12:06:36 | 显示全部楼层
    天啊.  

    5

    主题

    21

    帖子

    246

    积分

    初中生

    Rank: 4Rank: 4

    QQ
    发表于 2012-3-13 20:58:06 | 显示全部楼层
      这就是 机电工程啊   理解  我也学
    用激情坚持梦想

    0

    主题

    45

    帖子

    256

    积分

    初中生

    Rank: 4Rank: 4

    性别
    保密
    学校
    山东女子学院
    发表于 2012-6-2 09:31:56 | 显示全部楼层
    没有问题,坚决支持
    dalejepang 该用户已被删除
    发表于 2012-9-26 08:52:34 | 显示全部楼层
    提示: 作者被禁止或删除 内容自动屏蔽

    0

    主题

    9

    帖子

    232

    积分

    初中生

    Rank: 4Rank: 4

    性别
    学校
    山东劳动技术学院
    发表于 2012-9-29 23:21:49 | 显示全部楼层
    哈哈 瞧你说的~~~  

    0

    主题

    7

    帖子

    188

    积分

    小学生

    Rank: 3

    性别
    保密
    学校
    山东女子学院
    发表于 2012-10-7 07:02:46 | 显示全部楼层
    顶你一下.  

    0

    主题

    17

    帖子

    354

    积分

    初中生

    Rank: 4Rank: 4

    性别
    学校
    山东女子学院
    发表于 2012-10-7 17:06:17 | 显示全部楼层
    挺好啊  

    0

    主题

    7

    帖子

    269

    积分

    初中生

    Rank: 4Rank: 4

    性别
    学校
    山东师范大学
    发表于 2012-10-7 17:06:17 | 显示全部楼层
    一个有信念者所开发出的力量,大于99个只有兴趣者。  
    [url=http://www.poloralphlaurensoldes.net] polo ralph lauren[/url]

    0

    主题

    22

    帖子

    540

    积分

    初中生

    Rank: 4Rank: 4

    性别
    保密
    学校
    山东女子学院
    发表于 2012-11-13 14:01:59 | 显示全部楼层
    今天我才发现,原来回帖真的可以拿分的,以前真的太傻了…………

    4

    主题

    17

    帖子

    270

    积分

    初中生

    Rank: 4Rank: 4

    性别
    学校
    山东交通学院
    发表于 2012-11-13 14:01:59 | 显示全部楼层
    小心大家盯上你哦  

    0

    主题

    22

    帖子

    540

    积分

    初中生

    Rank: 4Rank: 4

    性别
    保密
    学校
    山东女子学院
    发表于 2012-11-13 14:01:59 | 显示全部楼层
    呵呵 高高实在是高~~~~~  

    0

    主题

    10

    帖子

    292

    积分

    初中生

    Rank: 4Rank: 4

    性别
    学校
    山东师范大学
    发表于 2012-11-14 13:56:45 | 显示全部楼层
    不错的东西  持续关注  

    0

    主题

    4

    帖子

    90

    积分

    幼儿园

    Rank: 2Rank: 2

    性别
    学校
    山东师范大学
    发表于 2012-11-18 14:05:04 | 显示全部楼层
    你加油吧  

    发表回复

    您需要登录后才可以回帖 登录 | 免费注册

    本版积分规则

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