资源描述
AVR使用范例--AVR外部中断范例
本页关键词: 单片机外部中断 外部中断的应用 AVR外部中断 INTERUPTS
关于AVR中断:
系统在正常运行主程序时,如果突然有一个重要的任务要马上处理,那么系统就要保存现在的工作,然后再去处理这个任务,执行这个重要任务完毕以后再返回原来的主程序继续运行,这就是中断。
主程序一旦进入中断服务程序,那么AVR芯片将自动的关闭全局中断,在这个期间不再执行其它的中断请求,直到中断程序结束以后芯片才自动的重新开放全局中断。(注意,在这个期间某些中断请求可能会被丢弃,某些请求会留下中断请求标致,一旦当前的中断执行完毕,这个有中断标致的请求就有可能马上得到响应,如INT0的下降沿触发就会留下中断请求标致,而低电平触发就不会流下中断请求标致)。如果你想在执行中断服务程序时响应另外一个更重要的中断,那么就要在中断服务程序中加入一条打开全局中断的语句。
使用ICC快速建立中断服务程序
//ICC-AVR application builder : 2006-12-8 17:04:44
// Target : M16
// Crystal: 7.3728Mhz
#include <iom16v.h>
#include <macros.h>
unsigned int i=0;
void port_init(void)
{
PORTA = 0x00;
DDRA = 0x01;
PORTB = 0x00;
DDRB = 0x00;
PORTC = 0x00; //m103 output only
DDRC = 0x00;
PORTD = 0x0C; //使INT0,INT1对应口上拉电阻有效
DDRD = 0x00; //必须设置INT0,INT1对应口为输入
}
#pragma interrupt_handler int0_isr:2
void int0_isr(void)
{
//external interupt on INT0
i++;
}
#pragma interrupt_handler int1_isr:3
void int1_isr(void)
{
//external interupt on INT1
PORTA = 0x01;
}
//call this routine to initialize all peripherals
void init_devices(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
port_init();
MCUCR = 0x08; //INT1 的下降沿产生异步中断请求,INT0上升延
GICR = 0xC0; //INT0和INT1使能
TIMSK = 0x00; //timer interrupt sources
SEI(); //re-enable interrupts
//all peripherals are now initialized
}
void main(void)
{
init_devices();
while(1) //死循环等待中断
;
}
使用ICCAVR Application Builder进行如下图所示的设置。 可以设置是否使用中断,上升延,下降延,低电平,任意的逻辑电平变化。
将生成的程序进行修改,DDRA = 0x01;PORTD = 0x0C; ,添加MAIN函数,如下
· //ICC-AVR application builder : 2006-12-8 17:04:44
· // Target : M16
· // Crystal: 7.3728Mhz
·
· #include <iom16v.h>
· #include <macros.h>
·
· unsigned int i=0;
·
· void port_init(void)
· {
· PORTA = 0x00;
· DDRA = 0x01;
· PORTB = 0x00;
· DDRB = 0x00;
· PORTC = 0x00; //m103 output only
· DDRC = 0x00;
· PORTD = 0x0C; //使INT0,INT1对应口上拉电阻有效
· DDRD = 0x00; //必须设置INT0,INT1对应口为输入
· }
·
· #pragma interrupt_handler int0_isr:2
· void int0_isr(void)
· {
· //external interupt on INT0
· i++; //在中断里进行操作
· }
·
· #pragma interrupt_handler int1_isr:3
· void int1_isr(void)
· {
· //external interupt on INT1
· PORTA = 0x01; //在中断里进行操作
· }
·
· //call this routine to initialize all peripherals
· void init_devices(void)
· {
· //stop errant interrupts until set up
· CLI(); //disable all interrupts
· port_init();
·
· MCUCR = 0x08; //INT1 的下降沿产生异步中断请求,INT0上升延
· GICR = 0xC0; //INT0和INT1使能
· TIMSK = 0x00; //timer interrupt sources
· SEI(); //re-enable interrupts
· //all peripherals are now initialized
· }
·
· void main(void)
· {
· init_devices();
· while(1) //死循环等待中断
· ;
· }
相关解释
1. #pragma interrupt_handler int0_isr:2
2. 中断的约定表示方法:int0_isr有一个与之对应的应用程序void int0_isr(void),2为中断向量,值越小,优先级越高,INT0的优先级仅次于复位。
3. MCU 控制寄存器- MCUCR MCU 控制寄存器包含中断触发控制位与通用MCU 功能
4. 通用中断控制寄存器- GICR 使能或禁用外部中断请求
使用过程中:为了降低干扰,中断引脚请加上一个4.7K的上拉电阻,还可以根据实际需要,加上电容滤波,防抖动。
更详细的内容,AVR外部中断,时钟中断,串行通信,IIC综合实例
//此程序为AVR外部中断,时钟中断,串行通信,IIC综合实例
#include <iom16v.h>
#include <macros.h>
#define uchar unsigned char
#define uint unsigned int
#pragma interrupt_handler int2:19//外部中断2
#pragma interrupt_handler timer0_ovf_isr:10//时钟中断
#pragma interrupt_handler rec:12//串口接收中断
void delay(uint ticks);//延时
unsigned char const Tab[]={0x14,0x9F,0x38,0x1A,0x93,0x52,0x50,0x1F,
0x10,0x12,0x11,0xD0,0x74,0x98,0x70,0x71};
//数码管显示代码
unsigned int count=0;//软件记数
void main()
{
uchar Address,date;
int x=0,j=0;
init_devices();
//中断设置
CLI();//关总中断
//INT2设置
MCUCSR&=~0x40;//下降沿触发
GIFR|=0x20;//清INT2标志
GICR|=0x20;//开INT2中断
//定时设置
TCCR0 = 0x00; //stop
TCNT0 = 0x83; //set count
OCR0 = 0x7D; //set compare
//TCCR0 = 0x03; //start timer
TIMSK = 0x01; //timer interrupt sources
//串口设置,波特率:9600
UCSRB = 0x00; //disable while setting baud rate
UCSRA = 0x00;
UCSRC = BIT(URSEL) | 0x06;
UBRRL = 0x33; //set baud rate lo
UBRRH = 0x00; //set baud rate hi
//UCSRB = 0x08;
UCSRB = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN);
SEI();//开总中断
PORTA=0x80;
PORTC=Tab[8];
//DS3231每秒产生一个中断:
WriteDs3231_OneByte(0x0e,0x07);
WriteDs3231_OneByte(7,0x80);WriteDs3231_OneByte(8,0x80);
WriteDs3231_OneByte(9,0x80);WriteDs3231_OneByte(10,0x81);
/*
while(1)
{//读出并显示:
date=ReadDs3231_OneByte(j++);//读取数据
if(j==7)j=0;//循环读出00-06地址的数据:秒、分、时、星期、日期、月和年信息
for(x=0;x<200;x++)
{
PORTA=0x80;
PORTC=Tab[date&0x0f];//显示个位
delay(50);
PORTA=0x40;
PORTC=Tab[date>>4];//显示十位
delay(50);
}
PORTA=0;//关闭显示
delay(5000);
}*/
}
void delay(uint ticks)
{
uchar i;
while(ticks--)for(i=100;i!=0;i--);//约0.1mS
}
void int2()//外部中断服务程序
{
CLI();
PORTC=Tab[ReadDs3231_OneByte(0)&0x0f];
SEI();
}
void timer0_ovf_isr(void)//定时中断服务程序
{
unsigned char data;
TCNT0 = 0x83; //reload counter value
if(++count==3000)//1000个1mS等于1秒
{
count=0;
data=ReadDs3231_OneByte(0)&0x0f;
PORTC=Tab[data];
printf("%dn",data);
}
}
void rec()//接收中断服务程序
{
unsigned char data;
data=UDR;
PORTC=data;
}
展开阅读全文