【发布时间】:2021-03-12 22:55:38
【问题描述】:
我的目标:制作一个可以打开和关闭“闪烁 LED”程序的按钮。 PortD 只有输出 LED。 PORTBO 有输入按钮。 微控制器:Atmega328p
问题:目前,当我按下开关的按钮 case1 时,“闪烁 LED”程序启动。但我无法通过按钮关闭 LED。
注意:我是初学者,我想我可能不得不以某种方式使用中断,但不确定
#include <avr/io.h> // header file file for input output pins
#include <util/delay.h> // header file for delay.
#define DEBOUNCE_TIME 25 // time to wait while "de-bouncing" button
void init_ports_mcu()
{ /* set pin 5 of PORTB for output*/
DDRD = 0xFF;
PORTD = 0x00;
PORTB |= (1 << DDB0);
}
unsigned char button_state()
{
if( !(PINB & 0x01) )
{
_delay_ms( DEBOUNCE_TIME );
if( (PINB & 0x01) ) return 1;
}
return 0;
}
int main( void )
{
init_ports_mcu();
unsigned char n_led = 1;
while( 1 )
{
if( button_state() )
{
switch( n_led )
{
case 1:
while( 2 )
{
PORTD |= 0xFF;
_delay_ms( 1000 ); //delay 1 second
PORTD &= ~0xFF;
_delay_ms( 1000 );
if( button_state() ) // If the button is pressed break while loop
{
break;
}
}
break;
case 2:
PORTD |= 0x00;
_delay_ms( 5000 ); //delay 1 second
n_led--; // swtiches back to case1 LED number
break;
}
//n_led ++;
}
}
return 0;
}
【问题讨论】:
-
不能说我遵循逻辑,代码格式也无济于事。但有一件事,
main以unsigned char n_led = 1;开头,而n_led之后唯一的变化是n_led--;。我看不出switch(n_led)怎么能到达case 2:。 -
button_state()函数是一个边缘检测器。为了使该函数返回 1,您需要在 25 毫秒的延迟时间内按下按钮。当代码在执行while(1)循环时,大部分时间都花在了_delay(DEBOUNCE_TIME)调用上,因此可以识别按钮按下。但是在while(2)循环中,大部分时间都花在了_delay(1000)调用上,因此您需要将按钮按下的时间精确到毫秒。祝你好运!赔率是 40 比 1。 -
这是一个有趣的尝试。删除第二个
_delay_ms(1000)。将DEBOUNCE_TIME更改为1000。现在,当您按下按钮时,LED 将开始闪烁。如果在 LED 亮起时按下按钮,它会一直闪烁。但是如果在 LED 熄灭时按下按钮,它将停止闪烁。