历史上的今天
返回首页

历史上的今天

今天是:2024年11月02日(星期六)

2021年11月02日 | STC89C52之中断终结篇 ---- 自学笔记

2021-11-02 来源:eefocus

一、概述

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,

推荐阅读

史海拾趣

光大芯业公司的发展小趣事

随着技术的不断进步,光大芯业的产品逐渐得到了市场的认可。公司的产品线涵盖了磁传感、DC/DC、AC/DC转换器、电机驱动等多个领域,广泛应用于消费电子、运动控制、电动工具、智能家居、汽车电子等多个行业。通过不断拓展市场,光大芯业的产品已经走进了千家万户,为人们的生活带来了便利和舒适。

BOOKHAM公司的发展小趣事

随着市场的不断扩大,BOOKHAM公司意识到单打独斗难以取得更大的突破。于是,公司开始积极寻求与其他企业的战略合作。通过与一家知名电子设备制造商的合作,BOOKHAM公司成功将其光学元件产品集成到对方的产品中,共同开拓市场。这种合作不仅提升了BOOKHAM公司的市场份额,还为其带来了更多的商业机会和合作伙伴。

Dau Semiconductor Inc公司的发展小趣事

在成立初期,Dau Semiconductor Inc公司面临着诸多技术挑战。其中,如何实现芯片的低功耗设计是困扰公司发展的一个难题。为了解决这个问题,公司投入大量研发资源,不断探索新的技术和材料。经过数年的努力,公司终于成功突破了技术瓶颈,研发出了一款具有超低功耗的半导体芯片。这款芯片的推出,不仅为公司赢得了市场认可,也为公司在行业中树立了技术领先的形象。

Exar公司的发展小趣事

面对日益激烈的市场竞争和不断变化的市场需求,Exar公司始终坚持以创新为核心竞争力。公司不断投入研发资金,加强技术创新和产品研发力度,推出了一系列具有自主知识产权的新产品。同时,Exar还积极关注行业发展趋势和市场动态,不断调整和优化产品线,以适应市场的变化和发展。在未来,Exar将继续坚持创新驱动的发展战略,努力成为电子行业的领军企业。

请注意,以上故事框架仅供参考,具体的故事内容需要根据实际情况进行补充和完善。

Hartmann Codier GmbH公司的发展小趣事

随着科技的不断发展,CNC Tech公司意识到,只有不断创新才能在行业中保持领先地位。因此,公司加大了对研发创新的投入,积极引进和培养高端人才,加强与高校和科研机构的合作。在CNC Tech的努力下,公司成功研发出一系列具有创新性的数控加工技术和产品,不仅提高了生产效率和质量,还降低了生产成本,为客户创造了更大的价值。这些创新成果也引领了行业的技术变革和发展趋势。

迈翔科技(COILMX)公司的发展小趣事

迈翔科技(COILMX)的创始人看到了电子行业,特别是电感器市场的巨大潜力。1996年,公司正式成立,初期主要专注于SMD电感的设计、制造和销售。公司从香港起步,逐步在深圳设立工厂,引进先进的生产设备和技术,为未来的发展奠定了坚实的基础。

问答坊 | AI 解惑

车载移动电视接收的系统方案

在柏林推出的DVB T(地面数字广播)数字电视也已经影响到汽车娱乐系统中的电视接收。现在,汽车电视接收机不仅能够接收模拟电视信号(它仍将在城市以外的地区继续存在数年),而且也能够接收和处理DVB T信号。Hirschmann Electronic ...…

查看全部问答>

S3C2410完全开发流程

这是一篇关于s3c2410的开发文档的资料,以及linux的一些实验…

查看全部问答>

无线收发模块汇总

本帖最后由 paulhyde 于 2014-9-15 09:12 编辑 :P :P :P :P :P :P :P :P :P :P :P 好东西与各位分享!  …

查看全部问答>

电子书---高频电路设计与制作

发一本高频电路设计与制作,日本人写的。感觉还不错。不过有点大,40M,分享啦…

查看全部问答>

单片机双电源切换

请问老师:+5V单片机双电源自动及手动切换用哪种芯片?谢谢!…

查看全部问答>

医用自动洗片机控制器的研制

  1 引 言   洗片机是各医院影像科的必需设备。医院影像科每天要冲洗大量的x-射线透射胶片,工作量大,且洗片操作有一定难度,对操作人员专业技术要求高,另外,洗片时化学药液对人体有伤害。因此,目前医院大多采用医用自动洗片机。进口的 ...…

查看全部问答>

WINCE 5.0 输入法如何实现,

我使用 ARM 2440开发板, 使用WINCE 5.0 (中文)OS, 现在想实验软键盘 汉字输入 和手写 输入。 请前辈们 描述一下实现 思路。 …

查看全部问答>

串口接收不定长字符串

void InitSio(void) {         u16 RELOAD_COUNT = 0;                 //使用独立波特率发生器作为波特率发生器     S2CON    =   0x50;  ...…

查看全部问答>

PB的编译问题

新装的WIN XP SP2, 番茄花园, 然后装PB5.0, 先装.net framework 1.1, 然后装PB5.0(CPU选择了ARMV4I, X86, Emulator). PB5.0 装好之后,就新建工程编译了,这时EVC, VS2005等都还没有装. 用自带的2410BSP新建工程编译的时候出现错误: \"Invalid  ...…

查看全部问答>

电脑拆卸后无法开机

我的电脑拆卸了一次再重新装上后就无法启动了,按电源后只显示品牌标志.…

查看全部问答>