AVR单片机中断
- 格式:doc
- 大小:29.00 KB
- 文档页数:5
AVR单片机的捕获中断//ICC-AVR application builder : 2007-5-29 下午 02:12:45 // Target : M16// Crystal: 11.059Mhz#include <iom16v.h>#include <macros.h>/***********预编译******************/#define uchar unsigned char#define uint unsigned int#define ulong unsigned long/**************全局变量****************/uchar Flag=0; //捕获次数定义uchar ReadFlag=0; //发送数据标志ulong rpm=0; //转速uchar i;uint CNT1=0; //第一次捕获值uint CNT2=0; //第二此捕获值uint CNT=0; //捕获差值uchar ZHSH=0x00,ZHSL=0x00;struct UARTSJ{uchar tou0,tou1,CDH,ZHSH,ZHSL,temp3,temp4,Crc;};struct UARTSJ TXout;//发送的数据帧void port_init(void){PORTA = 0x00;DDRA = 0x00;PORTB = 0x00;DDRB = 0x00;PORTC = 0x00; //m103 output onlyDDRC = 0x00;PORTD = 0x00;DDRD = 0x0E;}//Watchdog initialize// prescale: 256Kvoid watchdog_init(void){WDR(); //this prevents a timout on enablingWDTCR = 0x0C; //WATCHDOG ENABLED - dont forget to issue WDRs}//TIMER1 initialize - prescale:1// WGM: 0) Normal, TOP=0xFFFF// desired value: 1uSec// actual value: 0.995uSec (0.5%)void timer1_init(void){TCCR1B = 0x00; //stopTCNT1H = 0x00;TCNT1L = 0x00;ICR1H = 0x00;ICR1L = 0x00;TCCR1A = 0x00;TCCR1B = 0xC1; //start Timer}#pragma interrupt_handler timer1_capt_isr:6void timer1_capt_isr(void){//timer 1 input capture event, read (int)value in ICR1 using;// value=ICR1L; //Read low byte first (important)// value|=(int)ICR1H << 8; //Read high byte and shift into top byte while(TIFR&0x20) //捕获检测{TIFR|=0x20; //清除捕获标志CNT2=(ICR1H<<8)+ICR1L; //CNT2存放当前捕获值if(CNT2>CNT1)CNT=CNT2-CNT1; //CNT存放两次时间差elseCNT=0xffff-CNT2+CNT1;CNT1=CNT2; //CNT1存放上次捕获值rpm=(ulong)120E6/(ulong)CNT;Flag++; //检测到第一次捕获}if(Flag==2) //检测到第二此捕获{Flag=0;i=(uchar)rpm; //清除捕获检测标志ZHSH=i&0xff00;ZHSL=i&0x00ff; //数据处理ReadFlag=1; //标志传输有效CNT=0;CNT1=0;CNT2=0;} //清除捕获值及捕获差值}#pragma interrupt_handler timer1_compa_isr:7void timer1_compa_isr(void){//compare occured TCNT1=OCR1A}//UART0 initialize// desired baud rate: 4800// actual: baud rate:4800 (0.0%)// char size: 8 bit// parity: Disabledvoid uart0_init(void){UCSRB = 0x00; //disable while setting baud rateUCSRA = 0x00;UCSRC = BIT(URSEL) | 0x06;UBRRL = 0x8F; //set baud rate loUBRRH = 0x00; //set baud rate hiUCSRB = 0xB8;}#pragma interrupt_handler uart0_rx_isr:12void uart0_rx_isr(void){//uart has received a character in UDR}#pragma interrupt_handler uart0_udre_isr:13void uart0_udre_isr(void){//character transferred to shift register so UDR is now empty }//call this routine to initialize all peripheralsvoid init_devices(void){//stop errant interrupts until set upCLI(); //disable all interruptsport_init();watchdog_init();timer1_init();uart0_init();MCUCR = 0x00;GICR = 0x00;TIMSK = 0x20; //timer interrupt sourcesSEI(); //re-enable interrupts//all peripherals are now initialized}//void main(void){init_devices();while(1);//insert your functional code here...}//转速=1E6微秒/秒×1脉冲/时间间隔(微秒表示)×2圈/脉冲(看有几个汽缸)×60秒/分钟。
AVR单片机中断
系统在正常运行主程序时,如果突然有一个重要的任务要马上处理,那么
系统就要保存现在的工作,然后再去处理这个任务,执行这个重要任务完毕以
后再返回原来的主程序继续运行,这就是中断。
主程序一旦进入中断服务程序,那么AVR 芯片将自动的关闭全局中断,在
这个期间不再执行其它的中断请求,直到中断程序结束以后芯片才自动的重新
开放全局中断。
(注意,在这个期间某些中断请求可能会被丢弃,某些请求会留下中断请求标致,一旦当前的中断执行完毕,这个有中断标致的请求就有可能
马上得到响应,如INT0 的下降沿触发就会留下中断请求标致,而低电平触发
就不会流下中断请求标致)。
如果你想在执行中断服务程序时响应另外一个更重要的中断,那么就要在中断服务程序中加入一条打开全局中断的语句。
使用ICC 快速建立中断服务程序程序文件
使用ICCAVR Application Builder 进行如下图所示的设置。
可以设置是否使用中断,上升延,下降延,低电平,任意的逻辑电平变化。
将生成的程序进行修改,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;。
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)
//终端服务函数;
{
//在中断函数中,不能定义局部数据类型变量;
//在此写入中断程序;
}。
/s/blog_4aa25f130100go4v.html转中断:我的理解就是cpu执行时,遇到中断——根据对应的中断源(硬件或软件)——pc定位中断入口地址,然后根据这里的函数指针——跳转到相应的服务程序之所以上面()了硬件或软件,这里还涉及到向量中断和非向量中断:区别就在于确定中断源,如果是硬件编码了中断源的,直接跳转相应的服务函数则是向量中断。
而非向量中断指的是:如果发生中断了,但此时还不清楚是那个中断,需要查找标志位来确定跳转到那个中断区域。
可以发现向量中断肯定来的快些,这里为定时器的中断来做好准备。
再来看看avr单片机的定时器:定时器/计数1(16位)————分为普通模式,CTC模式,快速pwm模式,相位修正pwm模式,相位频率修正pwm模式,输入捕获模式。
普通模式:*1 寄存器TCCR1B(控制寄存器)7 6 5 4 3 2 1 0ICNC1 ICES1 - WGM13 WGM12 CS12 CS11 CS10CS12 CS11 CS10控制分频(内:预分频器):取值0-5对应了停止,无分频,8,64,256,1024当为110为下降沿驱动,111为上升沿驱动(外部):用于对外部信号的计数*2上面的计数结果放在计数寄存器TCNT1,TCNT0中(高低8位)*3中断屏蔽寄存器(TIMSK)OCIE2 TOIE2 TICIE1 OCIE1A OCIE1B TOIE1OCIE0 TOIE0TOIE1 :设置为溢出中断,置1嘿嘿,有了上面的3个寄存器就可以做秒表等了——思路为:设定控制寄存器(内分频,还是外部计数?)——装初值——设置中断方式(这里用了溢出)——打开中断注意点:装初值时需要先写高位TCNT1,再写低位TCNT0,读时相反TCCR1B=0x01;无分频TCNT1H=0x88;TCNT1L=0x88;TIMSK|=BIT(2); 再开中断SREG|=bit(7); 这样初始化oK!由于avr不像51无int code等之类定义的方法,用的是#pragma data:code 底下为存储的内容写中断也类似:#pragma interrupt_handler (中断函数名:向量号)miao:9(现在该理解向量中断吧)写好申明后就写函数体了void miao(){中断服务程序}这样作为普通用法就小功告成了总结一下就是模式,初值,中断(对应的3个寄存器)和具体C函数的写法CTC模式比较输出模式:用于输出50%占空比的方波信号,用于产生准确的连续定时信号硬件:对应了pd4,pd5输出比较b和a比较输出*1 寄存器TCCR1A(控制寄存器)功能多了寄存器也分a、b了^_^7 6 5 4 3 2 1 0com1A1 COM1A0 com1B1 COM1B0 FOC1A FOC1B W GM11 WGM10用到了4567和01 4、5控制b 6、7控制acom1A(B)1 COM1A(B)0 一般用00和01 WGM11,WGM10放在底下讲0 0 普通i/00 1 比较匹配时输出取反1 0 比较匹配时输出01 1 比较匹配时输出1*2 寄存器TCCR1B(控制寄存器)7 6 5 4 3 2 1 0ICNC1 ICES1 - WGM13 WGM12 CS12 CS11 CS10CS12、CS11、CS10为设置时钟源的WGM13,WGM12,WGM11,WGM10用于波形产生描述的位选择,有对应的表0-15 这里选了4:CTC-OCR1A-立即更新-最大 OCR1A (16位)输出比较寄存器-这里存放了上限值设置的目的是,计数上升到了设定的上限后就电平取反思路:先初始话,对应的复用i/o为输出——设定com1A(B)1,COM1A(B)0 为比较输出取反——设定上限值为ocr1A 就ok了0CR1A可以根据公式计算:具体公式看手册,这里因为我打不起来o(∩_∩)o...哈哈总结一下就是控制寄存器a,b以及上限的值即可产生方波快速PWM分8位9位10位快速pwm,以及自定义方式我的理解:OCR1A存放上限值,这样用上了A的功能,由上面可知A只能为方波了,且计数到这个值时取反下限值通过OCR1B来确定的,从而计数到这个值置0,从而可以发现在一个周期内 OCROB即为高电平的时间(确定占空比)如图TCCR1A=0x63;TCCR1B=0x1B; 工作方式(快速pwm15,64分频)和分频系数OcR1A=1249;OCCR1B=250; 设为100Hz PWM信号,和2毫秒的高电平时间总结一下就是控制寄存器:由上限值,和分频系数可以确定计数的时间,确定频率由下限值可以确定占空比怎么样?明白了吗?o(∩_∩)o...相位修正PWM和快速pwm一样,模式分8位9位10位快速pwm,以及自定义方式共5种对应123和10,11相位修正其实和上面的方法相同,只不过到最大值时,不是取反,而是计数--,直到到了下限时取反由上可以发现2图的区别吧,一个为到TOP后,直接置0,后者为--,且在top 不取反而是到了最小值是取的,周期故而也比快速的长了一倍,故频率为快速pwm的一半,但是占空比不变,这也是为什么叫快速pwm的原因TCCR1A=0x63;TCCR1B=0x13 工作方式(相位修正pwm11,64分频)和分频系数OcR1A=1249;OCCR1B=250; 设为100Hz PWM信号,和2毫秒的高电平时间相位频率修正PWM和相位修正的类似输入捕获。
AVR 中断优先级AVR 单片机在同一个优先级中,中断向量入口地址越低,其优先级越高。
AVR 单片机在响应中断以后,会禁止系统响应其余中断。
如果程序需要在某个中断服务程序中响应其它中断事件,可以在该中断服务程序中用SEI 指令或_SEI()(IAR)、SEI()(ICCAVR)重新使能全局中断即可。
否则,AVR 单片机只有在退出中断进程时,才重新使能全局中断。
AVR(至少是ATmega16)单片机采用固定的硬件优先级方式,不支持通过软件对中断优先级重新设定。
AVR 有不同的中断源。
每个中断和复位在程序空间都有独立的中断向量。
所有的中断事件都有自己的使能位。
当使能位置位,且状态寄存器的全局中断使能位I 也置位时,中断可以发生。
根据程序计数器PC 的不同,在引导锁定位BLB02 或BLB12 被编程的情况下,中断可能被自动禁止。
这个特性提高了软件的安全性。
详见P247 存储器编程的描述。
程序存储区的最低地址缺省为复位向量和中断向量。
完整的向量列表请参见P43 中断。
列表也决定了不同中断的优先级。
向量所在的地址越低,优先级越高。
RESET 具有最高的优先级,第二个为INT0 – 外部中断请求0。
通过置位MCU 控制寄存器(MCUCR) 的IVSEL,中断向量可以移至引导Flash 的起始处。
编程熔丝位BOOTRST 也可以将复位向量移至引导Flash 的起始处。
具体参见P234 支持引导装入程序– 在写的同时可以读(RWW,Read-While-Write) 的自我编程能力。
简介:中断的概念,ATmega16中断向量表,avr中断寄存器SREG,MCU控制和状态寄存器MCUCSR,通用中断控制寄存器GICR,MCU控制寄存器MCUCR,ICCAVR中断函数格式介绍
中断就是暂停正在执行的程序语句,转去执行另一功能(函数)的程序语句,执行完后,立即返回原先暂停执行的语句处,继续执行。
单片机的中断系统解决了单片机运算速度快,外设(如键盘)速度慢之间的数据传输问题,提高了单片机的实时性和数据处理能力。
中断源:产生中断的地方,ATmega16具有20个中断源和一个复位中断,不同的单片机中断源的个数是不一样的。
单片机的中断源分为外部中断源和内部中断源,有三个外部中断源有INT0,INT1,INT2,当连接在单片机引脚的上的外部电平发生变化时,将产生相应的中断。
内部中断源由单片机内部的功能单元如定时器,串行通讯产生的中断。
按是否可屏蔽可分为,非屏蔽中断,和可屏蔽中断,非屏蔽中断有系统复位(reset)中断,可屏蔽中断:屏蔽指的的是中断可由软件编程控制是否允许中断,或禁止中断,大部分都是可屏蔽中断。
中断向量:单片机的每个中断源都有一个固定的入口地址,这个地址由单片机的硬件决定的,单片机相应中断后,自动跳转到相应的地址,这个地址就叫中断矢量
小企鹅diy科学探究学习网
更多相关文章转到: /wqb_lmkj/blog 文章分类下的单片机。
A VR中断一、中断信号往往是电信号的某种变化形式,如脉冲的上升沿或下降沿高电平或低电平电平变化二、中断向量中断请求被cpu检测到之后,如果中断控制系统允许,cpu会自动转移,执行一个固定的程序空间地址的指令。
这个固定地址叫做中断入口地址,也叫中断向量。
而这个地址是有单片机的硬件来决定的。
一般这个地址不放置具体的程序,只放置一条跳转指令,转向真正的中断服务程序。
三、A VR不支持软件改变中断优先级,即其优先级是固定的。
四、中断源分为三类1.非屏蔽中断,如reset中断,无法屏蔽2.屏蔽中断,大部分中断都是可屏蔽的3.软件中断,A VR不支持,好像ARM里面有,可以作为操作系统的中断调用。
五、中断响应条件响应A中断= 全局中断允许标志AND 中断A允许标志AND 中断A标志全局中断允许标志对于A VR就是其标志寄存器SREG的I位,SREG.7,gcc中打开和关闭的方法为sei()和cli()中断允许标志,一般来说每个中断都会有单独的允许标志位,放置在某个相关的寄存器中,通过单独设置那一位可以打开或关闭相应的中断。
中断标志,一般说来这个标志都是硬件触发的,就是一旦满足那个条件,这个标志自动为1,不需要手动设置。
六、中断向量区大小= 中断源个数x 每个中断向量所占的字数七、中断标志位一般会在cpu响应中断后自动清除,或在中断服务程序中通过读写专门的寄存器而自动清除。
当然也可以对其进行软件清除,清除方法是对其写1(这点比较怪)八、中断标志会一直保持,如果中断被禁止或者是cpu不能马上响应的话。
这是称作“挂起”,一旦cpu可以响应了,则马上按优先级处理中断。
九、个别中断不带中断标志,比如配置为低电平触发的外部中断。
只要满足条件就会向cpu 一直发送中断申请。
这里就会出现这样的问题:1.cpu暂时没响应中断,低电平没有了,这样就少了一次服务2.cpu响应了,响应完事,低电平还在,又多服务了一次所以设计的时候要注意一般这种低电平触发中断方式用于唤醒处于休眠模式的cpu,可参考具体方案。
AVR单片机中断应用设计要点
四川侯鑫
AVR的中断源较多,尤其是AT-mega128,一共有35个外部及内部中断源。
通常。
Flash 程序存储器空间的最低位置(0×0000~0×0045)定义为复位和中断向量空间。
在中断向量表中,处于低地址的中断向量所对应的中断拥有高优先级。
所以,系统复位RESET优先级最高。
一、中断设计注意事项1.具备Bootloader功能的AVR。
其中断向量区可以在Flash程序存储器空间最低位置和Bootloader区的头部来回迁移,这主要用于配合Bootloadel程序的应用。
如果不使用Bootloadel-功能。
一般不使用中断向量区迁移。
2.Flash较小的AVR芯片。
其一个中断向量占据1个字的空间。
用于放置一条相对转移RJMP指令(范围-2k~+2k字),跳到中断服务程序。
对于不使用的中断。
在中断向量区中应放置1条中断返回指令RETI。
以增强程序的抗干扰性。
3.ATmega128的Flash空间为64k字节,因此它的一个中断向量占据2个字的空间。
用于放置一条绝对转移JMP指令(指令长度为2个字)。
跳到中断服务程序。
对于不使用的中断。
在中断向量区中应连续放置2条中断返回指令RETI,以增强程序的抗干扰性。
当使用汇编语言编写系统程序时应注意。
4.当MCU响应一个中断时.其硬件系统会自动将中断返回地址压入系统堆栈。
并关闭全局中断响应(硬件将中断标志I位清0).清除该中断的中断标志位;执行中断返回指令RETI 时,硬件会先允许全局中断响应(硬件将中断标志I位置1),然后从系统堆栈中弹出返回地址到程序计数器PC中,继续执行被中断的程序。
除此之外,MCU的硬件没有对中断保护做其他处理。
5.在编写中断服务程序时。
首先要编写中断现场保护程序。
如保护MCU的状态寄存器等。
在中断返回之前,不要忘记恢复中断现场。
6.如果设置和允许外部中断响应。
即使是外部INT0~INT7引脚设置为输出。
在引脚上的电平变化也会触发外部中断发生。
这一特性提供了使用软件产生中断的途径。
7.外部中断可选择采用上升沿触发、下降沿触发、电平变化(由高变低或由低变高)和低电平触发等方式,无外部高电平触发方式。
具体触发方式由外部中断控制寄存器EICRA(INT3:0)和EICRB(INT7:4)决定。
8.选择外部低电平方式触发中断时应注意:(1)引脚上的低电平必须一直保持到当前一条指令执行完成后才能触发中断。
(2)低电平中断并不置位中断标志位。
即外部低电平中断的触发不是由于中断标志位引起的,而是外部引脚上电平取反后直接触发中断(需要开放全局中断允许)。
因此,在使用低电平触发方式时,中断请求将一直保持到引脚上的低电平消失为
止。
即只要中断引脚的输入引脚保持低电平,则将一直触发产生中断。
所以,在低电平中断服务程序中,应有相应的操作命令,控制外部器件释放或取消加在外部引脚上的低电平。
二、中断优先及中断嵌套处理
1.AVR中断的优先级由该中断向量在中断向量区中的位置确定,处于低地址的中断向量所对应的中断拥有高优先级。
所以。
系统复位RESET拥有最高优先级。
2.当两个中断源同时申请中断时。
MCU先响应中断优先级高的中断。
低优先级的中断一般将保持中断标志位的状态(外部低电平中断除外),等待MCU响应处理。
3.MCU响应一个中断后,在进入中断服务前已由硬件自动清零全局中断允许位。
此时。
即使有更高优先级的中断请求,MCU也不会响应。
要等执行到RETI指令,从本次中断返回,并执行了一条指令后。
才能继续响应中断。
所以,在缺省情况下,AVR的中断不能嵌套。
AVR中断的优先级只是在有多个中断同时发生时才起作用。
此时,MCU将首先响应高优先级的中断。
4.AVR中断嵌套处理是通过软件方式实现的。
如果在B中断服务中,需要MCU能及时响应A中断(不是等本次中断返回后再响应),B中断的服务程序应这样设计:
(1)B中断的现场保护;(2)屏蔽除A以外的其它中断允许标志;(3)用指令SEI开放允许全局中断;(4)B中断服务;(5)用指令CLI禁止全局中断;(6)恢复在本中断程序被屏蔽的中断允许标志;(7)B中断现场恢复;(8)B中断返回。
5.采用软件方式实现中断嵌套处理的优点。
是让程序员可以根据不同的实际情况和需要来决定中断的重要性。
有更加灵活的手段处理中断响应和中断嵌套,如让低优先级的中断(此时很重要)打断高优先级中断的服务等。
但同时也增加了编写中断服务程序的复杂性。
6.由于AVR的指令执行速度比较高,因此。
在一般情况下。
不建议使用中断嵌套的处理方法。
当然,这还需要用户在编写中断处理服务程序中。
应遵循中断服务程序要尽量短的原则。
三、高级语言环境中。
中断服务程序的编写1.在高级语言开发环境中,都扩展和提供了相应编写中断服务程序的方法及模块。
但不同的高级语言开发环境中对编写中断服务程序的语法规则和处理方法是不同的。
在编写中断服务程序前。
应当对所使用开发平台、中断程序的编写方法、中断的处理方法等有较好的了解。
2.使用ICCAVR、CVAVR、BASCOM-AVR等高级语言编写中断服务程序时。
通常不必考虑对中断现场保护和恢复的处理。
因为编译器在编译中断服务程序的源代码时,会在生成的目标代码中自动加入相应的中断现场保护和恢复指令。
3.如果用户要编写效率更高或特殊的中断服务程序。
可以采用嵌入汇编、关闭编译系统的自动产生中断现场保护和恢复代码等措施。
但这需要对所使用的开发环境有更深的了解和掌握。
并具备较高的软件设计能力。