繁体   English   中英

为什么要在arduino UNO中调用ISR,main中需要一个while循环?

[英]Why is a while loop needed in main for calling ISR in arduino UNO?

我正在编写上载到arduino uno的C代码。 这是学习如何在C中调用ISR的简单练习。代码如下:

#include<stdio.h>
#include<stdlib.h>
#include<avr/interrupt.h>
#include<avr/io.h>


int main(){

 DDRB        = 0;
 PORTB       = 0;
 DDRB        = (1<<5);
 PORTB       = (0<<5);

 //resetting the Timer/Counter1
 TCNT1H         = 0;
 TCNT1L         = 0;  

 //disabling all global interrupts
 SREG         = 0;

 //defining prescalar

 //TCCR1B: ICNC1 ICES1 – WGM13 WGM12 CS12 CS11 CS10
 TCCR1B = 0;
 //TCCR1B_reg = CS11_val; WORKING SETTINGS
 TCCR1B = 0b00000101;//(1<<CS10_val)|(1<<CS12_val);

 //setting up PWM mode

 //TCCR1A: COM1A1 COM1A0 COM1B1 COM1B0 COM1C1 COM1C0 WGM11 WGM10
 TCCR1A      = 0; //this is for waveform generation and CTC setting up mode;
 //TCCR1A      = 0b10000000;//(1<<COM1A1_val);
 TCCR1A      = COM1A1;

 OCR1AH      = 0b10011100;//0b00000000;
 OCR1AL      = 0b01000000;//0b01000000;

 TIMSK1      = 0b00100010;//(1<<ICIE1_val)|(1<<OCIE1A_val);//0b00100010;//writing so that output compare A is set up

 //enable global interrupts
 SREG         = (1<<7);
 while(1){}

 return 0;

}

ISR(TIMER1_COMPA_vect){
  PORTB = PORTB^(1<<5);
}

有趣的是,当我摆脱了“ while(1){}”时,该代码似乎无法切换PinB5(在arduino uno上导致的内置)。 在while循环中添加后,我立即看到PinB5切换。 奇怪的是,当我想使用计时器来制作直接输出到引脚的PWM时,我不需要使用while循环。

以防万一你们好奇,这是我上传到arudino-uno的方法:

avr-gcc -Os -DF_CPU=16000000UL -mmcu=atmega328p -c -o ISR_example.o ISR_example.c
avr-gcc -mmcu=atmega328p ISR_example.o -o ISR_example
avr-objcopy -O ihex -R .eeprom ISR_example ISR_example.hex

read -p "Get ready to flash!"
#flashing the Arduino:
avrdude -C/home/ashwini/Downloads/arduino-1.8.3/hardware/tools/avr/etc/avrdude.conf -v -patmega328p -carduino -P/dev/ttyACM0 -b115200 -D -Uflash:w:ISR_example.hex:i

很简单的答案。 当main在大多数AVR工具链上返回时,它执行cli指令以禁用中断,然后在不定式循环中结束。 这是AVR裸机工具链中最常见的结尾例程。

这是当您从main出口退出时发生的情况

00000078 <_exit>:
  78:   f8 94           cli

0000007a <__stop_program>:
  7a:   ff cf           rjmp    .-2         ; 0x7a <__stop_program>

您可以通过修改启动程序集文件(它也包含结尾)来更改它。

如果没有繁忙循环,程序将立即返回0,然后结束。 当它处于循环中时,什么也不做,它可以被中断服务程序中断。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM