STC89C52之中断终结篇 ---- 自学笔记

发布者:beta12最新更新时间:2022-01-12 来源: eefocus关键字:STC89C52  中断  寄存器 手机看文章 扫描二维码
随时随地手机看文章

一、概述

1.1、五个中断

外部中断0                                INT0

定时器/计数器(C/T)中断0         T0

外部中断1                                 INT1

定时器中断1                              T1

串行通信中断                             RX  and  TX


1.2、中断允许寄存器(IE)

 

1.3中断请求标志(TCON)

 

ITO(TCON.0):外部中断0触发控制位。


  当IT0=0时,为电平触发方式      低电平

  当IT0=1时,为边沿触发方式(下降沿有效)

IE0(TCON.1):外部中断0中断请求标志位。


IT1(TCON.2):外部中断1触发方式控制位。


IE1(TCON.3):外部中断1中断请求标志位。


TF0(TCON.5):定时/计数器T0溢出中断请求标志位。    置1溢出


TF1(TCON.7):定时/计数器T1溢出中断请求标志位。

1.4、控制寄存器(TCON)

1.5、工作方式寄存器(TMOD)

方式0时,N=13(此为TH为8位,TL为5位)

方式1时,N=16(此为TH为8位,TL为8位)

方式2时,N=8(此为TH为8位,TL为0位)

方式3时,N=8(此为TH为8位,TL为8位,只适用于T0,且T0被分成两个独立的8位计数器TH与TL)

 

12M的晶振   定时1ms

第一种  THx,TLx表达方式

定时=(2的13次方-计数初值)*12/晶振频率 

       = (8192-计数初值)*12/12

       = 8192-计数初值    ( 单位:微秒)

 计数初值 = T0 = 8192-定时 + 1 = 7193  = 0x1c19     TH0 = 0x1c   TL0 = 0x19

不知道第一种方式对不对,我设置成TH0=0x1c;TL0=0x19,这样LED能闪烁

 

第二种  THx,TLx表达方式        此种方式网上摘抄

因为寄存器是13位的,高位8bit,低位5bit, 2^5=32

定时=5ms = 5000微秒

所以有: TH0 = (8192-定时)/32; TL0 = (8192-定时)%32

 

 

TH0和TL0的赋值是定时器T0装填初值,TH0是高位,TL0是低位,连起来看就是定时器T0装填了初值。

除以32或者除以256是用来求高位的初值,同理取余就是求低位初值,

至于为什么有32和256是因为定时器工作方式不同,工作方式在之前的TMOD赋值的时候设定,256对应工作方式2,而32对应方式0

0000 0000                       TMOD |= 0x00               方式1           常用


0000 0001                        TMOD |=0x01               方式2            常用


0000 0010                        TMOD |=0x02              方式3            不常用


0000 0011                        TMOD |=0x03            方式4             不常用


 


二、代码

2.1、方式0

方式 0 为 13 位计数,由 TL0 的低 5 位(高 3 位未用)和 TH0 的 8 位组成。 TL0 的低 5 位溢出时向 TH0 进位,TH0 溢出时,置位 TCON 中的 TF0 标志,向 CPU 发出中断请求。


#include

#define uchar unsigned char      //  #define宏定义关键字

#define uint  unsigned int

/*

typedef unsigned int u16;      //  关键字 typedef 可以为类型起一个新的别名 

typedef unsigned char u8;

                               

 */

//  sbit led=P2^0;     第一个led灯闪烁

//  sbit led = P2^1; 第二个led灯与DA1切换灯闪烁

//  sbit led = P2^2; 第三个led灯闪烁,数码管第一位与数码管第二位来回跳动

//  sbit led = P2^3;    第四个led灯闪烁,数码管第一位与数码管第三位来回跳动

//  sbit led = P2^4;    第五个led灯闪烁,数码管第一位与数码管第五位来回跳动 

//  sbit led = P2^5;    第六个led灯闪烁并且有滴答滴答的声音

//  sbit led = P2^6;    第七个led灯闪烁

    sbit led = P2^7;    // 第八个LED灯闪烁

uchar num;

// u8 num =0;

 

void TIM0init()

{

/*

1、选择工作方式

TMOD |= 0x00;   工作方式0

计数器是13位的,计数范围1~8192(2^13=8192)

定时=(2的13次方-计数初值)*12/晶振频率   = 2^16 -1000 +1 = 7193 = 0x1c19

T0  or T1  = 0x1c19                    

TH1 or TH0 = 0x1c                       

TL1 or TL0 = 0x19

工作方式0:寄存器为13为   THx为8位  TLx为5位(高三位未用)

除以32用来求高八位(THx)的初值,取余就是求低位初值

例子:方式0是13位定时器,其最大计数值是8192,51单片机定时器/计数器是加法计数,因此如果要计数1000个脉冲,定时器的初值应该是8192-1000 ,

如果要计数100个脉冲,定时器的初值应该是8192-100

该16位定时器又分成了高8 位和低8位,其中低8位只用了5位,最大装回值是31,超过32则装入高8 位,高8位的1代表32。

因此高8位装的是32的整数倍,低8位装32的余数,

上例的求模和求余就 是这个意思,很明显答上例设定的计数值是100个脉冲,

如果晶振是12M,一个脉冲是1us,那么定时时间就是100us。

TMOD |= 0x01; 工作方式1

TMOD |= 0x10;   工作方式2

TMOD |= 0x11;   工作方式3

*/

 

 

     TMOD|=0x00;   

/*

2、选择定时器/计数器(C/T)

T1(16位C/T+1) = TH1(八位) + TL1(八位)

T0(C/T)  = TH0(高八位寄存器)   + TL0(低八位寄存器)

TH1 =

TH1 =

*/         

     TH0= (8192-1000)/32;             //0x1c;//(8192-5000)/32;   //装入初值,怎么计算,下面分析

     TL0=  (8192-1000)%32;            //0x19;//(8192-5000)%32;    

     EA=1;    //开总中断

     ET0=1;   //开定时器中断

     TR0=1;   //启动定时器0

}

/*

interrupt 0  指明是外部中断0;

interrupt 1  定时器中断0; 

interrupt 2  外部中断1;

interrupt 3  定时器中断1;

interrupt 4  串行口中断;

*/

void T0_time()  interrupt 1      

{

     TH0= 0x1c;        //(8192-5000)/32; //重装初值,如果不重装,中断只触发一次

     TL0= 0x19;       //(8192-5000)%32;

     num++;

}

  

void main()

{

    TIM0init(); 

    while(1)

    {

  if(num==200)     //如果到了200,说明一秒时间到

          {

             num=0;

     led=~led;   //闪灯

  }

    }

}

计数初值与计数个数的关 系为:X=2(13)-N


方式0的例子

2.2、方式1

方式 1 的计数位数是 16 位,由 TL0 作为低 8 位,TH0 作为高 8 位,组成了 16 位加 1 计数器。


 

#include "reg52.h" //此文件中定义了单片机的一些特殊功能寄存器

 

typedef unsigned int u16;   //对数据类型进行声明定义

typedef unsigned char u8;

 

sbit led=P2^0; //定义P20口是led

 

 

void Timer0Init()

{

TMOD|=0X01;//选择为定时器0模式,工作方式1,仅用TR0打开启动。

 

TH0=0XFC; //给定时器赋初值,定时1ms

TL0=0X18;

ET0=1;//打开定时器0中断允许

EA=1;//打开总中断

TR0=1;//打开定时器

}

 

/*******************************************************************************

* 函 数 名       : main

* 函数功能 : 主函数

* 输    入       : 无

* 输    出    : 无

*******************************************************************************/

void main()

{

Timer0Init();  //定时器0初始化

while(1);

}

 

 

void Timer0() interrupt 1

{

static u16 i;

TH0=0XFC; //给定时器赋初值,定时1ms

TL0=0X18;

i++;

if(i==1000)

{

i=0;

led=~led;

}

}

2.3、方式2

自动重装初值的 8 位计数方式。工作方式 2 特别适合于用作较精确的脉冲信号发生器


#include "reg52.h" //此文件中定义了单片机的一些特殊功能寄存器

 

typedef unsigned int u16;   //对数据类型进行声明定义

typedef unsigned char u8;

 

 

u8 code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,

0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//显示0~F的值

u8 n=0;

 

void Timer1Init()

{

 // TMOD   |=0X01;              速度快//选择为定时器1模式,工作方式1,仅用TR1打开启动。

   TMOD    |=0x02;

 // TMOD   |=0x00;

 //  TMOD  |= 0x03;

TH1=0XFC; //给定时器赋初值,定时1ms

TL1=0X18;

ET1=1;//打开定时器1中断允许

EA=1;//打开总中断

/***************************************************************

** * TCON的中断请求标志       

** *  

** *       位:    7      6      5      4      3      2     1      0  

** *   

** * 字节地址:   TF1     TR1    TF0   TR0    IE1    IT1   IE0    ITO 

** *     说明:   

** *ITO(TCON.0):外部中断0触发控制位。   

** *    当IT0=0时,为电平触发方式   低电平      

** *    当IT0=1时,为边沿触发方式(下降沿有效)   

** *IE0(TCON.1):外部中断0中断请求标志位。

** *IT1(TCON.2):外部中断1触发方式控制位。   

** *IE1(TCON.3):外部中断1中断请求标志位。   

** *TF0(TCON.5):定时/计数器T0溢出中断请求标志位。置1溢出   

** *TF1(TCON.7):定时/计数器T1溢出中断请求标志位。   

** ****************************************************************   

** *   

** *****************************************************************

** * 控制寄存器(TCON)   

   

** * TCON的低四位用于控制外部中断,   

** * TCON的高四位用于控制定时器计数器的启动和中断  

** *     

          位:  7    6    5     4     3   2    1   0    

字节地址: TF1  TR1  TF0   TR0    

   

    TF1(TCON.7):T1 溢出中断请求标志位。T1 计数溢出时由硬件自动置 TF1 为 1。 

CPU 响应中断后 TF1 由硬件自动清 0。T1 工作时,CPU 可随时查询 TF1 的 状态。

所以,TF1 可用作查询测试的标志。TF1 也可以用软件置 1 或清 0,同硬件置 1    

或清 0 的效果一样。   

   

    TR1(TCON.6):T1 运行控制位。TR1 置 1 时,T1 开始工作;TR1 置 0 时,    

T1 停止工作。TR1 由软件置 1 或清 0。所以,    

用软件可控制定时/计数器的启动 与停止。    

   

    TF0(TCON.5):T0 溢出中断请求标志位,其功能与TF1相同。    

    TR0(TCON.4):T0 运行控制位,其功能与TR1相同。    

   

  

   

** ********************************************************************************/

TR1=1;//打开定时器

}

 

 

void main()

{

Timer1Init();  //定时器1初始化

while(1);

}

 

 

void Timer1() interrupt 3

{

static u16 i;

TH1=0XFC; //给定时器赋初值,定时1ms

TL1=0X18;

i++;

if(i==10000)

{

i=0;

P0=smgduan[n++];

if(n==16)n=0;

}

}

#include

 

#define uchar unsigned char

#define uint  unsigned int

 

sbit led1=P2^0;

uint num;

 

void TIM0init(void)

