AVR单片机外部中断范例

PORTC =0xFF;
PORTD =0xFF;
DDRB = (1<<LED2)|(1<<LED1)|(1<<LED0); //输出
PORTB =~((1<<LED2)|(1<<LED1)|(1<<LED0)); //低电平,灯灭
//外部中断INT0,1,2做按键输入,使能内部上拉,就可以不用外接电阻了
读端口用PINx
写端口用PORTx */
}INTERRUPT(SIG_INTERRUPT1) //INT1中断服务程序
{
//硬件自动清除INTF1标志位
//这里全局中断被打开,将允许其他中断嵌套执行
_delay_ms(10);
if ((PIND&(1<<EXT_INT1))==0)
LED1_ON(); //点亮LED1
#define LED0 0 //PB0
#define LED1 1 //PB1
#define LED2 3 //PB3
//宏定义
#define LED0_ON() PORTB|= (1<<LED0) //输出高电平,灯亮
#define LED0_OFF() PORTB&=~(1<<LED0) //输出低电平,灯灭
在后面的C语句设[breakpoint],[RUN]跳过*/
//for()/while()语句计算延时时间较麻烦。
//为了使_delay_ms()函数的延时正确,须在makefile中设定F_CPU为实际的系统时钟频
//本范例为1MHz内部RC振荡器即F_CPU=1000000 /*
C:\WinAVR\avr\include\avr\目录包括所有芯片的定义和其他头文件
loop_until_bit_is_set(PIND,EXT_INT1);
_delay_ms(10);
}SIGNAL(SIG_INTERRUPT2) //INT2中断服务程序
{
//硬件自动清除INTF2标志位
_delay_ms(10);
if ((PINB&(1<<EXT_INT2))==0)
{
LED0_OFF(); //熄灭LED0
#define LED1_ON() PORTB|= (1<<LED1)
#define LED1_OFF() PORTB&=~(1<<LED1)
#define LED2_ON() PORTB|= (1<<LED2)
#define LED2_OFF() PORTB&=~(1<<LED2)
//51系列的高电平输出能力很弱,低电平也仅能点亮LED.所以常见输出低电平才灯亮的接法。
MCUCR=(1<<ISC11)|(0<<ISC10)|(1<<ISC01)|(0<<ISC00); //注意该寄存器有多个功能
/*
ISCx1:0=00 INTx引脚为低电平时产生中断请求
ISCx1:0=01 INTx引脚上任意的逻辑电平变化都将引发中断
ISCx1:0=10 INTx引脚的下降沿产生中断请求
AVR单片机外部中断范例1.开发语言
本范例使用WinAVR/GCC 20050214版本开发
2.范例描述
按下按键0,LED0亮。直到松手,其他按键才能起作用
按下按键1,LED1亮。其他按键随时都能起作用
按下按键2,LED0/1都熄灭。直到松手,其他按键才能起作用3.电路图设Hale Waihona Puke :为简化线路设计。.
4.代码设计与说明:
其中iom16.h定义ATMEGA16芯片的特性(中断向量,寄存器,位定义...)
包括下面中断服务程序的常量SIG_INTERRUPTx ,PORTx,GICR.....
*/
//管脚定义
#define EXT_INT0 2 //PD2按键0
#define EXT_INT1 3 //PD3按键1
#define EXT_INT2 2 //PB2按键2
本范例可直接使出厂状态的新M16芯片,无需对芯片的熔丝位进行配置。
出于简化程序考虑,各种数据没有对外输出,学习时建议使用JTAG ICE硬件仿真器关于外部中断作唤醒源的条件:(将会在后面的电源管理和睡眠模式范例中应用)而INT0和INT1的边沿触发中断只能在空闲模式起作用,即CLKI/O不停止INT0和INT1的低电平中断,INT2在各种睡眠模式下都可以,因为这几种中断工作于异步模式,不需要时钟驱动
#else
unsigned char FLAG; //全局变量.
#endif
//仿真时在watch窗口,监控这些变量。
SIGNAL(SIG_INTERRUPT0) //INT0中断服务程序
{
//硬件自动清除INTF0标志位
_delay_ms(10); //延时
if ((PIND&(1<<EXT_INT0))==0) //重复检测,防抖动
LED1_OFF(); //熄灭LED1
}
loop_until_bit_is_set(PINB,EXT_INT2);
FLAG=!FLAG; //修改全局变量
_delay_ms(100);
}int main(void)
{ //上电默认DDRx=0x00,PORTx=0x00输入,无上拉电阻
PORTA =0xFF; //不用的管脚使能内部上拉电阻。
LED0_ON(); //点亮LED0
loop_until_bit_is_set(PIND,EXT_INT0); //等待按键释放(变为高电平)
_delay_ms(10); //延时按键释放时也会抖动。
//即使同时发生其它的中断事件,如果在这里把相应的中断标志位清除,那么该中断将
不能触发进入中断服务/*注意
//注:内部函数_delay_ms()最高延时262.144mS@1MHz
/*该函数可以实现较精确的定时,但用JTAG仿真时较麻烦---会进入机器码窗口(Disassembeler)
.注意跳开该语段。
一旦JTAG仿真进入该内部函数语句,会变得像"死机"一样(其实在运行中),可以先[break],然后
//程序将永远都运行不到这里。
while (FLAG!=0);
LED2_OFF();
}
}
/*
程序运行效果
按下按键0,LED0亮。直到松手,其他按键才能起作用
按下按键1,LED1亮。其他按键随时都能起作用
按下按键2,LED0/1都熄灭。直到松手,其他按键才能起作用
LED2是根据按键2的顺序来亮灭,松手后变换,前提是FLAG加了volatile限定
ISCx1:0=11 INTx引脚的上升沿产生中断请求
*/
MCUCSR&=~(1<<ISC2); //注意该寄存器有多个功能
/*
ISC2=0 INT2引脚的下降沿产生异步中断请求
ISC2=1 INT2引脚的上升沿产生异步中断请求
*/
GIFR=(1<<INTF1)|(1<<INTF0)|(1<<INTF2);//写1清除标志位,在使能中断前最好先把对应
//的标志位清除,以免误触发
GICR=(1<<INT1)|(1<<INT0)|(1<<INT2); //使能三个外部中断FLAG=0;
sei(); //使能全局中断
while (1)
{
while (FLAG==0);
LED2_ON(); //如果FLAG不加volatile限定(即has_volatile=0),
官方的M16中文手册对外部中断的描叙存在多处错误,请参考英文原版。*/#include <avr/io.h>
#include <avr/delay.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
/*宏INTERRUPT的用法与SIGNAL类似,区别在于
SIGNAL执行时全局中断触发位被清除、其他中断被禁止
INTERRUPT执行时全局中断触发位被置位、其他中断可嵌套执行
另外avr-libc提供两个API函数用于置位和清零全局中断触发位,它们是经常用到的。
分别是:void sei(void)和void cli(void)由interrupt.h定义*/
****2005.8.31 ***
*************************************************/
/*
本程序简单的示范了如何使用ATMEGA16的外部中断
中断的设置
按键的简单延时防抖动
中断的嵌套
变量在中断中的应用---如果变量会在中断服务程序中被修改,须加volatile限定
*/
Reference URL:/mcu/AVR/278.html
/*************************************************
**** AVR外部中断使用范例***
*******
****策划、整理与测试:阿莫(armok) ***
****代码设计:HJJourAVR ***
****编译器:WINAVR20050214 ***
//AVR芯片的高低驱动能力都很强,甚至能推动8字数码管的公共极,怎么接都没问题。
//全局变量
#define has_volatile 1 //这里是条件编译
//可以修改has_volatile=1或0来看程序运行的效果
合集下载

AVR单片机WinAVR及Proteus仿真外部中断

AVR单片机WinAVR及Proteus仿真外部中断
打开刚才画好的仿真图,左键双击单片机出现如下配置框图,在Program File一栏中加载刚才生成的main.hex,由于我们编译时采用8M的CPU时钟,故CLKDIV8一栏要选择Unprogrammed,不要8分频,时钟选用内部8M的RC振荡源,确认后点击OK。按左下角的黑色三角形就可以仿真啦。
仿真的时候就可以按下那个button,看程序是否完成了应有的功能。
//LED灯状态标志位,0代表目前LED灯状态为灭,1代表LED灯目前状态为点亮
unsigned char led_flg = 0;
ISR(INT0_vect)//外部中断的中断服务程序,INT0_vectfromiom48p.h
{
EIFR &= ~(1<<INTF0);//清除中断标志位
_delay_ms(10);//延时去掉干扰
先打开这个MFile
将它另存到Hello_AVR下面,不要改它的名字,软件只认识Makefile这个名字,你若重命名了,还得再改还回来的。(在另存之前,这个界面下也可以做配置,可以配置完了再保存过去,效果也是一样的)
然后把它添加到工程文件夹Makefile下,打开Makefile文件,进行配置
绿色字体是注释,蓝色和黑色的是配置项。
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
extern void Exint_Iint(void);
#endif
avrexti.C:
#include <avrexti.h>
void Exint_Iint(void)//外部中断初始化函数

AVR学习-外部中断INT0实验

AVR学习-外部中断INT0实验

ARM-AVR 嵌入式开发论坛
2、GCC 中无参数的函数需要写为 void,否则编译时会有警告产生。如:void LED_off(void)
void LED_01(char i) { PORTB = ~_BV(i); _delay_ms(100); } void LED_02(char i) { PORTB=~(_BV(i)|_BV(i-2)); _delay_ms(100); }
Version : 08.12.06 Author:linxiyiran E_mail:605987969@ ※转载请注明出处
/
Updata : 09.02.26 模块化 09.05.03 增加 proteus 仿真模型,仿真通过 09.07.21 WinAVR-20071221 环境下编译通过 comments:
//LED 亮灭控制
//输出低电平 //调用延时程序
//间隔点亮
void LED_03(char i) { PORTB=~(_BV(i)|_BV(i-1)); _delay_ms(100); } //端口初始化程序 void port_init(void) { DDRA = 0x00; PORTA = 0xFF; DDRB = 0xFF; PORTB = 0xFF; DDRC = 0x00; PORTC = 0xFF; DDRD = 0x00; PORTD = 0xFF; } /*方向输入*/ /*打开上拉*/ /*方向输出*/ /*电平设置*/
ARM-AVR 嵌入式开发论坛
//输出高电平,LED 熄灭
for(l=0;l<2;l++) { for (i = 0; i < 8; i++) LED_01(i);

AVR mega16 简单的外中断C程序和相关寄存器解析

AVR mega16 简单的外中断C程序和相关寄存器解析

ISC11~ISC10:外部中断 1 的中断检测方式 ISC11 0 0 1 1 ISC01~ISC00:外部中断 0 的中断检测方式 ISC01 0 0 1 1 ISC00 0 1 0 1 表三 MCU 控制与状态寄存器-MCUCSR bit7 JTD bit6 ISC2 bit5 bit4 JTRF bit3 WDRF bit2 BORF bit1 EXTRF bit0 PORF INT0中断 低电平中断 INT1 引脚上任意的逻辑 电平变化都将引发中断 下降沿中断 上 ISC10 0 1 0 1 INT1中断 低电平中断 INT1 引脚上任意的逻辑电 平变化都将引发中断 下降沿中断 上升沿中断
個人說明:本文為本人學習的筆記,有不足之處請多多包涵,還請各路大俠多多指教。
INT1:使能外部中断请求1 INT0:使能外部中断请求0 INT2:使能外部中断请求 2 表五 通用中断标志寄存器 GIFR bit7 INTF1 bit6 INTF0 bit5 INTF2 bit4 bit3 bit2 bit1 IVSEL bit0 IVCE
INTF1:外部中断标志 INT1引脚电平发生跳变时触发中断请求,并置位相应的中断标志INTF1。如果SREG 的位I以及GICR寄存器相应的中断使能位INT1为”1”,MCU即跳转到相应的中断向量。 进入中断服务程序之后该标志自动清零。此外,标志位也可以通过写入”1” 来清零。
SE:MCU休眠使能位 SM1~SM0:MCU 休眠模式选择 SM2 0 0 0 0 1 1 1 1 SM1 0 0 1 1 0 0 1 1 SM0 0 1 0 1 0 1 0 1 休眠模式 空闲 ADC 噪声抑制模式 掉电模式 省电模式 保留 保留 Standby(1) 模式 扩展Standby(1) 模式

AVR的常用中断编程

AVR的常用中断编程

实在没有财富了,才拿自己写的东西出来献丑。

平时自己并不常用A VR,所以没有写得很完全,这个是做参考用,如果您接纳了我这种写法,可以自己写完所有的东西自己建立一个固件库。

包含了三个文件,分别是interrupt.c、interruptt.h和MacroAndConst.h,如果有疑问或者见解可以发邮件给我,我的邮箱:349705262@。

现在粘贴如下:/*interrupt.h里面的内容*/#ifndef _INTERRUPT_H_#define _INTERRUPT_H_#include<iom16v.h>#include<macros.h>#include"MacroAndConst.h"#include"interrupt.h"extern void INT(uchar int_num,uchar sense_ctrl);/*函数名:exteral_int()(外部中断控制函数)参数:int_num(外部中断数),sense_ctrl(触发方式)外部中断的数int_num的取值为0和1,为0时是外部中断0,为1时是外部中断1sense_ctrl的取值如下:0:为低电平产生中断1:任意逻辑电平变化都产生中断2:下降沿产生中断3:上升沿产生中断功能:设置外部中断并使能外部中断函数编写流程:1、写MCU控制寄存器MCUCR,选择是外部中断0还是1,并且选择触发方式;2、写MCU控制与状态寄存器MCUCSR,选择使能外部中断。

调用例子:main(){INT(0,2);//设置外部中断0,下降沿触发中断SREG=0x80;//打开总中断while(1){}}#pragma interrupt_handler int0:2void int0()//外部中断0响应函数{//写执行语句}-----------------------------------------------------------------------------------*/extern void TCNT0_8bit(uchar timer_counter,uchar clock_select);/*函数名:TCNT0_8bit()(设置8位定时计数器为定时器)参数:timer_counter(定时计数器寄存器初始值),clock_select(时钟分频选择) clock_select可取一下值:0:无时钟,T/C 不工作1:1 分频( 没有预分频)2:8 分频( 来自预分频器)3:64 分频( 来自预分频器)4:256 分频( 来自预分频器)5:1024分频( 来自预分频器)6:时钟由T0 引脚输入,下降沿触发7:时钟由T0 引脚输入,上升沿触发功能:设置8位定时计数器并使能定时计数器函数编写流程:1、重置T/C控制寄存器,WGM0和WGM1为0,普通模式2、选择时钟源3、赋8位定时计数器初值4、溢出中断使能调用例子:void main(){TCNT0(142,5);//选择1024分频,初值为142SREG|=0x80;//打开总中断while(1){}}#pragma interrupt_handler int0:10void tcnt0(){TCNT0=142;//重新赋值//写需要执行的语句}-----------------------------------------------------------------------------------*/extern void TCNT1_16bit(uint tcnt1_val,uchar clock_select);/*函数名:TCNT1_16bit()(设置16为定时计数器为定时器)参数:tcnt1_val(TCNT1初始值),clock_select(时钟分频选择)clock_select可取一下值:0:无时钟,T/C 不工作1:1 分频( 没有预分频)2:8 分频( 来自预分频器)3:64 分频( 来自预分频器)4:256 分频( 来自预分频器)5:1024分频( 来自预分频器)6:时钟由T0 引脚输入,下降沿触发7:时钟由T0 引脚输入,上升沿触发功能:设置16位定时计数器并使能相应溢出中断函数编写流程:1、设置TCCR1A、TCCR1B寄存器2、选择时钟分频3、赋初始16位定时计数器值4、溢出中断使能调用例子:#pragma interrupt_handler tcnt0:9void main(){TCNT1_16bit(57722,5);SREG|=0x80;while(1){}}void tcnt0(){TCNT1=57722;//写相应语句}-----------------------------------------------------------------------------------*/extern void Input_Capture(void);/*------------------------------------------------------------------------------------------------*/extern void FAST_PWM_16bit(uchar clock_select,uint ICR1_val,uint OCR1A_val,uint OCR1B_val);/*函数名:FAST_PWM_16bit()(设置16位定时计数器的快速PWM功能)参数:clock_select(时钟分频选择),ICR1_val(ICR1寄存器的值),OCR1A_val(OCR1A寄存器的值),0CR1B_val(OCR1B寄存器的值)clock_select可取一下值:0:无时钟,T/C 不工作1:1 分频( 没有预分频)2:8 分频( 来自预分频器)3:64 分频( 来自预分频器)4:256 分频( 来自预分频器)5:1024分频( 来自预分频器)6:时钟由T0 引脚输入,下降沿触发7:时钟由T0 引脚输入,上升沿触发功能:设置16位定时计数器的快速PWM功能,快速PWM模式恒为14模式,此模式下TOP值恒设为ICR1寄存器中的值函数编写流程:1、设置PD4、PD5为输出2、设置TCCR1A、TCCR1B寄存器3、选择时钟分频4、赋值ICR1,OCR1A,OCR1B备注:PWM的频率可以计算如下:PWM频率=时钟频率/(分频数*(1+ICR1_val))PWM的占空比可计算如下:PWM占空比=OCR1A_val/ICR1 (PD5引脚输出)PWM占空比=OCR1B_val/ICR1 (PD4引脚输出)调用例子:void main(){FAST_PWM_16bit(3,1249,625,625);while(1){}}-----------------------------------------------------------------------------------*/#endif/*interrupt.c里面的内容*/#include"interrupt.h"void INT(uchar int_num,uchar sense_ctrl)//外部中断设置函数{switch(int_num){case 0: MCUCR|=sense_ctrl;//控制产生中断方式GICR|=0x40;//使能外部中断0break;case 1: MCUCR=MCUCR|(sense_ctrl*0x04);GICR|=0x80;break;case 2: MCUCSR=MCUCR||(sense_ctrl<<7);GICR=0x20;break;default:break;}}void TCNT0_8bit(uchar time_counter,uchar clock_select){TCCR0=0;//重置T/C控制寄存器,WGM0和WGM1为0,普通模式TCCR0|=clock_select;//选择时钟源TCNT0=time_counter;//初始化T/C寄存器TIMSK|=(1<<TOIE0);//溢出中断使能}void TCNT1_16bit(uint tcnt1_val,uchar clock_select){TCCR1A=0;//重置TCCR1ATCCR1B=0;//重置TCCR1B//普通模式TCCR1B|=clock_select;//选择时钟源TCNT1=tcnt1_val;//定时计数器初始化TIMSK|=(1<<TOIE1);//使能溢出中断}void Input_Capture(){TCCR1A=0;TCCR1B=0xc4;//使用输入噪声抑制器,输入捕捉为上升沿触发,时钟256分频TIMSK|=(1<<TICIE1);//输入捕捉中断使能TIMSK|=(1<<TOIE1);//T/C1溢出中断使能}void FAST_PWM_16bit(uchar clock_select,uint ICR1_val,uint OCR1A_val,uint OCR1B_val) {DDRD|=0x30;TCCR1A|=0XA2;//设置为快速PWM15模式,PD4、PD5口在匹配时输出电平翻转clock_select|=0x18;TCCR1B|=clock_select;ICR1=ICR1_val;OCR1A=OCR1A_val;OCR1B=OCR1B_val;}/*MacroAndConst.h里面的内容*/ #ifndef _MACRO_AND_CONST_H_ #define _MACRO_AND_CONST_H_typedef unsigned int uint;typedef unsigned char uchar; #endif。

第4章avrmega16单片机中断实例

第4章avrmega16单片机中断实例

• 4) 中断嵌套
在中断发生后,SREG的I位由硬件清除,并由 RETI(中断返回)指令置位,从而允许子序列的中断响应。
由于 AVR 在响应一个中断的过程中通过硬件将 I 标志 位自动清零,这样就阻止了 MCU响应其它中断。因此通 常情况下,AVR 是不能自动实现中断嵌套的。 如要系统中必须要实现中断嵌套的应用,用户可在中 断服务程序中使用指令将全局中断允许位开放,通过间接 的方式实现中断的嵌套处理。
1) MCU 控制寄存器—MCUCR
• MCU 控制寄存器 MCUCR 的低 4 位为 INT0(ISC01、 ISC00)和 INT1(ISC11、ISC10)中断触发类型控制位。
2)MCU 控制和状态寄存器—MCUCSR
• MCU 控制和状态寄存器 MCUCSR 中的第6位(ISC2) 为 INT2 的中断触发类型控制位。
void main(void) { PORTA=0xFF; DDRA=0xFF; PORTD|=0x0C; DDRD|=0x00; //DDRD.3=0;DDRD.2=0; GICR|=0xC0; MCUCR=0x0A; MCUCSR=0x00; GIFR=0xC0; //清除INT0、INT1中断标志位 #asm("sei") //SREG|=0x80; SREG.7=1; while (1) { PORTA=led_7[counter]; } }
4) 通用中断标志寄存器—GIFR
• 注意:用户可以使用指令将 INTFn 清除,清除的方式是 写逻辑“1”到 INTFn,将标志清零。另外, 当INT0 (INT1) 设置为低电平触发方式时, 标志位 INTF0 (INTF1) 始终为“0”,这并不意味着不产生中断请求, 而是低电平触发方式是不带中断标志类型的中断触发。在 低电平触发方式时,中断请求将一直保持到引脚上的低电 平消失为止。 • 而在开放中断允许前,一般应通过向 GIFR 寄存器中的中 断标志位 INTFn 写入逻辑“1” ,将该中断的中断标志位 清除,然后开放中断。这样可以防止在改变ISCn 的过程

AVR单片机外部中断C程序框架

AVR单片机外部中断C程序框架

AVR单片机外部中断C程序框架
Avrmega16a
单片机在studio4开发环境中外部中断C程序框架如下:
#include;
//头文件.
#include;
//中断头文件;
typedefunsignedcharuint8;
//习惯宏定义数据类型语法.应用时只需写入数据类型:
//
uint8s=0;
typedefunsignedintuint16;
//习惯宏定义数据类型语法.应用时只需写入数据类型:
//
uint16
i=0;
Intmain()
//主函数;
{
MCUCR=0Xnn:
//中断模式触发寄存器,用来设置外部中断引脚的触发方式,上升沿,下降
//沿,还是高电平或低电平方式;
GICR=0Xnn;
//局部中断使能,用来使能某个中断源.
Sei();
//全局中断使能,用来开启中断服务(中断总使能); //在此写入程序语句;
//
//如果外部中断源一旦被触发,程序就会立即执行中断服务函数;
}
//此&darr;&lsquo;n&rsquo;是外部中断源序号有中断0,中断1,中断2.
SIGANL(SIG_INTRRUPTn)
//终端服务函数;
{
//在中断函数中,不能定义局部数据类型变量;
//在此写入中断程序;
}。

AVR外设汇总之中断

中断 //PD2 位发生下降沿,触发的中断函数 ISR(INT0_vect) { } //PD3 位发生下降沿,触发的中断函数 ISR(INT1_vect) { } int main(void){ //设置 PD2、PD3 为输出 DDRD=_BV(PD2)|_BV(PD3); //置 PD2、PD3 位都为高电平 PORTD=0xFF; //ISC01 位置 1,表示设置 INT0(PD2)为下降沿中断 //ISC11 位置 1,表示设置 INT1(PD3)降沿触发一个外部中断 INT0 INT1 //INT0 位置 1,表示打开 INT0 的外部中断使能 //INT1 位置 1,表示打开 INT1 的外部中断使能 GICR= _BV(INT0)|_BV(INT1); sei();//cli();打开/关闭全局中断 while(){ //设置 PD2 位为输出 DDRD|=_BV(PD2); //置 PD2 位为低电平产生一个下降沿,触发 INT0 的中断函数 PORTD&=~_BV(PD2); _delay_ms(1); //置 PD2 位为高电平 PORTD|=_BV(PD2); //置 PD2 位为输入,等待硬件中断(全局等待 SW18 按键被按下) DDRD&=~_BV(PD2); //设置 PD3 位为输出 DDRD|=_BV(PD3); //置 PD3 位为低电平产生一个下降沿,触发 INT1 的中断函数 PORTD&=~_BV(PD3); _delay_ms(1); //置 PD3 位为高电平 PORTD|=_BV(PD3); //置 PD3 位为输入,等待硬件中断(全局等待 SW17 按键被按下) DDRD&=~_BV(PD3); } }

CodevisionAVR中断的使用(中文翻译)

service routine. Example:
#pragma矢量用来指明接下来的声明函数是一个中断服务程序。例如:
/* Vector numbers are for the AT90S8515 */
AT90S8515的矢量(向量)值
/* Specify the vector number using the #pragma vector directive */
关闭寄存器自动保存
#pragma savereg-
/* interrupt handler */
中断处理程序
interrupt [1] void my_irq(void) {
/* now save only the registers that are affected by the routines in the
#pragma savereg指示是为了保持与早于V1.24.1版本的兼容性。这个指示不建议在新版本中使用。
interrupt handler, for example R30, R31 and SREG */
现在只保存被中断程序影响的寄存器,比如R30,R31和SREG
#asm pusBiblioteka r30 push r31
in r30,SREG
push r30
Example:/* Vector numbers are for the AT90S8515 */
AVR单片机的中断入口由关键词interrupt指示。
例如:AT90s8515的中断向量值
/* Called automatically on external interrupt */
自动调用外部中断

AVR单片机外部中断触发的流水灯程序

AVR单片机外部中断触发的流水灯程序/*programname : 外部中断程序; 这费了我好几个小时的心血!成功的喜悦难以用言语表达! 概述: 8 位流水非精确定时,一秒循环灯闪烁,等待外部中断一下降沿中断触发信号, 外部中断一旦触发,等待触发按键弹起(此时流水灯暂停状态),中断按键一旦弹起,继续运行上一级程序(流水灯继续运行); accomplish time : 2014-2-7 22:47:15;*/#include #include interrupt.h> //中断必备的头文件;typedef unsigned char uint8;typedef unsigned int uint16;void init_io() //所有io 口初始化函数;{ DDRA=0XFF;PORTA=0X00; //PA 口输出0;DDRB=0XFF;PORTB=0X00; //PB 口输出0;DDRC=0XFF;PORTC=0X00; //PC 口输出0;DDRD=~(1}void delay(){ uint16 u=0 ; uint8 s=0;for(s=0;s}void buzz(){ uint16 s=0; uint8 i=0;PORTC|=0X80; for(i=0;iint main(void){ init_io(); //初始化io 口;//* 1. 先设置好由那个引脚来触发外部中断, 和触发方式; // MCUCR 是中断触发模式控制寄存器; MCUCR|=1 sei();//全局中断使能函数.没有此函数,中断将无法执行.(我不知道为什么!或许是甲鱼的屁股--规定!)while(1){ PORTB|=1 delay(); //非精确延时1 秒左右;PORTB&=~(1delay(); //非精确延时1 秒左右;}。

AVR笔记:外部中断

A VR学习笔记之【外部中断】【一】Mega16共有三个外部中断,外部中断相比定时器而言它的寄存器比较少,因此相对比较简单。

我们现在只关心需要用的部分,其他的暂且放弃不管。

和外部中断相关的特殊功能寄存器有:①MCU控制寄存器(MCUCR)在上面八位的寄存器中,白色的部分使我们要关心的,灰色部分就不用管了。

资料上对后面四位(第四位)的作用有介绍。

ISC11与ISC10控制中断1的触发方式。

下表为ISC10/11的值对应触发方式:SC11与ISC10控制中断0的触发方式。

下表为ISC00/01的值对应触发方式:我们在使用外部中断0和1的时候,其触发方式的设置便是通过以上ISC的不同值实现的。

至于INT2下面有介绍。

②MCU控制与状态寄存器(MCUCSR)这个寄存器只有一个BIT与外部中断相关。

ISC2,我们通过和INT0/1的对比可以发现ISC的后缀数字命名只有规律的,这会方便我们记忆。

同时在说明文档上说了很长一段关于ISC2的说明:他的意思说早了,他也就是想说:ISC=0的话INT2是下降沿出发中断,ISC=1是上升沿出发。

这才是应该说明的最重要的点。

他后面还说了:(1)如果你让ISC=0那么外部的低电平必须保持到当前正在运行的指令运行结束才会出发,换一句意思就是,如果外部时间过短,有可能导致INT2不被触发。

(2)他又说明,如果改变ISC2的值的话有可能触发中断,导致误判,因此如果你想改变其中断触发方式的话,首先把通用中断控制寄存器(GICR)里面控制INT2的中断开关关了,这样便不会触发中断了。

③通用中断控制寄存器(GICR)他就是个中断开关。

前面三位依次赋值便会打开响应中断。

当然总中断开关也要打开才行(SREG|=BIT(7))。

④通用中断标志寄存器(GIFR)他就是一个中断标志,我们也就是说在中断发生的时候中断对用的标志会变为1,此时程序会自动转到中断程序子函数。

然后有硬件自动清零,以等待下一次的中断发生。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
相关文档
最新文档