锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

STC15学习笔记 第二章 定时器和中断

时间:2022-09-24 09:30:00 56f继电器工作原理继电器连接器te

一、外部中断

实验开发板型号:STC15W4K56S4

1.1简介

内核与外设之间的主要交互方式有两种:轮询和中断。轮询的方式貌似公平,但实际工作效率很低,且不能及时响应紧急事件;中断系统使得内核具备了应对突发事件的能力。
在执行CPU在当前程序中,由于系统中急需处理,CPU暂停正在执行的程序,转而执行另一个特殊程序来处理紧急情况。CPU自动返回原暂停程序继续执行。由于外部原因,该程序在执行过程中中中断,称为中断。
中断服务函数:中断内核响应后执行的相应处理程序。
中断向量:中断服务程序的入口地址。每个中断源对应一个固定的入口地址。当内核响应中断请求时,将暂停当前程序执行,然后跳转到入口地址执行代码。
五个中断请求源:
外部中断0:INT0 中断号:0
定时/计数器0:TF0 中断号:1
外部中断1: INT1 中断号:2
定时/计数器1: TF1 中断号:3
串口中断: RI/TI 中断号:4

1.2硬件设计

中断系统结构:
在这里插入图片描述
EA :允许位整体中断;EA=1允许中断。
ES :串行中断允许位(只能用于串行口通信);ES=1允许中断。
ET1 :T1中断允许位;ET1=1允许中断。
EX1 :INT1中断允许位;EX1=1允许中断。
ET0 :T0中断允许位;ET0=1允许中断。
EX0 :INT0中断允许位;EX0=1允许中断。
一般来说,有两个中断处理函数,一个是中断初始化函数,另一个是中断服务函数。初始化函数是一种普通函数,但中断服务函数有特殊的格式要求:
<1>中断函数没有回值,无参数。
<2>函数名后面有一个关键字interrupt,说明这是中断服务函数。
<3>在关键字interrupt后面跟上中断号,说明这个中断服务函数是为那个中断服务的。
中断服务函数的格式为:
void 函数名() interrupt 中断号
{…… ……}

1.2.硬件设计过程

1.3代码设计

例如:
定义一个Working() 函数,使L指示灯不断闪烁。P32引脚定义为外部中断功能,按钮S在中断响应函数中,按钮会产生外部中断触发信号,LED8闪光熄灭。
从原理图可以看出,S1按键由P40控制,使用杜邦线P40和外部中断0,即P32相连。
中断初始化函数按上图写出,中断打开;

代码:

/***** STC15单片机开发系统演示程序 定义一个working() 函数,使L指示灯闪烁。将P32引脚定义为外部中断功能, 按键S在中断响应函数中,按钮会产生外部中断触发信号,LED8闪光熄灭。 硬件:按键S1对应的P4.0用线连接P3.2 MCU:STC15W4K56S4 ,晶体频率:22.1184MHz ****/   #include   #include      void Delay(unsigned char t)       //@22.1184MHz延时1ms  { 
              while(t)    { 
              unsigned char i, j;   _nop_();   _nop_();   i = 22;   j = 128;   do   { 
            while (--j);   } while (--i);    t--;  }  }   void HC138_Y(unsigned char n) ///138译码器控制端口  { 
               switch(n)       { 
                    1: //数码管---位码--控制输出Y1  P0 = ((P0&0xF8)|0x04); break; case 2: //数码管---断码--控制输出Y2  P0 = ((P0&0xF8)|0x02); break; case 3: //LED灯--控制输出Y3--控制输出Y3  P0 = ((P0&0xF8)|0x06); break; case 4: //ULN2003--电机--继电器--控制输出Y4  P0 = ((P0&0xF8)|0x01); break; } } void working(void) { 
          HC138_Y(3); P2 = 0x01; P0 &= 0xF8; Delay(100); HC138_Y(3); P2 = 0x00; P0 &= 0xF8; Delay(100); } void Init_INT0(void) //打开外部中断0  { 
          IT0 = 1; //设置为电平触发 EX0 = 1; //打开中断允许控制位 EA = 1; //打开总中断 } void INT0() interrupt 0 //P3.2端口对应的是外部中断0 { 
          HC138_Y(3); P2 = 0x80; P0 &= 0xF8; Delay(100); HC138_Y(3); P2 = 0x00; P0 &= 0xF8; Delay100(); } void main() { 
          P0M1=0;P0M0=0; P1M1=0;P1M0=0; P2M1=0;P2M0=0; P3M1=0;P3M0=0; Init_INT0(); //中断初始化  while(1) { 
          working(); } } 

二、定时器

实验用开发板型号:STC15W4K56S4

2.1基础简介

定时器/计数器T0由特殊功能寄存器TH0,TL0构成;定时器/计数器T1由特殊功能寄存器TH1,TL1构成。

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


8位分为两组,高4位控制T1,低4位控制 T0,不能位寻址。
TMOD 各位的功能如下:
(1)GATE:门控位
GATE=0,定时器/计数器是否计数,仅由控制位 TRx(x=0,1)来控制。
GATE-1,定时器/计数器是否计数,要由外中断号脚(IT0 或 IT1)上的电平与运行控制
位 TRx 两个条件共同控制。
(2)M1、MO:工作方式选择位
MI、MO 的4种编码,对应于 4种工作方式的选择,如下表所示。

(3)C/T:计数器模式和定时器模式选择位
C/T = 0,为定时器工作模式,对系统时钟 12 分频后的内部脉冲进行计数。
C/T = 1,为计数器工作模式,计数器对外部输入引脚 T0(p3.4)或T1(P3.5)的外部脉冲(负跳变)计数

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


