首页 > 编程知识 正文

单片机(中断系统c语言程序,51单片机中断系统程序实例 (STC89C52RC))

时间:2023-05-04 09:59:13 阅读:122037 作者:3145

51单片机中断系统程序示例(STC89C52RC ) )。

51单片机有中断,就可以编程。 做某件事的时候,停下来先应答中断,做别的事,做别的事再继续做原来的事。 中断的优先顺序是可以对要做的事情进行排序。

单片机学习并不难。 如果你掌握了学习方法,学习就不难了。 什么是好的学习方法呢? 请务必掌握两个要点:

了解寄存器的英语拼写,如IE=interrupt中断

我不知道所有的拼写,你去猜,我去查。 这样就能理解为什么是这个名称了,理解了就不用记忆了。

2 .每个知识点都需要有形像的来源

例如看到TF0,在脑海中必须马上形象地定位为有TCON寄存器的人

看到ET0后,立即映像到IE寄存器的第2位进行定位

51hei独家揭秘:形象是记忆最大的技巧。 当人眼看到某张图时,把视觉信号转换成电信号,转换成人类能理解的形式。 当我们想起图像的时候,我们正在重新搜索和放大原始的视觉信号。 在学习过程中,不断练习搜索、信号放大,我们的学习能力会越来越强。

写程序代码时,也请尽量将每行的代码形象化。

51单片机中的中断源

8051有五个中断源,有两个优先级。 在与中断系统有关的特殊功能寄存器中,有IE (中断许可寄存器)、IP (中断优先级控制寄存器)、中断源控制寄存器(例如TCON、SCON的关系位)。 51单片机的中断系统结构如下图所示(注意,IF0必须为TF0 )。

8052有六个中断源,比8051多一个定时器/计数器T2中断源。

8051个中断源分别是:

(1) 51单片机外部中断源

8051有两个外部中断源: INT0和INT1,分别从P3.2和P3.3两个引脚接收中断请求信号。 两个中断源的中断触发允许通过TCON的后4位控制、TCON的前4位控制进行动作和溢出标志。

INT0也就是Interrupt 0。 你应该在这里看看你的51单片机开发板的电路图。 脱离形式的记忆是没有意义的。 你应该读上面的句子,想起原理图上的连接。 任何记忆都会转换成形像。 这是学习的根本原理。 我们可以通过学习单片机来学习这样的学习方法。 会给你带来一生的利益。

TCON的结构如下图所示。

(a )计时器T0运行控制位TR0

TR0由软件设置或清除0。 当栅极控制位GATE=0时,TO计数器仅由TR0控制,以TR0=1开始计数,并以TR0=0停止。 当栅极控制位GATE=1时,T0计数器由INT0和TR0共同控制,并且当INT0=1且TR0=1时,启动T0计数器。

(b )计时器T0溢出标志TF0

如果T0溢出,则TF0=1并且可以向CPU申请中断,在CPU响应中断之后硬件可以清除TF0,或者可以通过软件查询的方式清除TF0。

c )计时器T1运行控制位TR1

功能与TR0相同。

(d )计时器T1的溢出标志是TF1

功能与TF1相同。

(e )外部中断源1(int1、P3.3 )中断请求标志IE1

如果IE1=1,则外部中断源1向CPU请求中断,并且当CPU对该中断作出响应时硬件清除IE1 (下降触发方案)。

(f )外部中断源1触发方式选择位IT1

IT1=0时,外部中断源1选择电平触发方式,输入低电平时置位IE1; 当IT1=1时,外部中断源1选择下降触发方式,当中断源从高电平变为低电平时,置位IE1,向CPU请求中断。

(g )外部中断源0(int0、P3.2 )中断请求标志IE0

功能与IE1相同。

(h )外部中断源0触发方式选择位IT0

功能与IT1相同。

CPU在每个机器周期对INT0和INT1引脚的输入电平进行采样。

I、电平触发方式

CPU采样到低电平时,置IE0和IE1,采样到高电平时,清除IE0和IE1。 在电平触发方式下,外部中断源必须始终保持低电平,直到CPU响应中断请求。 否则,中断请求就会丢失。 另外,在中断处理程序结束之前,外部中断源必须处于高电平。 否则,会发生另一个中断。

ii、下降沿触发方式

CPU在每个机器周期对中断输入端子进行采样,连续两次采样后,第一次为高电平,第二次为低电平,设定相应的IE,硬件响应中断自动将IE清零。 在采样下降沿触发方式下,为了使CPU有效地检测下降沿并产生CPU中断,中断源的高电平、低电平都需要维持12个振荡周期,即1个机器周期以上。

)2) 51单片机内部中断源

8051有三个内部中断源,分别是计时器T0、T1和串行端口中断。 8052添加了T2计时器中断。

2,51单片机中断使能控制

允许和禁止中断由中断允许控制寄存器IE控制,其字节地址为0A8H,可以进行位地址,其结构如下图所示。

EX0:外部中断0中断允许位;

ET0 )定时器/计数器T0中断允许位;

EX1 )外部中断1中断允许位;

ET1 :计时器/计数

器T1中断允许位;

ES:串行口中断允许位;

ET2:定时器/计数器T2中断允许位;(只要8052具有)

EA:CPU中断总允许位,EA=1时所有的中断开放,EA=0时禁止所有的中断。

3、51单片机中断优先级

51有两个优先级:高、低。通过IP(中断优先级寄存器)来设置优先级,其字节地址为0B8H,可位寻址,其结构如下图:

