我一直在做一个简单的项目,在AVR微控制器atmega16上对proteus进行模拟。
项目是:当我按下按钮时,它会将七个段增加到数字9,然后,如果我们再次按下按钮,它就会溢出,并再次返回到0。
当我改变(flag=1;)在When循环代码的位置时,它给了我不同的输出,我的意思是当我按下按钮时,它在推送后没有响应。
可能需要再按一下按钮才能增加七段proteus模拟
唯一正常工作的代码是在退出之前设置flag=1; (第二个if和else条件)。
因此,我的问题是,当我更改代码中的flag=1;语句位置时,实际发生了什么。
#include<avr/io.h>
#include<avr/interrupt.h>
char flag=1;
char num=0;
void INT2_Init(void){
DDRB&=~(1<<2);
SREG|=(1<<7);
GICR|=(1<<INT2);
MCUCSR|=(1<<ISC2);
}
ISR(INT2_vect){
flag=0;
GIFR|=(1<<INTF2);
}
int main(void){
DDRC=0x0f;
PORTC=0;
DDRB&=~(1<<2);
INT2_Init();
while(1){
if(flag==0){
if(num>8){
num=0;
PORTC=(PORTC&0xf0)|num;
}
else{
num++;
PORTC=(PORTC&0xf0)|num;
}
}
flag=1;
}
}发布于 2022-04-25 07:50:05
如果主代码和中断中有一些变量更改,则必须将其标记为volatile。否则,编译器可能决定缓存变量值,并在循环中省略它的读取。
volatile char flag=1;
第二,注意您的标志变量更改的时间和地点。例如:
while(1){
// at this point flag is 0, comparison failed
if(flag==0) {
...
}
// Interrupt happens here, changing flag to 0
// Then flag is immediately reset, thus flag change is missed in the loop
flag=1;
}相反,考虑使用这样的模式:
while (1) {
cli(); // disabling interrupts ensuring no interrupt happens inside
if (flag==0) {
...
}
flag = 1;
sei(); // re-enable interrupts
}或者,在这种情况下,它可以更简单
while (1) {
if (flag==0) {
flag = 1; // Reset flag only if it set, right after comparison
...
}
}发布于 2022-04-20 07:07:00
我不太清楚你在问什么。你只是挣扎着去理解代码吗?我的评论有用吗?
#include<avr/io.h>
#include<avr/interrupt.h>
char flag=1;
char num=0;
void INT2_Init(void){
DDRB&=~(1<<2);
SREG|=(1<<7);
GICR|=(1<<INT2);
MCUCSR|=(1<<ISC2);
}
// sets flag to 0 on external interrupt (button press)
ISR(INT2_vect){
flag=0;
GIFR|=(1<<INTF2);
}
int main(void){
DDRC=0x0f;
PORTC=0;
DDRB&=~(1<<2);
INT2_Init();
while(1){
// if flag was set to 0 in external interrupt -> increment (or overflow) number on segment display
if(flag==0){
if(num>8){
num=0;
PORTC=(PORTC&0xf0)|num;
}
else{
num++;
PORTC=(PORTC&0xf0)|num;
}
}
// reset the flag to 1 to prevent num from being incremented continuously
flag=1;
}
}我建议将flag=1;移到if中,以明确说明语句只应在按下每个按钮时执行一次。
while(1) {
// if flag was set to 0 in external interrupt -> increment (or overflow) number on segment display
if(flag==0){
// reset the flag to 1 to prevent num from being incremented continuously
flag=1;
if(num>8){
num=0;
PORTC=(PORTC&0xf0)|num;
}
else{
num++;
PORTC=(PORTC&0xf0)|num;
}
}
}使用自描述变量名也是明智的。例如,喜欢buttonWasPressed而不是flag。这样的代码就更容易阅读了。
https://stackoverflow.com/questions/71932120
复制相似问题