{

     TMOD|=0x02;    //设置定时器0为工作方式2

/*

TOMD=0x02,是定时器工作方式3,分为两个8位定时器,每个定时器计数最大值为255,

[1] [2]
关键字:STC89C52  中断  寄存器 引用地址:STC89C52之中断终结篇 ---- 自学笔记

上一篇:51单片机之串口通信 ---- 自学笔记
下一篇:51单片机12分频 ----- 学习笔记

推荐阅读最新更新时间:2024-11-17 03:56

51单片机串行口--同步移位寄存器
MCS-51单片机的串行口具有两条独立的数据线 发送端TXD和接收端RXD,它允许数据同时往两个相反的方向传输。一般通信时发送数据由TXD端输出,接收数据由RXD端输入。 MCS-51单片机的串行口既可以用于网络通信,亦可实现串行异步通信,还可以用作同步移位寄存器。如果在串行口的输入输出引脚上加上电平转换器,就可方便地构成标准的RS-232接口。 MCS-51单片机的串行接口是一个全双工通信接口,它有两个物理上独立的接收、发送缓冲器SBUF,可以同时发送和接收数据。但是发送缓冲器只能写入,不能读出;接收缓冲器只能读出,不能写入。两个缓冲器共用一个地址(99H)。 数据通信的基本概念 常用于数据通信的传输方式有单工、半双工、全双
[单片机]
51单片机串行口--同步移位<font color='red'>寄存器</font>
STC89C52单片机RAM模式
STC89C52 单片机内变量、函数参数等数据在RAM中的储存模式: small、compact、large 前边介绍单片机资源的时候,我们提到过 STC89C52 共有 512 字节的 RAM,是用来保存数据的,比如我们定义的变量都是直接存在 RAM 里边的。但是单片机的这 512 字节的 RAM在地位上并不都是平等的,而是分块的,块与块之间在物理结构和用法上都是有区别的,因此我们在使用的时候,也要注意一些问题。 51 单片机的 RAM 分为两个部分,一块是片内 RAM,一块是片外 RAM。标准 51 的片内 RAM 地址从 0x00H~0x7F 共 128 个字节,而现在我们用的 51 系列的单片机都是带扩展
[单片机]
<font color='red'>STC89C52</font>单片机RAM模式
定时器计数、定时器中断函数、while(1)之间如何协调、工作?
51单片机程序,使用定时器时,定时器计数、定时器中断函数、while(1)循环三者之间如何协调好整个流程? 我拿一个最经典的单片机应用——‘流水灯’来分析吧。 【定时器0实现间隔1s的流水灯】简单示例 #include reg52.h typedef unsigned int u16; //对数据类型进行声明定义 typedef unsigned char u8; #define LED P3 bit LED_flag=0; //定时到1s的标志位 u8 n; //循环变量,用作LED总线的位索引index void InitTimer0(void); //定时器0,初始化 void mai
[单片机]
MSP430FR5969内存分配的问题
cmd文件里的具体内容我就不贴了,大家自己可以看一下。cmd文件主要由两部分构成,一个是MEMORY{};另一个是SECTIONS{} 其中MEMORY{}是定义内部所有寄存器及存储器的地址,在这里大部分内容都是厂家定义好的,一般不能修改。但是咱们今天要改的就是他,当然只能改其中允许该的地方,那就是FRAM的分配问题。根据数据手册里提供的内存分配情况(如下图)我们可以得知,59x9的内存从0x0000开始,一直到0x13FFF。对应着这个图和Cmd文件,我们可以了解内部的地址分配问题,如果做过总线扩展之类的同学肯定对这个不会陌生了,如果没有见过就需要理解一下。其实也很简单,就是对应的地址要对应上就可以了。有一些是固定好的不能变
[单片机]
为你破解ARM中断寄存器
S3C2440的中断寄存器: 1.中断分两大类:内部中断和外部中断。 2.外部中断。24个外部中断占用GPF0-GPF7(EINT0-EINT7),GPG0-GPG15(EINT8-EINT23)。用这些脚做中断输入,则必须配置引脚为中断,并且不要上拉。具体参考datesheet数据手册。 寄存器:EXTINT0-EXTINT2:三个寄存器设定EINT0-EINT23的触发方式。 EINTFLT0-EINTFLT3:控制滤波时钟和滤波宽度。 EINTPEND:这个是中断挂起寄存器,清除时要写1,后面还有几个是写1清除。当一个外部中断(EINT4-EINT23)发生后,那么相应的位会被置1。为什么没有EINT0-
[单片机]
STM32的中断机制 stm32中断方式有几种
STM32的中断机制stm32中断方式有几种 中断机制在单片机中是很重要的环节,中断代码默认地从上往下执行,遇到特定条件或特定语句,将按照指定的程序跳转。而STM32单片机的中断是有两层控制器分别控制的,若采用中断机制,必须同时配置内核和芯片。 在STM32单片机中执行中断机制主要有三个函数,分别是: 1.配置NVIC_Config()函数 2.配置EXTI_Config()函数 3.自行编写中断服务函数 NVIC是嵌套向量中断控制器,主要控制整个单片机芯片中断相关的功能,跟内核紧密耦合。配置NVIC_Config()函数是为单片机提供选择中断源的优先级及打开中断通道,主要由配置NVIC初始化结构体NVIC_InitStr
[单片机]
msp4306989单片机的寄存器 第五章
1.5 单片机C语言入门 1.5.1 单片机的寄存器 在前面的示例程序中我们发现对单片机进行编程实际上就是改写寄存器的值。单片机各个外设的功能其实是预先固定的,而寄存器就像是这些功能的控制接口,通过改变寄存器的值就可以在这些功能中进行选择。还有一些寄存器直接对应引脚的状态,例如GPIO的输入/输出寄存器。像以下语句: P1OUT = 0x01; 这句话其实就是赋值给P1OUT这个寄存器,这个寄存器是GPIO的输出寄存器,赋值之后对应引脚的输出状态就会发生改变。 P1OUT寄存器共有8位,分别是从P1.0-P1.7。要给这个寄存器赋值,其实就是写入一个8位的二进制数值,例如0000 0001。在C语言中,为了尽量
[单片机]
msp4306989单片机的<font color='red'>寄存器</font> 第五章
混合信号设计 模拟工具必须迎头赶上
  就在不久前,市场上的绝大多数IC从本质上说,不是纯数字电路就是纯模拟电路。而如今,为了满足成本、尺寸、重量和功耗等方面的要求,复杂的模拟和数字功能组合出现在了“混合信号”器件上。   虽然传统的模拟设计和验证工具经过多年发展已经在容量和性能上取得了很大进步,但是它们的基本架构在很大程度上却仍然是基于上世纪90年代中期的技术。数字工具目前已经发展到能够提供高度自动化的水平,从而极大提高了设计者的产能。与其不同,模拟工具所支持的自动化水平极低,而模拟设计工作也仍然在很大程度上依赖手工作业,整个过程耗时且容易出错。   大约在上世纪60年代初,也就是数字集成电路设计的早期,工程师用钢笔在纸和蜡纸(偶然还会用到餐厅的桌布)上绘制原
[模拟电子]

推荐帖子

关于WINCE下SOCK_RAW的使用,在线等待
我正在WINCE下写一PING程序,原以用ICMPCreateFile(),ICMPSendEcho()实现。但根据项目最新要求,需要程序可对发送PING命令的网卡进行绑定,现打算建立SOCK_RAW套接字,但是上网查找资料,发现在WINCE下必须用WSCInstallProvider()进行声明。请问各位老大,有人用过WSCInstallProvider()吗?可否指点一二。关于WINCE下SOCK_RAW的使用,在线等待up
carlry WindowsCE
学习MSP430G2553遇到的定时器和串行I2C的问题求助
最近在学MSP430G2553这个单片机,一切觉得都还不错,但就是有两个问题不大理解1:定时器那不会(不是看门狗定时器),就特别简单的定时程序要怎么写呢?还有那个PMW波又是什么意思?2:串行通信的I2C软件程序要怎么编写,里面有发送/接收字节函数还有发送/接受帧函数这个两个有什么区别呢如果是简单的pcf8591的AD转换这两个函数要不要都写进去呢?求高手解答谢谢学习MSP430G2553遇到的定时器和串行I2C的问题求助另外定时器要定时多久是可以随意的吗还是跟看门狗定时
扯szp 微控制器 MCU
增程式电动汽车动力总成关键技术
以探索增程式电动汽车动力总成的关键技术为目标,分析了增程器系统专用发动机的振动震源和噪声传递路径,通过悬置系统固有频率匹配及解耦率优化、增程器发动机测试工况点选择及多目标优化控制策略、减速器啸叫噪声双目标函数优化等技术手段减低了增程器系统引起的整车噪声,通过增程器系统高可靠性弹性连接技术、建立增程器动力总成可靠性台架试验方法而改善了增程器系统的可靠性,将这些关键技术应用于增程式电动车进行整车布置及性能测试,终实现动力总成关键技术(增程器系统低噪声和高可靠性关键技术、减速器的啸叫噪声的优化控制技
arui1999 下载中心专版
PC机与多个单片机如何通信?
我需要把100组数码管(每组6个)放在每个间隔40CM格子里,显示的数据就是该格子里东西的数量,我看了别人搞的,每组数码管用一个单片机控制,单片机与单片机之间的通信(连线)只用一条线相连(一进一出串连),用了MAX232芯片,请问这是一种什么总线方式?原理怎样?希望哪位高手指点.PC机与多个单片机如何通信?你可以看一下MODBUS总线的协议....这是一个另外你也可以自己设计一下协议...其实带个地址就来进行识别就行...其实是232串口通信而已因为它可能不需要返回数据,所以只用了
mega128 嵌入式系统
清华大学的经典ARM学习教材,全中文版
特附上首页的目录,一看便知道有无价值前言................................................................................................................................................1第一章嵌入式系统的硬件构成.................................................................
11dong330 ARM技术
STM32F仿真时提示堆栈溢出,怎么办?
老大,整是搞不懂,为什么要用IAR???MDK不是挺好的吗?不管怎么说,我用MDK,十分爽,一切都很顺利,MDK配带的example我基本都看了,自己建工程,编译,在ram中debug通过。关于MDK,想和我交流的话,用qq:656749469MSN:********@msn.com这个不能提供,呵呵STM32F仿真时提示堆栈溢出,怎么办?上面集成st-link2只能用在iar环境下啊。我也不想啊,可是我买了一块万利的开发板我运行个几圈就跑飞了,可
catcat0123 stm32/stm8
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved