/* program name : 外部中斷程序;
這費了我好幾個小時的心血!成功的喜悅難以用言語表達!
概述:
8位流水非精確定時,一秒循環燈閃爍,等待外部中斷一下降沿中斷觸發信號,
外部中斷一旦觸發,等待觸發按鍵彈起(此時流水燈暫停狀態),中斷按鍵一旦彈
起,繼續運行上一級程序(流水燈繼續運行);
accomplish time : 2014-2-7 22:47:15;
*/
#include <avr/io.h>
#include <avr/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<<3); //INT1引腳設為輸入狀態;
PORTD=0XFF; //INT1引腳內部有上拉,其他引腳輸出1;
}
void delay()
{
uint16 u=0 ;
uint8 s=0;
for(s=0;s<200;s++)
{
for(u=0;u<50000;u++); //5毫秒左右;
}
}
void buzz()
{
uint16 s=0;
uint8 i=0;
PORTC|=0X80;
for(i=0;i<10;i++)
{
for(s=0;s<50000;s++);
}
PORTC&=~0X80;
}
int main(void)
{
init_io(); //初始化io口;
//* 1. 先設置好由那個引腳來觸發外部中斷, 和觸發方式;
// MCUCR 是中斷觸發模式控制寄存器;
MCUCR|=1<<3; //ISC11 被置一,其他位全部是零,代表 INT1 (外部中斷1)下降沿產生異步中斷;
//一旦 INT1 被拉低,就會進入中斷子程序;
//* 2. 開啟中斷使能位;
GICR |=0X80; // GICR是中斷使能寄存器,最高位被置一,表示外部INT1中斷使能
// (在MCUCR寄存器中,INT1被設置為下降沿異步中斷觸發方式);
sei();//全局中斷使能函數.沒有此函數,中斷將無法執行.(我不知道為什么!或許是甲魚的屁股--規定!)
while(1)
{
PORTB|=1<<2; //使能流水燈,此時PA口為全零(流水燈全亮);
delay(); //非精確延時1秒左右;
PORTB&=~(1<<2); //關閉流水燈;
delay(); //非精確延時1秒左右;
}
}
//==================中斷服務子程序=============================
SIGNAL(SIG_INTERRUPT1) //外部中斷INT1 中斷服務子程序函數(中斷一旦被觸發,cpu將會進入此函數);
{
buzz();
while((PIND&(1<<3))==0);
}