单片机c语言 oxfe,AVR单片机入门及C语言高效设计实践(五)

ATMEAGl6L的中断系统什么是“中断”?顾名思义中断就是中断某一工作过程去处理一些与本工作过程无关或间接相关或临时发生的事件,处理完后,则继续原工作过程。比如:你在看书,电话响了,你在书上做个记号后去接电话,接完后在原记号处继续往下看书。如有多个中断发生,依优先法则,中断还具有嵌套特性。又比如:看书时,电话响了,你在书上做个记号后去接电话,你拿起电话和对方通话,这时门铃响了,你让打电话的对方稍等一下,你去开门,并在门旁与来访者交谈,谈话结束,关好门,回到电话机旁,拿起电话,继续通话,通话完毕,挂上电话,从作记号的地方继续往下看书。由于一个人不可能同时完成多项任务,因此只好采用中断方法,一件一件地做。

类似的情况在单片机中也同样存在,通常单片机中只有一个CPU,但却要应付诸如运行程序、数据输入输出以及特殊情况处理等多项任务,为此也只能采用停下一个工作去处理另一个工作的中断方法。在单片机中,“中断”是一个很重要的概念。中断技术的进步使单片机的发展和应用大大地推进了一步。所以,中断功能的强弱已成为衡量单片机功能完善与否的重要指标。中断系统的引入解决了微处理器和外设之间数据传输速率的问题,提高了微处理器的实时性和处理能力。

当微处理器处于中断开放时,才能接受外部的中断申请。一个完整的中断处理过程包括中断请求、中断响应、中断处理和中断返回。

中断请求是中断源向微处理器发出的信号,要求微处理器暂停原来执行的程序并为之服务。中断请求可以是电平信号或者脉冲信号。中断请求信号一般保持到微处理器作出响应为止。微处理器在检测到中断请求信号之后,将中止当前正在执行的程序,并对断点实行保护,即将断点的地址(PC值)推入堆栈保护,以便在中断结束时从堆栈弹出断点地址,以便继续执行中断前的任务。然后,微处理器由中断地址表获取中断入口地址,并将此地址送入程序计数器(PC),从而开始执行中断服务程序。在中断服务程序里一般需要完成现场保护、开关中断、执行中断服务程序、现场恢复和中断返回等工作。

ATMEAG16L具有20个中断源和1个复位中断,在中断源中处于低地址的中断具有高的优先级。所有中断源都有独立的中断使能位,当相应的使能位和全局中断使能位(SREG寄存器的位I)都置1时,中断才可以发生,相应的中断服务程序才会执行。下表为ATMEAGl6L的中断源。

向量号

程序地

中断源

中断足义

1

0x000

RESET

外部引脚电平引发的复位,上电复位,掉电检测复位,看门狗复位,以及JTAGAVR复位

2

0x002

INT0

外部中断请求0

3

0x004

INT1

外部中断请求1

4

0x006

TIMER2COMP

定时器/计数器2比较匹配

5

0x008

TIMER2OVF

定时器/计数器2溢出

6

0x00A

TIMERlCAPT

定时器/计数器1事件捕捉

7

0x00C

TIMERlCOMPA

定时器/计数器1比较匹配A

8

0x00E

TIMER1COMPB

定时器/计数器1比较匹配B

9

0x010

TIMER1OVF

定时器/计数器1溢出

10

0x012

TIMER0OVF

定时器/计数器O溢出,

11

0x014

SPI.STC

SPI串行传输结束

12

0x016

USART.RXC

USART,Rx结束

13

0x018

USART.UDRE

USART数据寄存器空

14

0x01A

USART。TXC

USART,Tx结束

15

0x01C

ADC

ADC转换结束

16

0x01E

EERDY

EEPROM就绪

17

0x020

ANACOMP

模拟比较器

18

0x022

TWI

两线串行接口

19

0x024

INT2

外部中断请求2

20

0x026

TIMER0COMP

