AVR C:使用按钮的 8 位计数器
AVR C : 8 Bit Counter using button
我有电路设置,每次按下按钮时都会打开 LED,它从 0 到 255 递增,因此二进制为 0000 0000 到 1111 1111。我的开关配置为 PB2,也就是 D9板.
我遇到了一个问题,正如你从我的coud中看到的那样,我使用了8个引脚,6个来自D寄存器,2个来自B寄存器。当我增加 PORTB 并在某个时候它变成 0b00000100,然后它的值与输入引脚 pb2 相同,所以在我的无限循环中即使我没有按下 PINB 按钮,它也会打开。我尝试将 PORTB 的值重置为 0,但它仍然无法关闭。
我需要一种机制,这样当我递增 PORTB 时它不会影响我的输入引脚 PB2。
非常感谢任何帮助,我尝试发布视频但它太大了。
#include <avr/io.h>
#define F_CPU 16000000UL
#include <util/delay.h>
/*
Board digital I/O pin to atmega328 registers for LEDS
| d2 | d3 | d4 | d5 | d6 | d7 | d8 | d9 |
| pd2 | pd3 | pd4 | pd5 | pd6 | pd7 | pb0 | pd1 |
Input Button
| d9 |
| pb2 |
*/
int main(void) {
int x;
DDRD = 0b11111100;
PORTD = 0b00000000;
DDRB = 0b00000011;
PORTB = 0b00000100;
while(1) {
if((PINB & 0b00000100) == 0) {
if(x < 63) {
PORTD = PORTD + 0b00000100;
x++;
} else if (x == 63) {
x=0;
PORTD = 0b00000000;
PORTB = PORTB + 0b00000001;
//problem here, when PORTB is incremented to 0b00000100 then the switch turns on automatically
if((PORTB & 0b00000100) == 0b00000100) {
PORTB = 0b00000000;
PORTD = 0b00000000;
}
}
_delay_ms(80);
}
}
return 0;
}
简单的答案是避免使用 PORTB 作为变量。而是使用 x,并适当移动 x 中的值以显示它。
#include <avr/io.h>
#define F_CPU 16000000UL
#include <util/delay.h>
/*
Board digital I/O pin to atmega328 registers for LEDS
| d2 | d3 | d4 | d5 | d6 | d7 | d8 | d9 |
| pd2 | pd3 | pd4 | pd5 | pd6 | pd7 | pb0 | pd1 |
Input Button
| d9 |
| pb2 |
*/
int main(void) {
uint8_t x = 0;
DDRD = 0b11111100;
PORTD = 0b00000000;
DDRB = 0b00000011;
PORTB = 0b00000100;
while(1) {
if((PINB & 0b00000100) == 0) {
++x;
PORTD = x << 2;
PORTB = (PORTB & 0b11111100) | ((x >> 6) & 0b00000011);
}
_delay_ms(80);
}
return 0;
}
我有电路设置,每次按下按钮时都会打开 LED,它从 0 到 255 递增,因此二进制为 0000 0000 到 1111 1111。我的开关配置为 PB2,也就是 D9板.
我遇到了一个问题,正如你从我的coud中看到的那样,我使用了8个引脚,6个来自D寄存器,2个来自B寄存器。当我增加 PORTB 并在某个时候它变成 0b00000100,然后它的值与输入引脚 pb2 相同,所以在我的无限循环中即使我没有按下 PINB 按钮,它也会打开。我尝试将 PORTB 的值重置为 0,但它仍然无法关闭。
我需要一种机制,这样当我递增 PORTB 时它不会影响我的输入引脚 PB2。
非常感谢任何帮助,我尝试发布视频但它太大了。
#include <avr/io.h>
#define F_CPU 16000000UL
#include <util/delay.h>
/*
Board digital I/O pin to atmega328 registers for LEDS
| d2 | d3 | d4 | d5 | d6 | d7 | d8 | d9 |
| pd2 | pd3 | pd4 | pd5 | pd6 | pd7 | pb0 | pd1 |
Input Button
| d9 |
| pb2 |
*/
int main(void) {
int x;
DDRD = 0b11111100;
PORTD = 0b00000000;
DDRB = 0b00000011;
PORTB = 0b00000100;
while(1) {
if((PINB & 0b00000100) == 0) {
if(x < 63) {
PORTD = PORTD + 0b00000100;
x++;
} else if (x == 63) {
x=0;
PORTD = 0b00000000;
PORTB = PORTB + 0b00000001;
//problem here, when PORTB is incremented to 0b00000100 then the switch turns on automatically
if((PORTB & 0b00000100) == 0b00000100) {
PORTB = 0b00000000;
PORTD = 0b00000000;
}
}
_delay_ms(80);
}
}
return 0;
}
简单的答案是避免使用 PORTB 作为变量。而是使用 x,并适当移动 x 中的值以显示它。
#include <avr/io.h>
#define F_CPU 16000000UL
#include <util/delay.h>
/*
Board digital I/O pin to atmega328 registers for LEDS
| d2 | d3 | d4 | d5 | d6 | d7 | d8 | d9 |
| pd2 | pd3 | pd4 | pd5 | pd6 | pd7 | pb0 | pd1 |
Input Button
| d9 |
| pb2 |
*/
int main(void) {
uint8_t x = 0;
DDRD = 0b11111100;
PORTD = 0b00000000;
DDRB = 0b00000011;
PORTB = 0b00000100;
while(1) {
if((PINB & 0b00000100) == 0) {
++x;
PORTD = x << 2;
PORTB = (PORTB & 0b11111100) | ((x >> 6) & 0b00000011);
}
_delay_ms(80);
}
return 0;
}