TCON的字节地址为88H,可以位寻址,位地址为88H-8FH
TCON的低4位功能与外部中断有关,TCON 寄存器中与中断系统有关的各标志位的功能如下:
(1)TF1:片内定时器/计数器 T1 的溢出中断请求标志位。
当启动 T1计数后,定时器/计数器T1 从初值开始加 1计数,当计数溢出时,由硬件自动置
TE1 为1,向CPU 申请中断。CPU 响应TF1 中断时,TF1标志由硬件自动清零,TF1 也可由软件清零。
(2)TF0:片内定时器/计数器T0 的溢出中断请求标志位,功能与TF1 相同。
(3)IE1:外部中断请求1的中断请求标志位。
(4)IE0:外部中断请求0的中断请求标志位。
(5)IT1:选择外部中断请求1为跳沿触发方式还是电平触发方式。
IT1 = 0,为电平触发方式,加到引脚 INT1上的外部中断请求输入信号为低电平有效,并把IE1置“1”。转向中断服务程序时,则由硬件自动把 IE1 清零。
IT1 = 1,为跳沿触发方式,加到 脚 INT1上的外部中断请求输入信号电平从高到低的负跳沿
有效,并把 IE1 置“1”。转向中断服务程序时,则由硬件自动把 IE1 清零。
(6)IT0:选择外部中断请求。为跳沿触发方式还是电平触发方式,与IT1类似。
(7)TR1、TR0 :计数运行控制位
TR1 位(或TR0 位)= 1,启动定时器/计数器计数的必要条件。
TR1位(或TR0 位)= 0,停止定时器/计数器计数。
该位可由软件置 1 或清零。

2.2硬件设计


时间设置:
定时时间计算:
<1>定时时间t,单位us

例如定时5ms, t = 50000,计算出X,X = 19456 = 0x4c00,将初值写入TH0和TL0寄存器即可,即:TH0 = 0x4c;TL0 = 0x00;
<2>定时时间t,单位us
TH0 = (65535-t)/256;
TL0 = (65535-t)%256;
//比如当
晶振频率为11.0592M的晶振。
则每秒可产生机器周期为11.0592/12=0.9216M的机器周期,也就是921600个机器周期。50ms等于0.05秒,所以需要921600*0.05=46080个机器周期;定时器在方式1工作,为16位,最大值为65536,所以需设初值为65536-46080=19456;转为16进制为(4c00),所以高位TH0=0x4c; TL0=0x00;

2.3代码设计

利用15单片机的定时/计数器T0的模式1实现间隔定时,每隔1秒L8指示灯闪烁一下, 也就是点亮0.5秒,熄灭0.5秒。

/***** STC15单片机开发系统演示程序 利用15单片机的定时/计数器T0的模式1实现间隔定时, 每隔1秒L8指示灯闪烁一下, 也就是点亮0.5秒,熄灭0.5秒。 MCU:STC15W4K56S4 ,晶体频率:22.1184MHz ****/  
#include  
#include  
int count = 0;  
void Delay(unsigned char t)       //@22.1184MHz延时1ms 
{ 
          
   while(t)
   { 
        
   		unsigned char i, j;
		_nop_();
		_nop_();
		i = 22;
		j = 128;
		do
		{ 
        
			while (--j);
		} while (--i); 
		t--;
	} 
}  
void HC138_Y(unsigned char n) //138译码器控制使能端口 
{ 
          
    switch(n)  
    { 
          
        case 1:  //数码管---位码--控制输出Y1 
            P0 = ((P0&0xF8)|0x04);  
        break;  
        case 2:  //数码管---断码--控制输出Y2 
            P0 = ((P0&0xF8)|0x02);  
        break;  
        case 3:  //LED灯--控制输出Y3--控制输出Y3 
            P0 = ((P0&0xF8)|0x06);  
        break;  
        case 4:   //ULN2003--电机--继电器--控制输出Y4 
            P0 = ((P0&0xF8)|0x01);  
        break;  
    }  
}    
  
void Init_Timer0(void) //打开外部中断0 
{ 
          
    TMOD = 0x01;//TMOD寄存器,选择工作模式 
    TH0 = (65535-50000)/256;//时间计算50ms 
    TL0 = (65535-50000)%256;  
     
    ET0 = 1;//打开定时器中断 
    EA = 1;//因为是选用定时器是T0,所以源允许处ET0要允许,才能往后执行 
    TR0 = 1;//启动定时器T0,此时开始定时计数 
}  
void INT0() interrupt 1  //打开定时器T0,中断号为1
{ 
          
    TH0 = (65535-50000)/256;//时间计算 
  	TL0 = (65535-50000)%256;  
    count++;  
    if(count == 10)  //每次计数50ms,经过10次计数,500ms
    { 
          
        HC138_Y(3);  
      	 P2 = 0x80;  
        P0 &= 0xF8;  
        Delay(100);  
        HC138_Y(3);  
        P2 = 0x00;  
        P0 &= 0xF8;  
        Delay(100);  
        count = 0;  //标志位清0
    }  
      
}  
void main()  
{ 
          
    P0M1=0;P0M0=0;  
    P1M1=0;P1M0=0;  
    P2M1=0;P2M0=0;  
    P3M1=0;P3M0=0;     
    Init_Timer0(); //打开中断 
    while(1)  
    { 
             
    }  
} 
锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章