avr外部中断.docx
- 文档编号:10460264
- 上传时间:2023-02-13
- 格式:DOCX
- 页数:7
- 大小:17.47KB
avr外部中断.docx
《avr外部中断.docx》由会员分享,可在线阅读,更多相关《avr外部中断.docx(7页珍藏版)》请在冰豆网上搜索。
avr外部中断
AVR单片机外部中断范例1.开发语言
本范例使用WinAVR/GCC20050214版本开发
2.范例描述
按下按键0,LED0亮。
直到松手,其他按键才能起作用
按下按键1,LED1亮。
其他按键随时都能起作用
按下按键2,LED0/1都熄灭。
直到松手,其他按键才能起作用3.电路图设计:
为简化线路设计。
.
4.代码设计与说明:
/*************************************************
****AVR外部中断使用范例***
*******
****策划、整理与测试:
阿莫(armok)***
****代码设计:
HJJourAVR***
****编译器:
WINAVR20050214***
****www.OurAVR.com2005.8.31***
*************************************************/
/*
本程序简单的示范了如何使用ATMEGA16的外部中断
中断的设置
按键的简单延时防抖动
中断的嵌套
变量在中断中的应用---如果变量会在中断服务程序中被修改,须加volatile限定
本范例可直接使出厂状态的新M16芯片,无需对芯片的熔丝位进行配置。
出于简化程序考虑,各种数据没有对外输出,学习时建议使用JTAGICE硬件仿真器关于外部中断作唤醒源的条件:
(将会在后面的电源管理和睡眠模式范例中应用)而INT0和INT1的边沿触发中断只能在空闲模式起作用,即CLKI/O不停止INT0和INT1的低电平中断,INT2在各种睡眠模式下都可以,因为这几种中断工作于异步模式,不需要时钟驱动
官方的M16中文手册对外部中断的描叙存在多处错误,请参考英文原版。
*/#include
#include
#include
#include
/*宏INTERRUPT的用法与SIGNAL类似,区别在于
SIGNAL执行时全局中断触发位被清除、其他中断被禁止
INTERRUPT执行时全局中断触发位被置位、其他中断可嵌套执行
另外avr-libc提供两个API函数用于置位和清零全局中断触发位,它们是经常用到的。
分别是:
voidsei(void)和voidcli(void)由interrupt.h定义*/
//注:
内部函数_delay_ms()最高延时262.144mS@1MHz
/*该函数可以实现较精确的定时,但用JTAG仿真时较麻烦---会进入机器码窗口(Disassembeler)
.注意跳开该语段。
一旦JTAG仿真进入该内部函数语句,会变得像"死机"一样(其实在运行中),可以先[break],然后
在后面的C语句设[breakpoint],[RUN]跳过*/
//for()/while()语句计算延时时间较麻烦。
//为了使_delay_ms()函数的延时正确,须在makefile中设定F_CPU为实际的系统时钟频
//本范例为1MHz内部RC振荡器即F_CPU=1000000/*
C:
\WinAVR\avr\include\avr\目录包括所有芯片的定义和其他头文件
其中iom16.h定义ATMEGA16芯片的特性(中断向量,寄存器,位定义...)
包括下面中断服务程序的常量SIG_INTERRUPTx,PORTx,GICR.....
*/
//管脚定义
#defineEXT_INT02//PD2按键0
#defineEXT_INT13//PD3按键1
#defineEXT_INT22//PB2按键2
#defineLED00//PB0
#defineLED11//PB1
#defineLED23//PB3
//宏定义
#defineLED0_ON()PORTB|=(1< #defineLED0_OFF()PORTB&=~(1< #defineLED1_ON()PORTB|=(1< #defineLED1_OFF()PORTB&=~(1< #defineLED2_ON()PORTB|=(1< #defineLED2_OFF()PORTB&=~(1< //51系列的高电平输出能力很弱,低电平也仅能点亮LED.所以常见输出低电平才灯亮的接法。 //AVR芯片的高低驱动能力都很强,甚至能推动8字数码管的公共极,怎么接都没问题。 //全局变量 #definehas_volatile1//这里是条件编译 //可以修改has_volatile=1或0来看程序运行的效果 #ifhas_volatile volatileunsignedcharFLAG;//全局变量,会在中断服务程序中被修改,须加volatile限定 #else unsignedcharFLAG;//全局变量. #endif //仿真时在watch窗口,监控这些变量。 SIGNAL(SIG_INTERRUPT0)//INT0中断服务程序 { //硬件自动清除INTF0标志位 _delay_ms(10);//延时 if((PIND&(1< LED0_ON();//点亮LED0 loop_until_bit_is_set(PIND,EXT_INT0);//等待按键释放(变为高电平) _delay_ms(10);//延时按键释放时也会抖动。 //即使同时发生其它的中断事件,如果在这里把相应的中断标志位清除,那么该中断将 不能触发进入中断服务/*注意 读端口用PINx 写端口用PORTx*/ } INTERRUPT(SIG_INTERRUPT1)//INT1中断服务程序 { //硬件自动清除INTF1标志位 //这里全局中断被打开,将允许其他中断嵌套执行 _delay_ms(10); if((PIND&(1< LED1_ON();//点亮LED1 loop_until_bit_is_set(PIND,EXT_INT1); _delay_ms(10); } SIGNAL(SIG_INTERRUPT2)//INT2中断服务程序 { //硬件自动清除INTF2标志位 _delay_ms(10); if((PINB&(1< { LED0_OFF();//熄灭LED0 LED1_OFF();//熄灭LED1 } loop_until_bit_is_set(PINB,EXT_INT2); FLAG=! FLAG;//修改全局变量 _delay_ms(100); } intmain(void) {//上电默认DDRx=0x00,PORTx=0x00输入,无上拉电阻 PORTA=0xFF;//不用的管脚使能内部上拉电阻。 PORTC=0xFF; PORTD=0xFF; DDRB=(1< PORTB=~((1< //外部中断INT0,1,2做按键输入,使能内部上拉,就可以不用外接电阻了 MCUCR=(1< /* ISCx1: 0=00INTx引脚为低电平时产生中断请求 ISCx1: 0=01INTx引脚上任意的逻辑电平变化都将引发中断 ISCx1: 0=10INTx引脚的下降沿产生中断请求 ISCx1: 0=11INTx引脚的上升沿产生中断请求 */ MCUCSR&=~(1< /* ISC2=0INT2引脚的下降沿产生异步中断请求 ISC2=1INT2引脚的上升沿产生异步中断请求 */ GIFR=(1< //的标志位清除,以免误触发 GICR=(1< sei();//使能全局中断 while (1) { while(FLAG==0); LED2_ON();//如果FLAG不加volatile限定(即has_volatile=0), //程序将永远都运行不到这里。 while(FLAG! =0); LED2_OFF(); } }/* 程序运行效果 按下按键0,LED0亮。 直到松手,其他按键才能起作用 按下按键1,LED1亮。 其他按键随时都能起作用 按下按键2,LED0/1都熄灭。 直到松手,其他按键才能起作用 LED2是根据按键2的顺序来亮灭,松手后变换,前提是FLAG加了volatile限定 */5.源代码,Makefile,烧录文件,仿真文件下载: 本文来自: DZ3W.COM原文网址: file: ///D: /My%20Documents/AVR单片机外部中断范例_AVR单片机_电子天下.htm
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- avr 外部 中断