为什么在 main 中需要一个 while 循环来调用 arduino UNO 中的 ISR?
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 上的内置 LED)。一旦我在 while 循环中添加,我就看到 PinB5 切换。奇怪的是,当我想使用定时器制作直接输出到 Pin 的 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
没有busy-loop,程序会立即return0,然后结束。当它在循环中时,什么都不做,它可以被中断服务程序中断。
非常简单的答案。当大多数 AVR 工具链上的 main returns 时,它执行 cli 指令以禁用中断,然后在无限循环中结束。这是 AVR 裸机工具链中最常见的结尾例程。
这是退出 main
时发生的情况
00000078 <_exit>:
78: f8 94 cli
0000007a <__stop_program>:
7a: ff cf rjmp .-2 ; 0x7a <__stop_program>
您可以通过修改启动程序集文件(它也包含结语)来更改它。
我正在编写上传到 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 上的内置 LED)。一旦我在 while 循环中添加,我就看到 PinB5 切换。奇怪的是,当我想使用定时器制作直接输出到 Pin 的 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
没有busy-loop,程序会立即return0,然后结束。当它在循环中时,什么都不做,它可以被中断服务程序中断。
非常简单的答案。当大多数 AVR 工具链上的 main returns 时,它执行 cli 指令以禁用中断,然后在无限循环中结束。这是 AVR 裸机工具链中最常见的结尾例程。
这是退出 main
00000078 <_exit>:
78: f8 94 cli
0000007a <__stop_program>:
7a: ff cf rjmp .-2 ; 0x7a <__stop_program>
您可以通过修改启动程序集文件(它也包含结语)来更改它。