AVR单片机WinAVR及Proteus仿真外部中断
单片机原理外部中断实验
单片机原理实验报告实验题目外部中断实验一、实验目的1.掌握用外部中断方式实现控制的方法。
2.掌握中断优先级的使用方法。
3. 掌握用Proteus实现单片机系统仿真的方法。
二、实验预备知识外部中断信号由P3.2(P3.3)管脚输入,当中断触发方式控制位ITO(IT1)为1时,CPU 在每个机器周期的S5P2采样P3.2(P3.3)管脚,如果连续两次采样,前一次采样为高电平,后一次采样为低电平,则认为有中断申请,随即使中断标志位IE0(IE1)置1,向CPU申请中断,直到该中断被CPU响应。
当定时器以计数方式工作,计数初值为满量程,在计数输入端T0(T1)输入负跳变信号时,计数器将加1并产生溢出,随即使溢出标志位TF0(TF1)置1,向CPU申请中断,直到该中断被CPU响应。
三、实验内容P1口做输出口,接八只发光二极管,利用手控单脉冲信号作为外部中断信号,编写控制程序,使八只发光二极管按一定的规律循环点亮。
1.程序1: 从外部中断0请求输入端(P3.2)输入脉冲信号2.程序2: 从定时器0的外部输入端(P3.4)输入脉冲信号四、实验参考电路P1口接发光二极管的阴极,P1口的管脚输出低电平时对应的发光二极管点亮,实验电路图如图4-1所示。
图4-1 外部中断实验电路五、实验参考程序ORG 0003HAJMP INT00 ORG 0013H AJMP INT11 ORG 0050H MAIN:SETB EASETB EX0SETB EX1SETB PX1SETB IT0SETB IT1MOV A,#0FEH LP1:MOV P1,ALCALL DELAY RL ASJMP LP1ORG 0100H INT00:PUSH ACCMOV A,#0FCH MOV R1,#7 LP2:MOV P1,A LCALL DELAY RL ADJNZ R1,LP2 POP ACCRETIORG 0150H INT11:PUSH ACCMOV A,#3FH MOV R2,#7 LP3:MOV P1,ALCALL DELAY RR ADJNZ R2,LP3 POP ACCRETIORG 0200H DELAY:MOV R3,#20 L1:MOV R7,#200 L2:MOV R6,#123 NOPL3:DJNZ R6,L3 DJNZ R7,L2 DJNZ R3,L1 RETEND六、实验分析与总结。
单片机实验之外部中断应用实验
一、实验目的1、掌握中断系统外部中断源的使用方法。
2、掌握延时程序的编程及使用方法。
3、掌握Proteus软件与Keil软件的使用方法。
4、掌握单片机系统的硬件和软件设计方法。
二、设计要求1、用Proteus软件画出电路原理图,在单片机的P1.0口线上接按键K0 ,作为外部中断源0使用,用于开启波形,在单片机的 P1.1口线上接按键K1,作为外部中断源1使用,用于关闭波形。
2、在单片机的P1.2口线上产生周期50mS的连续方波,在P1.2口线上接示波器观察波形。
三、电路原理图六、实验总结通过本实验能够准确安排各种类型的中断服务程序入口,中断源提出中断申请后,却执行到相应的中断服务程序。
弄清楚了中断服务程序与子程序的共同点和不同点。
七、思考题1、在P1.2口线上产生周期为100mS,占空比为2:5的连续矩形波,要求只采用按键K0来控制其开启和关闭。
答:程序见程序清单。
四、实验程序流程框图和程序清单。
1、在单片机的P1.2口线上产生周期50mS的连续方波。
P1.0口线上接按键K0 ,作为外部中断源0使用,用于开启波形, P1.1口线上接按键K1,作为外部中断源1使用,用于关闭波形。
汇编程序:ORG 0000H START: LJMP MAINORG 0003HLJMP EXT0ORG 000BHLJMP TTCOORG 0013HLJMP EXT1ORG 0100HMAIN: MOV TMOD, #01HMOV TCON, #01HMOV IE, #87HMOV TH0, #9EHMOV TL0, #58HSETB PX1HERE: LJMP HEREEXT0: SETB TR0RETIEXT1: CLR TR0RETITTCO: CPL P1.2MOV TH0, #9EHMOV TL0, #58HRETIENDC语言程序:#include<reg51.h>sbit P12=P1^2;main(){TMOD=0X01;EA=1;EX0=1;EX1=1;ET0=1;PX1=1;TCON=0X01;TH0=0X9E;TL0=0X58;while(1);}void EXT0() interrupt 0{ TR0=1;}void EXT1() interrupt 2{ TR0=0;}void TTC0() interrupt 1{ P12=!P12; TH0=0X9E;TL0=0X58;}2、在P1.2口线上产生周期为100mS,占空比为2:5的连续矩形波,要求只采用按键K0来控制其开启和关闭。
单片机实验:外部中断按键
单⽚机实验:外部中断按键实验内容:实验⼤致上就是说:按键不按的时候,灯⼀直亮,按键按下的时候,灯不亮,报警器响。
现在给了汇编语⾔,要改成c语⾔,并在proteus⾥⾯仿真。
思考与总结:响应中断请求的条件:1.总中断允许开关EA=1。
2.中断源的中断允许位为1。
3.中断源发出中断请求。
4.⽆同级或更⾼级中断正在被服务。
结合实验,就知道,这⾥跑到中断⼦程序的条件,⾸先总开关打开。
然后选择中断请求源,对这个实验来说,也就是选择I N T 0 ‾\overline{INT0}INT0外部中断请求0,它的中断允许控制位是E X 0 EX0EX0,我们置1后,就说明允许了外部中断0中断。
我们如果选⽤跳沿触发,⼀个机器周期采样到外部中断输⼊为⾼,下⼀个为低,那么中断请求触发器置⼀,这个时候进⼊中断⼦程序。
这个实验是电平触发。
cpu查询到中断请求时,就会进⾏中断响应(这⾥假设只是单⼀中断,如果有不同优先级的中断,那么cpu还要进⾏判断)。
硬件⽣成⼀个长调⽤指令并执⾏,程序转向中断⼊⼝地址,两个中断⼊⼝相隔8字节,难以放下中断⼦程序,此时需要⼀个跳转指令,转向在其他地址下的⼦程序中。
实验结果:汇编语⾔实现:ORG 0000hLJMP MAIN//主程序ORG 0003hLJMP INT0s//中断⼊⼝ORG 0100hMAIN: CLR IT0//外部中断请求0为电平触发SETB EA//总中断允许SETB EX0 //允许外部中断0LOOP: CLR P0.0//p0.0是低电平,此时灯亮SETB P2.3//p2.3是⾼电平,此时警报不响SJMP LOOP//短转移指令,程序跳到loop函数循环ORG 0200h//伪指令INT0s: SETB P0.0//p0.0是⾼电平,此时灯灭CLR P2.3//p2.3是低电平,此时警报响Delay: MOV R0,#200//延时函数D1: MOV R1,#254D2: DJNZ R1,D2DJNZ R0,D1RETIEND改成c51语⾔:#include<reg51.h>#define uchar unsigned charsbit key = P3^2;void delay(unsigned int i)//延时函数{unsigned int j;for(;i>0;i--)for(j=0;j<333;j++){}}void main()//主函数{EA=1;//总中断允许EX0=1;//允许外部中断0IT0=0;//选择外部中断0为电平触发⽅式while(1)//循环{P0=0xfe;}//P0.0⼝的Led亮}void key_scan() interrupt 0//外部中断0的中断服务函数{if(key==0)//判断是否有按键按下{delay(10);//延时去抖if(key==0){P2=0xf7;P0=0xff;while(!key);//等待按键松开P2=0xff;P0=0xfe; }}}proteus仿真:。
AVR单片机外部中断C程序框架
AVR单片机外部中断C程序框架
Avrmega16a
单片机在studio4开发环境中外部中断C程序框架如下:
#include;
//头文件.
#include;
//中断头文件;
typedefunsignedcharuint8;
//习惯宏定义数据类型语法.应用时只需写入数据类型:
//
uint8s=0;
typedefunsignedintuint16;
//习惯宏定义数据类型语法.应用时只需写入数据类型:
//
uint16
i=0;
Intmain()
//主函数;
{
MCUCR=0Xnn:
//中断模式触发寄存器,用来设置外部中断引脚的触发方式,上升沿,下降
//沿,还是高电平或低电平方式;
GICR=0Xnn;
//局部中断使能,用来使能某个中断源.
Sei();
//全局中断使能,用来开启中断服务(中断总使能); //在此写入程序语句;
//
//如果外部中断源一旦被触发,程序就会立即执行中断服务函数;
}
//此↓‘n’是外部中断源序号有中断0,中断1,中断2.
SIGANL(SIG_INTRRUPTn)
//终端服务函数;
{
//在中断函数中,不能定义局部数据类型变量;
//在此写入中断程序;
}。
多个外部中断——ARM的Proteus实验
多个外部中断——ARM的Proteus实验实验原理ARM开启两个中断源Eint1与Eint2,分别用一个按钮来控制。
在没有中断的时候两个LED都缓慢闪烁,当任何一个中断被出发的时候,对应的LED会急促闪烁,逐渐回复正常。
Proteus仿真电路图C语言源程序#include <LPC21XX.H>#define LED1 0x02000000/*LED1接在P0.25上*/#define LED0 0x01000000/*LED0接在P0.24上*/typedef unsigned int uint32;void Eint1_ISR(void) __attribute__ ((interrupt));/*声明某函数为中断服务子程序的方法*/void Eint0_ISR(void) __attribute__ ((interrupt));uint32 times = 40;/*循环次数默认为40*/void delay40(void) {unsigned volatile long i,j;for(i=0;i<10000;i++)for(j=0;j<times;j++);if(times > 40){times-=2;}else if(times <40){times+=2;}}void Eint0_ISR(void){times = 0;while(times!=40){IO0CLR = LED0;delay40();IO0SET = LED0;delay40();}while((EXTINT&0x01)!=0){EXTINT=0x01;/*清除EINT0中断标志*/}VICVectAddr=0x00;}void Eint1_ISR(void){times = 0;while(times!=40){IO0CLR = LED1;delay40();IO0SET = LED1;delay40();}while((EXTINT&0x02)!=0){EXTINT=0x02;/*清除EINT1中断标志*/}VICVectAddr=0;}int main(void){IO0DIR = LED1|LED0;PINSEL0 = 0x20000000;/*引脚选中EINT1功能*/PINSEL1 = 0x00000001;/*引脚选中EINT0功能*//*以下为中断控制部分*/VICIntSelect=0;/*全部中断设置为IRQ,若某位为1是FIQ*/VICIntEnable=0x0000C000;/*使能EINT1、0,EINT1为第15位,0为14位*/VICVectCntl0=0x2E;/*EINT0最高优先级*/VICVectAddr0=(int)Eint0_ISR;/*设置EINT0向量地址*/VICVectCntl1=0x2F;/*0xF,15号中断*/VICVectAddr1=(int)Eint1_ISR;/*设置中断服务子程序*/EXTINT=0x07;while (1) {/*无中断时,两灯一起缓慢闪烁*/IO0CLR = LED1|LED0;delay40();IO0SET = LED1|LED0;delay40();}}。
单片机外部中断实训报告
一、实训目的1. 理解单片机外部中断的概念和作用。
2. 掌握单片机外部中断的配置方法。
3. 学会编写外部中断服务程序。
4. 通过实际操作,提高单片机编程和调试能力。
二、实训内容1. 单片机外部中断原理2. 单片机外部中断配置3. 外部中断服务程序编写4. 实验验证与调试三、实训环境1. 单片机开发板:选用STC89C52单片机。
2. 仿真软件:Proteus。
3. 实验工具:示波器、电源、连接线等。
四、实训步骤1. 理解单片机外部中断原理外部中断是单片机中断系统中的一种,用于响应外部事件。
当外部事件发生时,单片机会暂停当前程序,转去执行外部中断服务程序。
外部中断有多个中断源,如INT0、INT1等。
2. 单片机外部中断配置(1)设置外部中断触发方式:根据需要选择上升沿触发、下降沿触发或双边沿触发。
(2)设置外部中断优先级:根据实际需求设置中断优先级。
(3)设置外部中断使能:通过设置IE寄存器使能外部中断。
3. 外部中断服务程序编写编写外部中断服务程序,用于处理外部中断事件。
在服务程序中,完成相关处理逻辑,如记录外部事件发生次数、控制LED灯闪烁等。
4. 实验验证与调试(1)搭建实验电路:将单片机开发板与外部设备(如按钮)连接,设置好外部中断配置。
(2)在Proteus中搭建仿真电路,编写代码。
(3)下载代码到单片机开发板,观察实验现象。
(4)根据实验现象,调试程序,确保外部中断功能正常。
五、实验结果与分析1. 实验现象:按下外部按钮,单片机进入外部中断服务程序,控制LED灯闪烁。
2. 分析:通过设置外部中断触发方式、优先级和使能,成功实现外部中断功能。
在服务程序中,完成相关处理逻辑,达到预期效果。
六、实训总结1. 通过本次实训,掌握了单片机外部中断的配置方法,学会了编写外部中断服务程序。
2. 熟悉了外部中断在实际应用中的重要作用,提高了单片机编程和调试能力。
3. 在实训过程中,遇到了一些问题,如外部中断响应不及时、LED灯闪烁不稳定等。
AVRGCC-WinAVR编译环境中断函数的使用方法
AVRGCC/WinAVR编译环境中断函数的使用方法
早期版本的avr-libc 对中断服务程序的书写提供了两个宏SIGNAL 和INTERRUPT,并且需要包含两个头文件:avr/signal.h 和avr/interrupt.h。
新版(如2007 版WINAVR)中,INTERRUPT 宏不再可用,而建议用ISR 宏替代SIGNAL 宏,ISR 和SIGNAL 是一回事,但以后的版本中SIGNAL 宏将会逐渐被丢弃,所以新的程序建议使用ISR,也就是使用ISR 作为中断服务函数名,下面将举例说明一些具体的中断使用。
一.为什么没有了INTERRUPT?
INTERRUPT 宏是各中断嵌套有关的,当中断程序得到执行时AVR 的硬件将全局的中断允许标记清除,其它中断无法再发生,当中断程序退出时自动被
允许。
而INTERRUPT 宏让编译器所做的就是在中断程序的入口处插入一个
SEI 指令,退出处插入一个CLI 指令,使得中断可以嵌套,也许这对于普通的程序意义不大,INTERRUPT 才被去掉的。
然而仍然可以使用下面的方式实现INTERRUPT 宏的功能:
void XXX_vect(void) __attribute__((interrupt));
void XXX_vect(void)
{
//程序
}
即上面方式定义的中断程序可以再次被中断,XXX_vect 是中断例程名字,下面将说明。
二.可使用第二套中断名
早期版本的avr-libc 中中断例程名为SIG_开头,从avr-libc 1.4.0 版开始第二。
AVR学习笔记二、基本输入和外部中断实验
A VR学习笔记二、基本输入和外部中断实验-------基于LT_Mini_M162.1 利用按键控制发光二极管的亮灭2.1.1 实例功能在“点亮发光二极管”和“让发光二极管动起来”这两个例子中,都是通过单片机程序来控制发光二极管的亮灭。
如果想要控制发光二极管的亮灭,只有通过打开或者关闭电源来实现控制。
那么怎样实现人工参与控制呢?在有些应用场合,需要单片机对人工的开关信号作出相应的响应和处理,通过控制电源的通断会影响到单片机系统中的其他功能,所以通过控制电源的方法并不明智。
能不能通过按动一个按键来实现发光二极管的亮灭呢?当然可以,前面已经讲过,A VR单片机的I/O口都是双向的,也就是既能当作输出控制端口,也能当作输入检测端口。
既然我们可以通过控制端口输出不同的高低电平使发光二极管实现点亮和熄灭;那么为什么不能通过监测端口输入电平的状态来进行相应的处理呢。
在本例中,通过介绍利用按键开关控制发光二极管的亮灭来了解A VR单片机的端口检测外部信号的功能和方法。
本例中有3个功能模块,描述如下:●单片机系统:检测外界的按键开关信号,根据按键的开关状态控制发光二极管的亮灭状态。
●外围电路:首先是产生信号的按键电路,包括对按键去抖动电路的介绍;然后是发光二极管的控制电路。
●软件程序:通过读取AVR单片机相应端口的状态,编写相应的程序控制发光二极管的亮灭。
本例的目的在于希望读者完成本例后,能完成相关电路的设计和相应程序的编写,从而掌握以下知识点:◆了解AVR单片机端口输入功能,掌握使用AVR单片机端口输入功能检测外部信号的原理。
◆熟悉单片机端口输入输出功能的综合使用。
◆掌握AVR单片机按键的硬件去抖动的电路设计和原理。
◆掌握AVR单片机端口输入输出程序的编写。
◆掌握AVR单片机按键软件去抖动功能的实现。
2.1.2 器件和原理本例主要介绍A VR单片机外围电路中按键去抖电路的设计,分别介绍相应的软件和硬件解决方案。
AVR单片机外部中断0、1、2详解
AVR单片机外部中断0、1、2 详解中断基本包含:1.中断源2.中断向量(中断入口地址)3.中断优先级4.中断函数除此之外,在单片机中,中断的执行或者中断的触发必须符合以下的规则:中断触发|执行= 全局中断使能位AND 中断源使能位AND 中断源标志位单片机内部中断的触发必须完成,全局中断使能,中断源使能,中断源标志位置一等条件。
除此之外,如果是外部中断0,1,2(INT0,1,2),必须设置引脚触发的规则。
最后呢,就是需要在程序里建立处理中断的中断函数。
在编程的时候的步骤大致如下:(无视INT2)1. 初始化PD2,PD3 为输入状态。
DDRD|=BIT(2)|BIT(3);2. 设置INT0,1 引脚触发的规则,实验中为低电平触发。
MCUCR=0xF0;3. 设置INT0,1 中断源使能位为逻辑1。
GICR|BIT(7)|BIT(6);4. 清除INT0,1 的中断标志位(软件写入,逻辑1 为清除)。
GIFR|=BIT(7);BIT(6);5. 全局中断允许位使能。
SREG|=BIT(7);6. 编辑中断处理函数。
/*ATmega16提供3个外部中断,分别由INT0、INT1和INT2引脚触发。
需要注意的是,如果将ATmega16设置为允许外部中断,则即使把INT0、INT1和INT2引脚设置为输出方式,外部中断仍然会被触发。
外部中断可选择采用上升沿触发、下降沿触发和低电平触发(INT2中断只能采用沿触发方式。
*/#include;#include;#include "smg.h"/*1.状态寄存器SREGbit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0I T H S V N Z CI:全局中断使能位。
在I置位后,单独的中断使能由不同的中断寄存器控制。
若I为0,则禁止中断。
MCU 控制寄存器- MCUCR MCU 控制寄存器包含中断触发控制位与通用 MCU 功能Bit 7 6 5 4 3 2 1 0SM2 SE SM1 SM0 ISC11 ISC10 ISC01 ISC00外部中断 1 由引脚 INT1 激发,如果 SREG 寄存器的 I 标志位和相应的中断屏蔽位置位的话。
WINAVR 中断
AVRGCC/WinAVR编译环境中断函数的使用方法早期版本的avr-libc 对中断服务程序的书写提供了两个宏SIGNAL 和INTERRUPT,并且需要包含两个头文件:avr/signal.h 和avr/interrupt.h。
新版(如2007 版WINAVR)中,INTERRUPT 宏不再可用,而建议用ISR 宏替代SIGNAL宏,ISR 和SIGNAL 是一回事,但以后的版本中SIGNAL 宏将会逐渐被丢弃,所以新的程序建议使用ISR,也就是使用ISR作为中断服务函数名,下面将举例说明一些具体的中断使用。
一.为什么没有了INTERRUPT?INTERRUPT 宏是各中断嵌套有关的,当中断程序得到执行时AVR 的硬件将全局的中断允许标记清除,其它中断无法再发生,当中断程序退出时自动被允许。
而INTERRUPT宏让编译器所做的就是在中断程序的入口处插入一个SEI 指令,退出处插入一个CLI 指令,使得中断可以嵌套,也许这对于普通的程序意义不大,INTERRUPT 才被去掉的。
然而仍然可以使用下面的方式实现INTERRUPT 宏的功能:void XXX_vect(void) __attribute__((interrupt));void XXX_vect(void){//程序}即上面方式定义的中断程序可以再次被中断,XXX_vect 是中断例程名字,下面将说明。
二.可使用第二套中断名早期版本的avr-libc 中中断例程名为SIG_开头,从avr-libc 1.4.0 版开始第二套中断名称,它以_vect 为后缀。
因为在器件手册里用比如用TIMER2 COMP表示定时器2比较匹配中断,新的方法更接近手册,称可查libc 手册或器件对应io.h 文件。
三.用户未定义中断的截获下如书中所说早期版本中用户未定义服务程序的中断发生时系统就会复位,而新版本可以截获这种中断了,使用如下:#include <avr/interrupt.h>ISR(BADISR_vect){ //服务程序}这个服务程序是可选的,并不是强制用户处理未定义中断,如果不定义那结果就是产生未定义中断时复位。
此程序为AVR外部中断
//此程序为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; //stopTCNT0 = 0x83; //set countOCR0 = 0x7D; //set compare//TCCR0 = 0x03; //start timerTIMSK = 0x01; //timer interrupt sources//串口设置,波特率:9600UCSRB = 0x00; //disable while setting baud rateUCSRA = 0x00;UCSRC = BIT(URSEL) | 0x06;UBRRL = 0x33; //set baud rate loUBRRH = 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 valueif(++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;}//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////将生成的程序进行修改,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:22. 中断的约定表示方法:int0_isr有一个与之对应的应用程序void int0_isr(void),2为中断向量,值越小,优先级越高,INT0的优先级仅次于复位。
单片机外部中断讲解
单片机外部中断讲解在单片机的世界里,外部中断就像是一位“紧急事务专员”,能够在关键时刻打断单片机正在进行的工作,让其优先处理更为重要和紧急的任务。
这一特性使得单片机在应对复杂多变的外部环境时变得更加灵活和高效。
首先,咱们来理解一下什么是外部中断。
简单来说,外部中断就是单片机从外部接收的一种信号,这个信号告诉单片机:“嘿,有重要的事情发生啦,你得马上停下来处理!”这个信号可以来自各种各样的外部设备,比如按键、传感器等等。
那么,单片机是如何感知到这些外部中断信号的呢?这就涉及到单片机的引脚配置。
通常,单片机都会有专门的引脚用于接收外部中断信号。
当外部设备产生中断信号并通过这些引脚输入到单片机时,单片机会立即响应。
外部中断有它自己的触发方式,常见的有边沿触发和电平触发。
边沿触发就像是一个瞬间的“脉冲”,可以是上升沿触发(也就是从低电平变为高电平的那一瞬间),也可以是下降沿触发(从高电平变为低电平的瞬间)。
而电平触发呢,则是根据引脚的高电平或者低电平状态来触发中断。
比如说,设置为高电平触发,那么只要引脚保持高电平,就会一直触发中断。
为了更好地管理外部中断,单片机一般都会有相应的中断控制寄存器。
通过对这些寄存器的配置,我们可以决定是否允许某个外部中断、选择触发方式、设置中断的优先级等等。
接下来,咱们说说外部中断的优先级。
想象一下,如果同时有多个外部中断信号来了,单片机该先处理谁呢?这就需要靠优先级来决定。
优先级高的中断会先得到处理,处理完后再去处理优先级低的中断。
在实际编程中,使用外部中断需要经过一系列的步骤。
首先,要对单片机进行初始化,包括设置中断相关的寄存器。
然后,编写中断服务函数。
这个函数就是单片机在响应中断后要执行的具体任务。
比如说,我们有一个基于单片机的温度监测系统,使用了一个温度传感器。
当温度超过设定的阈值时,传感器会给单片机发送一个外部中断信号。
在中断服务函数里,单片机可能会执行报警操作,比如点亮一个指示灯或者发出声音警报。
avr外部中断详细讲解
另外 ISC01,ISC00 和外部中断 0 设置触发方式有关:
ISC01 0 0 1 1 ISC00 0 1 0 1 说明 INT0 低电平触发中断 INT0 任意逻辑电平变化都触发中断 INT0 的下降沿产生异步中断请求 INT0 的上升沿产生异步中断请求
{ DDRB=0XFF; PORTB=0XFF; DDRD=0XF7; PORTD=0XFF;
//将 PB 口设置为输出 //PB 口输出 11111111,熄灭全部灯 //PD3 设置为输入,其余设置输出 //PD3 使能上拉电阻,其余都输出 1
MCUCR=0X08; //INT1 设置为下降沿触发 GICR=0X80; //使能 INT1 中断 SREG=0X80; //使能总中断 while(1) { PORTB=0X00; delay(100); PORTB=0XFF; delay(100); } }
MCUCR 是 MCU 控制寄存器,在中文版数据手册中 P65:
在这里我们只要关心它的 Bit 0-3,这四位跟外部中断才有关系。 对于上面的表格 Read/Write 代表可读可写,Initial Value 表示初始值,上面表示 默认值都为零。 其中 ISC11,ISC10 和外部中断 1 设置触发方式有关:
第 4 章 轻松掌握外部中断
4.1 什么是外部中断
“中断”这个词来自英文单词“interrupt” ,在单片机中中断的设置,大大提 高了单片机的工作能力。 对于中断的学习是单片机学习中的重点难点,只要掌握了中断,操纵单片机 让它做你想要实现复杂过程就容易多了。 从生活例子来看, 假如说在寝室里只有你一个人, 这个时候你在写一份作业, 写到一半,有人敲门,这时候,你放下笔,走过去开门,是隔壁寝室的同学来还 书,你收下书后,关上门,拿起笔继续写作业。这其中对于你写作业这个事情来 说就是发生了一次中断,而你能够处理这次“开门事件” ,就说明了你有“中断 能力” 。 反过来说,假如你没有中断能力,事情会这样发生:门外有人敲门的时候, 你的作业还没有写完, 你还是继续在写你的作业, 你甚至不知道外面有人在敲门, 于是便漏过了这件事情。 对应于单片机,假如有一段很长的程序要执行,当按键按下的时候,单片机 在执行前面的程序, 按键松开的时候还没有执行到按键扫描程序,一会儿到了执 行按键扫描程序的时候,扫描的结果是按键会是没有按下,这就发生了错误。 假如开启了外部中断,像上面人一样,执行写作业的动作的时候,外面一有 人在敲门,人便立刻知道了,然后放下手中的事情去开门。单片机开启中断后, 一旦有按键按下,单片机便立刻感知,马上去执行按键按下对应的程序。这样便 不会漏过按键对应的命令,保证了程序正常执行。
avr外部中断
AVR单片机外部中断范例1. 开发语言本范例使用WinAVR/GCC 20050214 版本开发2. 范例描述按下按键0,LED0亮。
直到松手,其他按键才能起作用按下按键1,LED1亮。
其他按键随时都能起作用按下按键2,LED0/1都熄灭。
直到松手,其他按键才能起作用3. 电路图设计:为简化线路设计。
.4. 代码设计与说明:/********************************************* ******** AVR 外部中断使用范例************** 策划、整理与测试:阿莫(armok) ******* 代码设计:HJJourAVR ******* 编译器:WINAVR20050214 ******* 2005.8.31************************************************* ***//*本程序简单的示范了如何使用A TMEGA16的外部中断中断的设置按键的简单延时防抖动中断的嵌套变量在中断中的应用---如果变量会在中断服务程序中被修改,须加volatile限定本范例可直接使出厂状态的新M16芯片,无需对芯片的熔丝位进行配置。
出于简化程序考虑,各种数据没有对外输出,学习时建议使用JTAG ICE硬件仿真器关于外部中断作唤醒源的条件:(将会在后面的电源管理和睡眠模式范例中应用)而INT0和INT1的边沿触发中断只能在空闲模式起作用,即CLKI/O不停止INT0和INT1的低电平中断,INT2在各种睡眠模式下都可以,因为这几种中断工作于异步模式,不需要时钟驱动官方的M16中文手册对外部中断的描叙存在多处错误,请参考英文原版。
*/#include <avr/io.h>#include <avr/delay.h>#include <avr/signal.h>#include <avr/interrupt.h>/*宏INTERRUPT 的用法与SIGNAL 类似,区别在于SIGNAL 执行时全局中断触发位被清除、其他中断被禁止INTERRUPT 执行时全局中断触发位被置位、其他中断可嵌套执行另外avr-libc 提供两个API 函数用于置位和清零全局中断触发位,它们是经常用到的。
单片机avr中断寄存器中断c语言函数外部中断INT0,INT1,INT3介绍
单片机avr 中断寄存器中断c语言函数外部中断INT0,INT1,INT3 介绍
简介:中断的概念,ATmega16中断向量表,avr中断寄存器SREG,MCU控制和状态寄存器MCUCSR,通用中断控制寄存器GICR, MCU控制寄存器MCUCR,ICCAVR中断函数格式介绍
中断就是暂停正在执行的程序语句,转去执行另一功能(函数)的程序语句,执行完后,立即返回原先暂停执行的语句处,继续执行。
单片机的中断系统解决了单片机运算速度快,外设(如键盘)速度慢之间的数据传输问题,提高了单片机的实时性和数据处理能力。
中断源:产生中断的地方,ATmega16具有20个中断源和一个复位中断,不同的单片机中断源的个数是不一样的。
单片机的中断源分为外部中断源和内部中断源,有三个外部中断源有INT0,INT1,INT2,当连接在单片机引脚的上
的外部电平发生变化时,将产生相应的中断。
内部中断源由单片机内部的功能单元如定时器,串行通讯产生的中断。
按是否可屏蔽可分为,非屏蔽中断,和可屏蔽中断,非屏蔽中断有系统复位(reset)中断,可屏蔽中断:屏蔽指的的是中断可由软件编程控制是否允许中断,或禁止中断,大部分都是可屏蔽中断。
中断向量:单片
机的每个中断源都有一个固定的入口地址,这个地址由单片机的硬件决定的,单片机相应中断后,自动跳转到相应的地址,这个地址就叫中断矢量。
ATmega8-Protues仿真之四 外部中断学习
第四讲外部中断的学习提要:主要学习ATmega8的PD口的PD2、PD3两端口的第二功能外部中断。
前面我们学习了ATmega8的I/O口作为通用数字输入/输出口来用时对LED 数码管控制和扫描按键的应用。
但ATmega8多数的I/O口都是复用口,除了作为通用数字I/O使用,还有其第二功能,下面我们就先来学习PD2、PD3两端口的第二功能:4.1 外部中断的特点:PD2端口是外部中断源0,PD3端口是外部源1。
ATmega8的外部中断就是由这两个引脚触发的。
要注意的是:如果设置允许外部中断产生,即使是INT0和INT1引脚设置为输出方式,外部中断还是会触发的。
外部中断的触发方式有三种可选择:上升沿触发、下降沿触发和低电平触发。
具体方式是由MCU控制寄存器MCUCR以及MCU控制和状态寄存器MCUCSR决定的。
当允许外部中断且设置为电平触发方式时,只有中断输入引脚保持低电平,就将一直触发产生中断。
而对于上升沿或下降沿的中断触发,则需要I/O时钟信号的存在。
要使用外部中断我们首先要了解几个寄存器:1 AVR的状态寄存器SREG2 MCU控制寄存器MCUCR3 通用中断控制寄存器GICR4 通用中断标志寄存器GIFR1 AVR的状态寄存器SREG的每位都是一个标志位,这里先介绍位7—I(全局中断允许位),该位为1时全局中断始能允许,单独的中断使能则有对应的中断寄存器控制。
如果该位为0则不论单独允许位是否置1,所有中断都被禁止,系统将不相应任何中断。
因而要使用外部中断首先要对该位置1。
2 控制寄存器MCUCR的位0、1(ISC00、ISC01)是外部中断0的中断方式控制位0和位1。
其设置可参见下表:ISC01 ISC00 INT0的中断方式0 0 INT0的低电平产生一个中断请求0 1 INT0的下降沿和上升沿都产生一个中断请求1 0 INT0的下降沿产生一个中断请求1 1 INT0的上升沿都产生一个中断请求MCUCR的位2、3(ISC10、ISC11)是外部中断1的中断方式控制位0和位1。
AVRSTUDIO与PROTEUS的联调(页1)-proteus仿真-ARM...
AVRSTUDIO与PROTEUS的联调(页1)-proteus仿真-ARM...AVR STUDIO与PROTEUS的联调网上很多介绍这两个软件联调的方式是先用AVR STUDIO生成COF或ELF文件,然后用PROTEUS打开,这样在PROTEUS中模拟运行的时候就可以看到源码和单步调试了。
在PROTEUS 7.4之后, PROTEUS有了一个叫PROTEUS VSM VIEWER的插入式模块. 这个模块可以自动插入到AVR STUDIO中, 与AVR STUDIO集成一体, 实现了在AVR STUDIO工作环境中的电路仿真调试.具体方式如下(译自PROTEUS官方网站):1. 在PROTEUS中画好电路图,保存,退出proteus,不必再打开PROTEUS.2. 启动AVRStudio, 打开你的项目文件. 进入AVRStudio的Debug菜单,选择 'Select Platform and Device' ,会有一个对话框弹出,在这个对话框的左边选择 'Proteus VSM Viewer' ,右边选择你在电路图中用的单片机。
3. 点击Finish确定完成后,默认情况下在AVRStudio中会显示出Proteus Viewer 的窗口,如果没有显示出来,那么进入View菜单,选 Toolbars ,把列在其中的 Proteus VSM勾选上.4. 在AVRStudio中的这个PROTEUS小窗口上,点击“打开文件”图标,调入画好的电路图。
5. 编译好你的AVR程序。
6. 现在就可以利用AVRStudio自己的运行,步进,断点等等调试手段了,所有这些动作都自动会和电路图协调进行,在电路图上的动作如按钮,中断等等也会反应在程序上。
7. 要终止程序时,请注意需要先点击暂停按钮。
[img]/support/vdmavr.gif[/img]默认情况下这个PROTEUS窗口会比较小,但这个小窗口是可以拖出来的,拖出来后可以调整其大小。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
仿真的时候就可以按下那个button,看程序是否完成了应有的功能。
//LED灯状态标志位,0代表目前LED灯状态为灭,1代表LED灯目前状态为点亮
unsigned char led_flg = 0;
ISR(INT0_vect)//外部中断的中断服务程序,INT0_vectfromiom48p.h
{
EIFR &= ~(1<<INTF0);//清除中断标志位
_delay_ms(10);//延时去掉干扰
先打开这个MFile
将它另存到Hello_AVR下面,不要改它的名字,软件只认识Makefile这个名字,你若重命名了,还得再改还回来的。(在另存之前,这个界面下也可以做配置,可以配置完了再保存过去,效果也是一样的)
然后把它添加到工程文件夹Makefile下,打开Makefile文件,进行配置
绿色字体是注释,蓝色和黑色的是配置项。
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
extern void Exint_Iint(void);
#endif
avrexti.C:
#include <avrexti.h>
void Exint_Iint(void)//外部中断初始化函数
#include <avr/interrupt.h>//包含中断函数实现的相关函数定义
#include <util/delay.h>//提供了2个比较准的延时函数,自己懒得写就包含进去
#include "avrexti.h"//自己写的外部中断实现的相关函数的头文件
int main(void)
{
unsigned char i;
let's begin。
首先要明确我们要完成的功能:单片机开始工作后,点亮LED灯1S,灭掉LED灯1S,如此循环3次,然后单片机进入无限循环,等待外部按键button按下,LED等再次点亮,当再次按下button时,LED等灭掉,如此循环。
接着画出要实现这个功能的电路,以便后续仿真。
先在桌面建一个文件夹Hello_AVR, 如图。
DDRB |=(1<<0);//PB0此管脚外接LED灯
for(i=0; i<3; i++)
{
PORTB |=(1<<0);//PB0置位点亮LED灯
_delay_ms(1000);//延时1000msfrom#include <util/delay.h>
PORTB &= ~(1<<0);//PB0清零灭掉LED灯
{
DDRD&= ~(1<<2);
//MCUCR |= (1<<PUD);
//PORTC |=(1<<2);//上拉电阻使能
//PORTC &= ~(1<<2);//上拉电阻禁止
EICRA = (1<<ISC01);//下降触发
EIMSK =(1<<INT0);//使能外部中断
}
将这3个文件加入到工程文件中
把MCU项改成atmaga48
F_CPU就是AVR单片机内核频率,一般采用内部8M的时钟分频系数为8后,得到1M,不过这里我们直接选8M也可以。
FORMATE代表输出的格式,有3个可选项srec,ihex和binary,这里用ihex输出hex文件,用于proteus仿真
TARGET代表你的main()函数所在源代码文件的文件名,而且不需要再写.c
本文主要以AVR单片机atmega48的外部中断的在Proteus上仿真的例子介绍AVR单片机C语言开发环境WinAVR的使用(如何包含头文件,如何写中断服务程序,如何配置编译产生hex文件),及其在Proteus上的仿真实现(如何建立仿真图,载入hex文件进行仿真)
本例子完全为PC上软件仿真所以不涉及硬件,其全部所需软件清单如下:
完成。
在工程下面建4个文件夹Sys、Drv、App、Makefile
在Hello_AVR文件夹下,创建main.c、avrexti.c、avrexti.h这3个源代码文件,这些代码实现什么功能,我在程序中进行了注释,最重要的还是参考芯片的手册。
其内容如下:
main.c:
#include <avr/io.h>//通过宏定义开关,将包含iom48p.h
_delay_ms(1000);
}
Exint_Iint();//初始化外部中断from#include "avrexti.h"
sei();//开全局中断from#include <avr/interrupt.h>
while(1);//无限循环
return 0;
}
/***********************************************************************/
这里用PB0管脚来驱动LED灯,查阅芯片的数据手册或直接从图中可以知道,外部中断0(INT0)在PD2管脚。而且Proteus的好处是,这里我们给单片机画电源的麻烦也可以省去。
接下来要做的就是看数据手册和建立工程,编程,编译的事了。
打开Programmers Notepad
File->New->Project新建工程Hello_AVR,保存到Hello_AVR文件夹
OBJDIR是编译中间生产的文件,比如.o和.lst文件存放的目录,.表示当前工程的目录,可以改成./obj,把它放到当前工程下新建的obj文件夹下。它会自动为你创建的,如果不存在。
SRC代表你这个工程包含的C源文件,$(TARGET).c代表刚才的包含main()函数的主文件,现在我们还需要包含avrexti.c这个源文件,两者之间用空格隔开即可。avrexti.c和源文件同在工程直接目录下直接写avrexti.c,否则就包含全路径是比较保险的做法,移动的时候要注意修改这里。
if(!(PIND&(1<<2)))//确认按键按下
{
if(1==led_flg)
{
PORTB &= ~(1<<0);
led_flg = 0;
}
else
{
PORTB |=(1<<0);
led_flg = 1;
}
}
}
avrexti.h:
#ifndef __AVREXTI_H__
#define __AVREXTI_H__
每个选项都有注释表明它是干什么的,有时间可以慢慢研究,这里就只涉及到这几个就可以了。下面是配置好的选项
然后点Tool下的Make All就会编译生成一堆文件,其中就包括我们需要的main.hex文件
再点击Make Clean,所有编译生成的文件就会被消除干净,省的看起来比较乱,
现在需要再Make All一次,以产生需要的main.hex
WinAVR、Proteus、atmega48_Datasheet
软件的下载安装,请参考网上其他教程,有很多,很容易的。
atmega48单片机的数据手册网上中英文的版本也都可以下载到。
下图是笔者所使用的软件截图,不同版本可能稍有差异,但基本不影响使用。
下面我将在假设您已经安装好2个软件(当然目前您不需要知道它们是怎么用的),并且对单片机和C语言有基本了解的基础上进行例程的演示。
头文件iom48p.h的位置是G:\Program Files\WinAVR\avr\include\avr\iom48p.h,它包含了这个芯片外设控制寄存器的地址映射和中断向量表,包含进来以后可以方便查看拷贝寄存器和中断向量表。
编辑好源代码后,就是编译了,跟一般的集成开发环境有点不一样,不过仍旧是很好用的。
打开软件, 这个图标。
在软件界面上,右键Place->Component->From Libraries
在Keywords里面输入atmega48,选择一个32PIN管脚的单片机放到图上
同样的方法,放置一个LED灯,一个button,电阻,电容。
放置POWER和GND
图完成,在文件夹Hello_AVR下新建文件夹Sim,保存在这里