单片机实验五

时间:2022-12-28 19:43:46

实验5.1 采用定时器控制从P1.0输出1000Hz音频信号。

这次实验主要是为了让我们巩固定时器和计数器的相关知识,比如TMOD,TH0,TL0,TH1,TL1,IE,TR0,TR1
定时/计数器有四种工作方式


1、方式0:
TMOD中M1M0为00的时候即为方式0,方式0是13位定时/计数方式, THx 提供高八位, TLx 提供低五位, TLx 的高三位是没有用的,最大计数是 213 次方(8192个脉冲)晶振是12MHz时,最多定时8.192ms,6MHz时翻倍。
当C/ T¯¯¯=0 时,工作于定时方式,以振荡源的12分频信号作为计数脉冲,12分频信号也就是一个机器周期。
当C/ T¯¯¯=1 时,工作于计数方式,对外部脉冲输入端 T0 T1 输入的脉冲计数。
此方式需要手动重装初值。


2、方式1:
当TMOD中M1M0=01时,定时/计数器工作在方式1。
方式1与方式0基本相同,唯一的却别在于寄存器的位数是16位的,有 THx TLx 各提供8位计数器初值,最大计数数值是 216 (65536个脉冲),是几种方式之中计数值最大的一种。


3、方式2:
当TMOD中M1M0=10时,定时/计数器工作再方式2。
方式2是8位可自动重装的定时/计数方式,最大计数值为 28 (256个脉冲)
在这种方式下, THx TLx 两个寄存器中, THx 专用于8位计数初值并保持不变, TLx 进行8位加1计数。当 TLx 计数溢出时,除产生溢出中断请求外,还自动将 THx 中不变的初值重装载到 TLx 中。


4、方式3:
方式3只适用于定时/计数器0(T0)。当定时/计数器工作在方式3时, THx TLx 成为两个独立的计数器。这是 TLx 可作为定时/计数器,占用T0在TCON和TMOD寄存器中的控制位和标志位;而 THx 只能作为定时器使用,占用T1的资源TR1和TF1。在这种情况下,T1仍可用于方式0,1,2,但不能使用中断方式。
只有将T1用做串行口的波特率发生器时,T0才工作在方式3,以便早增加一个定时/计数器。
方式3 用的非常少,我没怎么用过。


这个题目要产生1000Hz的信号,所以周期是1ms,所以每500us就应该取反一次,所以定时器应该定时500us。

汇编程序:

ORG 0000H 
LJMP START 
ORG 000BH
JMP TIMER0
ORG 0040H 
START: 
MOV TMOD,#01H
MOV TH0,#0FEH
MOV TL0,#0CH
SETB P1.0
SETB EA
SETB ET0
SETB TR0
SJMP $

TIMER0:
CPL P1.0
MOV TH0,#0FEH
MOV TL0,#0CH
RETI
END

C语言程序:

#include<reg51.h> timer0()interrupt 1{ TH0=0xfe;
    TL0=0x0c;
    P10=~P10;   //我在reg52.h中已经定义了P10,所以这里可以直接用
}
main(){
    TMOD=0x01;
    TH0=0xfe;
    TL0=0x0c;
    P10=0;
    EA=1;
    ET0=1;
    TR0=1;
    while(1){
    }
}

实验5.2 采用定时器控制从P1.0和P1.1分别输出周期为2ms和50us的方波。

汇编代码:这里采用的是软件计数,也就是先定时25us取反一次,同时用R0计数,当25us取反40次之后也就是1ms,P1.1取反一次,同时R0赋值为40。当然也可以用T1计数,我后面会有这个的代码

ORG 0000H 
LJMP START 
ORG 000BH
JMP TIMER0
ORG 0040H 
START: 
MOV TMOD,#02H
MOV TH0,#0E7H
MOV TL0,#0E7H
MOV R0,#40
SETB P1.0
SETB P1.1
SETB EA
SETB ET0
SETB TR0
SJMP $

TIMER0:
CPL P1.0
DJNZ R0,BACK
CPL P1.1
MOV R0,#40
BACK:
RETI
END

采用两个定时/计数器,一个计时器计时25us,一个计数器计数20次,因为计数器是每个下降沿计数一次,然后一个周期才有一个下降沿,所以只用计数20次。

ORG 0000H 
LJMP START 
ORG 000BH
JMP TIMER0
ORG 001BH
JMP TIMER1
ORG 0040H 
START: 
MOV TMOD,#62H ;T1T0都用上
MOV TH0,#0E7H
MOV TL0,#0E7H
MOV TH1,#0ECH
MOV TL1,#0ECH
SETB P1.0
SETB P1.1
SETB EA
SETB ET0
SETB ET1
SETB TR0
SETB TR1
SJMP $

TIMER0:
CPL P1.0
RETI

TIMER1:
CPL P1.1
RETI
END

C语言程序: 软件计数

#include<reg51.h>
uchar a=40; //我在reg51.h中定义了#define uchar unsigned char
timer0()interrupt 1{
    a--;
    P10=~P10;
    if(a==0){
        a=40;
        P11=~P11;
    }
}
main(){
    TMOD=0x02;
    TH0=0xe7;
    TL0=0xe7;
    P10=0;
    EA=1;
    ET0=1;
    TR0=1;
    while(1){
    }
}

计数器计数

#include<reg51.h>

timer0()interrupt 1{ P10=~P10; }
timer1()interrupt 3{ P11=~P11; }

main(){ TMOD=0x62; TH0=0xe7; TL0=0xe7; TH1=0xec; TL1=0xec; P10=0; P11=1; EA=1; ET0=1; ET1=1; TR0=1; TR1=1; while(1){ }
}