定时器/计数器0比较匹配

21

0x028

SPMRDY

保存程序存储器内容就绪

一个中断产生后,SREG寄存器的全局中断使能位I将被清零,后续中断被屏蔽。

用户可以在中断服务程序里对I置位从而再次开放中断。在中断返回后,全局中断位I将重新置位。当程序计数器指向中断向量开始执行相应的串断暇务程序时,对应中断标志位将被硬件清零。当一个符合条件的中断发生后,如果相应的中断使能位为0,中断标志位将挂起并一直保持到中断执行或者被软件清除。如果全局中断标志I被清零,则所有的中断都不会被执行直到I置位。然后,被挂起的各个中断按中断优先级依次被处理。

ATMEAG16L的外部中断编程实践ATMEAG16L具有多达20个中断源,这里我们首先进行外部中断的实验,其它的等到介绍到相关内容时再进行实验。

1.外部中断0外部中断0由引脚INT0(PIND2)触发。如果INT0引脚按照MCUCR寄存器中的ISC01、ISC00设置的方式发生跳变,则不管是否INTO中断使能,INTO中断标志位INTFO都将置位。如果SREG寄存器的全局中断位I和通用中断控制寄存器GICR中的lNT0中断使能位INTO置位,则开始执行中断程序。在进入中断服务程序时,INTF0被硬件清零。必须指出,不管INT0(PIND2)引脚方向位设置如何,只要INT0引脚发生规定的跳变,都会触发中断。中断标志位INTF0只在满足发生中断的条件时置位,一旦条件变化,INTF0被硬件清零。向INTF0位写“1”也会对其清零。

2.外部中断1外部中断1由引脚INTI(PIND3)触发。如果INTl引脚按照MCUCR寄存器中的ISC11、ISC10设置的方式发生跳变,则不管是否INT1中断使能,INT1中断标志位INTF1都将置位。如果SREG寄存器的全局中断位l和通用中断控制寄存器GICR中的INTl中断使能位INT1置位,则开始执行中断程序。在进入中断服务程序时,INTF1被硬件清零。必须指出,不管INT1(PIND3)引脚方向位设置如何,只要INT1引脚发生规定的跳变,都会触发中断。中断标志位INTF1只在满足发生中断的条件时置位,一旦条件变化,INTF1被硬件清零。向INTF1位写“1”,也会对其清零。

3.外部中断2外部中断2由引脚INT2(PINB2)触发。如果INT2引脚按照MCUCR寄存器中的ISC2设置的方式发生跳变,则不管是否INT2中断使能,INT2中断标志位INTF2都将置位。如果SREG寄存器的全局中断位I和通用中断控制寄存器GICR中的INT2中断使能位INT2置位,则开始执行中断程序。在进入中断服务程序时,INTF2被硬件清零。必须指出,不管INT2(PINB2)引脚方向位设置如何,只要INT2引脚发生规定的跳变,都会触发中断。中断标志位INTF2只在满足发生中断的条件时置位,一旦条件变化,INTF2被硬件清零。向INTF1位写“1”,也会对其清零。

INT1中断实验:平时8个LED闪烁,点亮/熄灭时间约500mS。一旦INT1触发中断后,蜂鸣器发出10秒的报警声。

在我的文档中新建一个ac6的文件夹。建立一个ac6.prj的工程项目,最后建立源程序文件ac6.C。输入下面的程序(程序1):

85f77f2bf5d7fda83de1f1555600e8a0.png

编译通过后,可在AVRStudio集成开发环境中进行INTO、INT1中断嵌套实验:平时8个LED闪烁,点亮/熄灭时间约500ms。INTl触发中断后,蜂鸣器发出1O秒的报警声。在INT1的中断服务子函数中,再置位总中断使能位I,这样INT1中断服务子函数中,即可进行INT0中断嵌套。当INT0触发中断时,进入INT0中断服务子函数,将8个LED的一半熄灭。

在我的文档中新建一个ac7的文件夹。建立一个JTAG在线仿真或进行软件模拟仿真。仿真完成后,将ac6.hex文件下载到AVR单片机综合试验板上。注意,标示“LED”及“INT1”的双排针应插上短路块。我们看到,D1-D8发光管闪亮,间隔约0.5秒。按下INT1键后,单片机进入中断,蜂鸣器发声10秒。

ac7.prj的工程项目,最后建立源程序文件ac7.C。输入下面的程序(程序2):

a7b1cdd632f77985127a79a8a8f15d95.png

编译通过后,可在AVRStudio集成开发环境中进行JTAG在线仿真或进行软件模拟仿真。仿真完成后,将ac7.hex文件下载到AVR单片机综合试验板上进行实际的中断操作。注意,标示“LED”、“BEEP”及“INT0”、“INT1”的双排针应插上短路块。

两路防盗报警器实验:平时一个数码管熄灭。当盗情发生时自动显示“1”或“2”,同时一个LED点亮(代表报警)。着两路同时产生盗情,则数码管每隔2秒轮流显示“1”、“2”。直到值班人员按下复位按钮后才解除报警。

在我的文档中新建一个ac8的文件夹。建立一个ac8.pd的工程项目,最后建立源程序文件ac8.C。输入下面的程序(程序3):

程序3)

#include    //包含头文件

#define uchar unsigned char  ∥变量类型的宏定

#define uint unsigned int

uchar const SEG7f [10]={0X3f,0x06.0x5b,∥共阴极数

码管0-9的字形码

0x4f,Ox66;Ox6d,0x7d,Ox07,0x7f,0x6f};

#define ALM_ON(PORTB=PORTB&0xfe)//报警

器启动

uchar aim_flag1,alm_flag2;//第1、2路盗情标志

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

void delay_ms(uint k)//定义毫秒级的延时子函数

{

uint i,j;

for(=O:i

{

for(j=0;j<1140;j++)

}

}

//========================

void main(void)∥定义主函数

{    ∥主函数开始

DDRA=0xff;  ∥将PA端口设为输出

DDRC=0xff;    ∥将PC端口设为输出

PORTA=0x00;#PA端口初始化输出00000000

PORTC=0xff;  //PC端口初始化输出1 1 11 1 1 1 1

PORTB=0xff; //PB端口初始化输出11 11 1 1 1 1

DDRB=0xff:  //将PB端口设为输出

PORTD=0xff;  #PD端口初始化输出1 111111 1

DDRD=0xf3;  //将PIND2、3设为输入

MCUCR=0x0A;//INT0、1为下降沿触发

GICR:0xC0;//使能INT0、1中断

SREG=0x80;//使能总中断

while(1)    //无限循环

{    ∥无限循环语句开始

if(alm_flag1==1)//如果第1路产生盗情

{PORTA=SEG7[1];∥数码管显示为1

PORTC=Oxfe;//点亮最右的数码管

ALM_ON://报警器启动

delay_ms(2000);#延时2秒

}

if(alm_flag2==1)∥如果第2路产生盗情

{PORTA=SEG7[2];∥数码管显示为2

PORTC=0xfe;//点亮最右的数码管

ALM_ON;//报警器启动

delay_ms(2000);//延时2秒

}

}    ////无限循环语句结束

}    ////主函数结束

∥****************************************

*

#pragma interrupt_handler intO_isr:2#INTO中断服

务子函数

void intO_isr(void)

{

aim_flagl=1:    //置第1路盗情标志为

1

#pragma interrupt_handler int1_isr:3//INT1

务子函数

中断服

void int1_isr(void)

{

alm_flag2=1;    //置第2路盗情标志为1

}

}

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

编译通过后,可将ac8.hex文件下载到AVR单片机综合试验板上进行实际的操作演示。注意,标示“LED”、“LEDMOD_DISP”、“LED-MOD_COM”及“INT0”、“INT1”的双排针应插上短路块。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值