#pragma interrupt_handler 函数名:中断向量
要注意不同的AVR芯片的中断向量是不同的,因此在ICCAVR下编译,除了要在程序上注明芯片的类型外,还要在PROJECT的OPTION页选择正确的芯片,否则有可能导致程序运行不正常;而GCC只要在MFILE里面选定芯片型号就可以,GCC在这点上的使用比ICCAVR的方便。
附:定时器1溢出中断例子,每溢出一次就令i自加1,然后在LCD1602上显示出来
------------------------------------------------------------------------------------------------
#include
#include
#pragma interrupt_handler ANA_COMP:10 //定时器1溢出中断
#define uchar unsigned char
#define uint unsigned int
#define LcdBus PORTA
#define rs 2 //LCD端口定义
#define rw 3
#define en 4
void LcdIni(void);
void WrOp(uchar dat);
void WrDat(uchar dat);
void ChkBusy(void);
void DisText(uchar addr,uchar *text);
void DisTextConst(uchar addr,uchar const *text);
void ShowNum(uchar addr,uint num); //在addr处显示数字num
int AdcVal(uchar n);
void delayms(uint n);
int AdcValPro(uchar n);
void ANA_COMP(void);
char BCD[6]; //十位二进制的显示码分别是千百十个位的显示
int Adc[3]; //存放Adc转换后的值
int i=0;
void main(void)
{
LcdIni();
TIMSK=0X04;
TCNT1H=0XFF;
TCNT1L=0X00;
TCCR1A=0X00;
TCCR1B=0X01;
SEI(); //允许全局中断
while(1);
}
void ANA_COMP(void)
{//中断处理程序,溢出时就令i增加1
TCNT1H=0XFF;
TCNT1L=0X00;
ShowNum(0x82,i++);
}
int AdcVal(uchar n)
{//软件滤波
uchar i,k;
uint tmp=0;
for(i=0;i<20;i++)
tmp=(tmp+AdcValPro(n))/2;
k=tmp>Adc[n] ? (tmp-Adc[n]):(Adc[n]-tmp);
Adc[n]=k>0 ? tmp:Adc[n];
return Adc[n];
}
int AdcValPro(uchar n)
{//返回第N个ADC的值从0到7
uchar dat1,dat0;
int val;
DDRA &=~BIT(n); //设置对应的ADC口为输入
PORTA &=~BIT(n);
ADMUX=0x40+n; //选择AVCC,选择第N个ADC
ADCSRA=0xc0; //允许转换ADEN,ADSC
while(ADCSRA & BIT(ADSC)); //
dat1=ADCH;
dat0=ADCL;
val=ADCH*256+ADCL;
return val;
}
void ShowNum(uchar addr,uint num) //在addr处显示数字num
{//将num转化成五个BCD码存放在全局数组BCD[5]中
uchar i;
for(i=5;i>0;i--) //将NUM数据转化成ASCII码,如521会转化为00521
{
BCD[i-1]=(uchar)(num%10+0x30); //取出最低位
num/=10; //去掉最低位
}
i=0;
while(BCD[i] ==0x30 && i<4) BCD[i++]=' '; //NUM转换成数组存放,但还没有加上小数点
BCD[5]='\0';
DisText(addr,BCD+1);
}
void DisText(uchar addr,uchar *p)
{
WrOp(addr);
while(*p !='\0')WrDat(*(p++));
}
void DisTextConst(uchar addr,uchar const *p)
{
WrOp(addr);
while(*p !='\0')WrDat(*(p++));
}
void LcdIni()
{
uint i;
DDRD=0XFF; //设置PA输出
PORTD=0XFF; //全部加上上拉电阻
DDRC=0XFF; //设置PC为输出
PORTC=0XFF; //全部加上上拉电阻
WrOp(0x38);
WrOp(0x06); //光标加1
WrOp(0x0c); //开显示
WrOp(0x01);
for(i=0;i<5000;i++);
}
void WrOp(uchar dat)
{
uchar i;
ChkBusy();
PORTD &=~BIT(rs); //RS=0
PORTD &=~BIT(rw); //RW=0
PORTD &=~BIT(en); //EN=0
PORTC =dat; //送数据
PORTD |=BIT(en); //EN=1
for(i=1;i;i++); //延时
PORTD &=~BIT(en); //EN=0
}
void WrDat(uchar dat)
{
uchar i;
ChkBusy();
PORTD |=BIT(rs); //rs=1
PORTD &=~BIT(rw); //rw=0
PORTD &=~BIT(en); //en=0
PORTC=dat; //送数据
PORTD |=BIT(en); //en=1
for(i=1;i;i++); //延时
PORTD &=~BIT(en); //en=0
}
void ChkBusy()
{
DDRC=0X00; //设置为输入
PORTC=0X00; //不设置上拉电阻
PORTD &=~BIT(rs); //RS=0
PORTD |=BIT(rw); //RW=1
PORTD |=BIT(en); //EN=1
while(PINC & 0x80); //送数据
PORTD &=~BIT(en); //en=0
DDRC=0xff; //设置为输出
}
void delayms(uint n)
{
uchar j;
uint i;
for(i=0;i
}
上一篇:基于AVR ATMega16 的PID 控制算法程序
下一篇:AVR的中断应用设计要点
推荐阅读最新更新时间:2024-03-16 15:10