您好,欢迎来到易妖游戏网。
搜索
您的当前位置:首页此程序为AVR外部中断

此程序为AVR外部中断

来源:易妖游戏网


//此程序为AVR外部中断,时钟中断,串行通信,IIC综合实例

#include

#include

#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<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\

}

}

void rec()//接收中断服务程序

{

unsigned char data;

data=UDR;

PORTC=data;

}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

将生成的程序进行修改,DDRA = 0x01;PORTD = 0x0C; ,添加MAIN函数,如下

• //ICC-AVR application builder : 2006-12-8 17:04:44

• // Target : M16

• // Crystal: 7.3728Mhz

• #include

• #include

• 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综合实例 一个中断示例程序[txt] 外部中断计数 现在要实现一个外部中断计数的程序:

INT1为外部中断(PD3)。

PD3输入方波信号,每输入一个方波信号,即上升沿触发中断。

触发中断后,number加一。

在数码管上显示number。

我目前的程序的效果是数码管一直显示零,请大家帮忙看看

unsigned long Step;

#pragma interrupt_handler int1_isr:3

void int1_isr(void)

{

number++;

}

void LED_display(unsigned long number);

{

……

}

void main(void)

{

number=0;

DDRD&=0xf7; //INT1(PD3)输入

TIMSK|=0x04; //使能INT1

MCUCR=0x0c; //上升沿触发MCUCR=0x0c; GICR=0x80; for(;;)

{

SEI();

LED_display(number);

}

//使能INT1

}

2007-3-21 11:17:00

AVR单片机初学者免费辅导学习,欢迎初学者参加,欢迎高手加入。

tonghe

等级:版主

威望:6

文章:408

积分:2499

门派:专业人员 注册:2007年1月4日 第 2 楼 这么一点程序,看不出来。 虽然已经老了,仍需活到老,学到老! 2007-3-21 11:47:00 AVR单片机初学者免费辅导学习,欢迎初学者参加,欢迎高手加入。

shinea8868

等级:版主

威望:5

文章:294

积分:2309

门派:专业人员

注册:2006年11月21日

第 3 楼

把LED显示部分也帖出来吧,大家好帮你分析下 做方一点,做事细心一点 自己能做的事情,不要期望别人帮你做 自己暂时不能做的事情,不要认为自己没有能力去做而不去做. 所有的成绩,都是自己努力的结果 2007-3-21 12:14:00 AVR单片机初学者免费辅导学习,欢迎初学者参加,欢迎高手加入。 AVR_AFA

等级:小飞侠 文章:1554 积分:8792 门派:专业人员 注册:2006年9月11日 第 4 楼

回复:(dudubeibei)外部中断计数

把number这样声明一下看看:

volatile unsigned char number;

volatile 关键词的说明请参照这个帖子:volatile关键字说明。

2007-3-21 13:15:00

AVR单片机初学者免费辅导学习,欢迎初学者参加,欢迎高手加入。

dudubeibei

等级:新手上路

文章:40 积分:485 门派:无门无派 注册:2006年12月9日 第 5 楼 认真看了看M16L的datasheet,终于找到了错误。重要是M16和8515的不同。 相应的控制寄存器误按8515的来写造成的。因为手上有本清华大学的《AVR单片机C语言开发入门指导》 ,这本书上都是以8515为例来编写的。 因为我的懒惰,自以为和M16都是一样的,就按着上面的来,事实证明8515和M16在中断控制上面有很多不同。

比如中断向量就不同。

在这个程序里面,对相应的中断寄存器进行初始话应该用这两个语句:

MCUCR=0x0c; //上升沿触发

GICR=0x80; //使能INT1

通过这次的错误让我再次感受到仔细阅读枯燥的datasheet的重要性

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- vipyiyao.com 版权所有 湘ICP备2023022495号-8

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务