IP中各位值为0时表示低优先级中断,为1时表示高优先级中断。CPU复位后IP=0。

高优先级中断可以中断低优先级中断,同优先级中断不能相互中断。当CPU同时接到同优先级的几个中断请求时,CPU按照如下硬件顺序进行中断响应:

4、51单片机中断请求的撤除

CPU响应中断请求,执行中断服务程序,但在中断返回指令(RETI)之前必须撤除中断信号,否则将可能再次引起中断而发生错误。

中断请求撤销的方法有三种:

a、单片机内部硬件自动复位:对于定时器/计数器T0、T1及采用边沿触发方式的外部中断请求,CPU在响应中断后,由内部硬件自动撤销中断请求;

b、应用软件清除响应标志:对串口发送/接收中断请求及定时器T2的溢出和捕获中断请求,CPU响应中断后,内部无硬件自动复位RI、TI、TF2及EXF2,必须在中断服务程序中清除这些标志,才能撤除中断;

c、既无软件清除也无硬件撤除:对于采用电平方式的外部中断请求,CPU对引脚上的中断请求信号既无控制能力,也无应答信号,为保障CPU响应中断请求中断后,执行返回指令前撤除中断请求,必须考虑另外的措施。

5、51单片机中断响应过程

51 单片机在每个机器周期的S5P2状态顺序检查每个中断源的中断请求标志,若有中断源发送中断请求,CPU在下个机器周期的S5P2状态按优先级顺序查询各 中断标志,并且取高优先级的中断进行响应。响应中断后置位相应的中断优先级状态触发器,标明当前中断服务的优先级别,执行硬件调用程序,将程序计数器PC 的内容压入堆栈进行保护。对于中断源的中断入口地址装入程序计数器PC,使程序转入该中断入口处执行中断服务程序,直到遇到RETI指令。执行RETI指 令,撤销中断优先级触发器,弹出断点地址至程序计数器PC,继续源程序的执行过程。

在接收中断申请时,如遇到下列情况之一,硬件调用子程序将被封锁:

a、正在执行同级或高一级的中断服务程序;

b、当前指令周期不是该指令的最后一个周期(或一条指令未执行完);

c、当前正在执行的指令是RETI或对IE、IP的读写操作。

6、中断入口地址

各中断源的中断入口地址为:

STC86C52RC 51单片机中断示例程序

#include

typedef unsigned char         uint8;

typedef unsigned int          uint16;

typedef unsigned long          uint32;

sbit enableG1 = P1^3; sbit enableG2 = P1^4;

sbit selectC  = P1^2; sbit selectB  = P1^1; sbit selectA  = P1^0;

code uint16 num16[16] = {         0xC0, 0xF9, 0xA4, 0xB0,

0x99, 0x92, 0x82, 0xF8,

0x80, 0x90, 0x88, 0x83,

0xC6, 0xA1, 0x86, 0x8E        };//共阳数码管真极表

uint8 num6[6] = {0};//储存秒,0-5对应于个位...10万位上各位上的值

void enable138(void); //启用138译码器切换IO口

void refresh_led(void);

void thtl_init(void);

void timer1_init(void);

void et1_init(void);

void main(void)

{

enable138();

timer1_init();

et1_init();

while(1);

}

void interrupt_timer1(void) interrupt 3

{

static uint16 counter = 0;

static uint32 sec = 0;

counter++;

thtl_init();

if(counter == 1000)

{

counter = 0;

sec++;

num6[0] = sec % 10;

num6[1] = sec/10%10;

num6[2] = sec/100%10;

num6[3] = sec/1000%10;

num6[4] = sec/10000%10;

num6[5] = sec/100000%10;

}

refresh_led();//更新num6数组后再刷新数码管

}

void enable138(void) { enableG1 = 1; enableG2 = 0; }

//刷新数码管,只显示有效值

void refresh_led(void)

{

static uint8 i = 0;

switch(i)

{

case 0: selectC = 0; selectB = 0; selectA = 0; P0 = num16[ num6[0] ]; break;

case 1: selectC = 0; selectB = 0; selectA = 1; P0 = num6[5] == 0 && num6[4] == 0 && num6[3] == 0 && num6[2] == 0 && num6[1] == 0 ? 0xFF : num16[ num6[1] ]; break;

case 2: selectC = 0; selectB = 1; selectA = 0; P0 = num6[5] == 0 && num6[4] == 0 && num6[3] == 0 && num6[2] == 0 ? 0xFF : num16[ num6[2] ]; break;

case 3: selectC = 0; selectB = 1; selectA = 1; P0 = num6[5] == 0 && num6[4] == 0 && num6[3] == 0 ? 0xFF : num16[ num6[3] ]; break;

case 4: selectC = 1; selectB = 0; selectA = 0; P0 = num6[5] == 0 && num6[4] == 0 ? 0xFF : num16[ num6[4] ]; break;

case 5: selectC = 1; selectB = 0; selectA = 1; P0 = num6[5] == 0 ? 0xFF : num16[ num6[5] ]; break;

default: break;

}

i = ++i % 6;

}

//设置计数器初数值,重用的内容都应该写成独立函数出来方便维护

void thtl_init(void)

{

TH1  = (65536 - 922) / 256;

TL1  = (65536 - 922) % 256;

}

void timer1_init(void)

{

TMOD |= 0X10;

TMOD &= 0xDF;

thtl_init();

TR1  = 1;

}

void et1_init(void) { ET1 = 1; EA  = 1; }

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。