问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

STC32单片机IE、TCON和TMOD寄存器详解及应用

创作时间:
作者:
@小白创作中心

STC32单片机IE、TCON和TMOD寄存器详解及应用

引用
51CTO
1.
https://blog.51cto.com/u_16099228/13513658

本文详细介绍了STC32单片机中的中断允许寄存器IE、定时器/计数器控制寄存器TCON以及定时器/计数器工作方式寄存器TMOD的使用方法。通过对外部中断和定时器的讲解,帮助读者理解单片机中这些重要寄存器的功能和应用。

中断允许寄存器IE

中断允许寄存器IE用于控制各种中断的使能状态。其位定义如下:

位序号
7
6
5
4
3
2
1
0
位符号
EA
-
-
ES
ET1
EX1
ET0
EX0
含义
总允许位
-
-
串行口中断允许位
定时器T1溢出中断允许位
外部中断1允许位
定时器T0溢出中断允许位
外部中断 INT0允许位
  • EA:总允许位。当 EA = 1,CPU开放中断。当 EA = 0,CPU 不开放中断。
  • ES:串行口中断允许位。当 ES = 1,允许串口中断。当 ES = 0,不允许串口中断。
  • ET0/ET1:定时器T0/T1溢出中断允许位。当 ET0/ET1 = 1,允许T0/T1中断。当 ET0/ET1 = 0,不允许T0/T1中断。
  • EX0/EX1:外部中断 INT0/INT1 允许位。当 EX0/EX1 = 1,允许外部中断INT 0/1 中断。当 EX0/EX1 = 0,不允许外部中断 0/1 中断。

定时器/计数器控制寄存器TCON

TCON寄存器用于控制定时器/计数器的运行状态和外部中断的触发方式。其位定义如下:

寄存器
TCON
位序号
7
位符号
TF1
含义
T1溢出标志位
  • TF0/TF1:定时器T0/T1溢出标志位。当定时器计数溢出时,由硬件置1,请求中断。
  • TR0/TR1:定时器T0/T1的运行控制位。当 TR0/TR1 = 1,定时器开始计数;当 TR0/TR1 = 0,定时器停止计数。
  • IE0/IE1:外部中断0/1请求中断标志位。当外部中断触发时,由硬件置1,请求中断。
  • IT0/IT1:外部中断0/1触发方式控制位。当 IT0/IT1 = 1,为跳变沿触发方式;当 IT0/IT1 = 0,为电平触发方式。

定时器/计数器工作方式寄存器TMOD

TMOD寄存器用于设置定时器/计数器的工作模式。其位定义如下:

寄存器
TMOD
位序号
7
位符号
GATE
含义
门控制
  • GATE:门控制位。当 GATE = 0,TR1/TR0 = 1 时就允许T1/T0 开始计数;当 GATE = 1,TR1/TR0 = 1 且外部中断1输入位高电平时,才允许T1计数。
  • C/T:计数/定时模式选择位。当 C/T = 0,为定时器模式;当 C/T = 1,为计数器模式。
  • M1/M0:工作方式选择位。可以设置为4种不同的工作模式:
  • 00:方式0,13位计时计数器
  • 01:方式1,16位计时计数器
  • 10:方式2,8位计时计数器,可自动重新载入计数值
  • 11:方式3,仅适用于T0,分成两个8位计数器,T1停止计数

定时器的使用方法

  1. 选择工作方式:通过TMOD寄存器设置定时器的工作方式(GATE、C/T、M1、M0)。
  2. 设置初值:根据需要的定时时间计算并设置THx和TLx的初值。
  3. 开启定时器中断:设置ET0/ET1位为1,开启定时器中断。
  4. 开启总中断:设置EA位为1,开启总中断。
  5. 启动定时器:设置TR0/TR1位为1,启动定时器。

代码示例

以下是一个使用定时器0和定时器1的示例代码:

#include "reg52.h"  //注意:如果是keil5需把头文件换成  #include <REGX52.H>
typedef unsigned int u16;
typedef unsigned char u8;

//定义P1led为P1口 注意:如果是P0口需上拉电阻
#define P1led P1

//延时函数
void Delay(u16 i){
    while(i--);
}

//数码管
u8 code Leds[] = {
    0x3F, // 0
    0x06, // 1
    0x5B, // 2
    0x4F, // 3
    0x66, // 4
    0x6D, // 5
    0x7D, // 6
    0x07, // 7
    0x7F, // 8
    0x6F  // 9
};

//定义,通过for遍历 共阳接法点亮需输出低电平
u8 led_status_g[] = {
    0xFE, //0 1111 1110
    0xFD, //1 1111 1101
    0xFB, //2 1111 1011
    0xF7, //3 1111 0111
    0xEF, //4 1110 1111
    0xDF, //5 1101 1111
    0xBF, //6 1011 1111
    0x7F  //7 0111 1111
};

void int0Init(){
    EA = 1; //总中断打开
    EX0 = 1; //外部中断0打开
    IT0 = 1; //INT0为跳变沿触发方式
}

void int1Init(){
    EA = 1;
    EX1 = 1;
    IT1 = 1;
}

void main(){
    int0Init();
    int1Init();
    IP = 0x01;   //IP=0x01是外部中断0设置为高优先级中断
    P2 = 0x3f;   //数码管一开始显示0
    while(1){
        u16 i;
        for(i = 0; i < 10; i++) {
            P1led = led_status_g[i];
            Delay(50000);  //延时
        }
    }
}

//外部中断 0 由 button01 控制
void int0(void) interrupt 0 {
    u16 i;
    for(i = 0;i < 10; i++){
        P2 = Leds[i];
        Delay(50000);
    }
    P2 = 0x3f;
}

//外部中断 1 由 button02 控制
void int1(void) interrupt 2{
    int j;
    for(j = 1; j < 5; j++) {
        //P1口
        P1led = 0x00;  //此时P1口灯全亮
        Delay(50000);
        P1led = 0xFF;  //此时P1口灯全暗
        Delay(50000);
    }
}

//定时器0初始化
void Timer0Init(void){
    //使用方式0  1ms12MHz
    TMOD |= 0x01;
    TH0 = (65536-1000)/256; //0xfc
    TL0 = (65536-1000)%6; //0x18
    ET0 = 1;  //定时器0中断打开
    EA = 1;  //总中断打开
    TR0 = 1;  //定时器0开关打开
}

//定时器1初始化
void Timer1Init(void) {
    //使用方式1,16位
    TMOD |=0x10;
    //定时器
    TH1 = (65536-50000)/256; //50ms
    TL1 = (65536-50000)%6;
    ET1 = 1;   //定时器1中断打开
    EA =  1;  //总中断打开
    TR1 = 1;   //定时器1打开
}

//定时器0中断
void Timer0(void) interrupt  1{
    static u16 i;
    //1ms  12MHz
    TH0 = (65536-1000)/256; //0xfc
    TL0 = (65536-1000)%6; //0x18
    i++;
    if(i == 1000)  //1000ms
    {
        num0 ++;
        i = 0;
    }
}

//定时器1中断
void Timer1(void) interrupt  3{
    static u16 i;
    TH1 = (65536-50000)/256;  //50ms
    TL1 = (65536-50000)%6;
    i++;
    if(i == 20)  // 1s
    {
        num0++;
        i = 0;
    }
}

仿真图

由于设置了 IP = 0x01,所以外部中断0的优先级别较高。按下button01时,外部中断0开始执行。

定时器的定时计算

以方式1为例,定时器为16位,最大值为65536。假设需要定时1ms(1000us),对于12MHz的单片机,机器周期为1us。因此,定时器的初值计算如下:

TH1 = (65536-1000)/256; // 0xfc
TL1 = (65536-1000)%6; // 0x18

当定时器从初值开始计数,达到65536时溢出,产生中断。这个过程正好是1ms。

如果需要更长时间的定时,可以使用计数器变量累加。例如,需要1s的定时,可以定义一个计数器变量,每1ms计数一次,当计数到1000时,表示1s已到。

总结

本文详细介绍了STC32单片机中IE、TCON和TMOD寄存器的使用方法,并通过具体的代码示例展示了外部中断和定时器的应用。这些知识对于单片机的学习和开发具有重要的参考价值。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号