陷入 AVR ATMEGA128 编程困境
我正在尝试用 C 语言为 ATMEGA128 微控制器构建第一个程序,但我遇到了按钮问题。我需要按特定顺序点亮 LED,并使用按钮我需要能够改变相反方向的方向(如图所示) 灯光顺序 ) 现在的问题是,当使用按钮时,我不能直接按下它。需要按住它才能改变灯光的方向。我尝试了一些东西,但没有任何效果。将不胜感激任何帮助。谢谢!
这是我的 C 代码:
#include <avr/io.h>
#define F_CPU 8000000UL
#include <util/delay.h>
int main(void)
{
DDRA = 0xFF;
PORTA = 0b00000001;
DDRB = 0xFF;
PORTB = 0x00;
DDRD = 0xFF;
PORTD = 0b10000000;
DDRC = 0xFF;
PORTC = 0x00;
DDRE = 0x00;
PORTE = 0xFF;
while(1)
{
int E;
int d;
d = 500;
E = PINE&(1<<PE0);
if (E==1)
{
for (int i=7; i>=0; i--)
{
PORTA = (1<<i);
PORTD = (1<<(7-i));
_delay_ms(d);
}
PORTA &=~ (1<<0);
PORTD &=~ (1<<7);
PORTC |= (1<<7);
PORTB |= (1<<0);
_delay_ms(d);
PORTC &=~ (1<<7);
PORTB &=~ (1<<0);
PORTB |= (1<<7);
PORTC |= (1<<0);
_delay_ms(d);
PORTB &=~ (1<<7);
PORTC &=~ (1<<0);
}
else
{
for (int i=0;i<=7;i++)
{
PORTA = (1<<i);
PORTD = (1<<(7-i));
_delay_ms(d);
}
PORTA &=~ (1<<7);
PORTD &=~ (1<<0);
PORTB |= (1<<7);
PORTC |= (1<<0);
_delay_ms(d);
PORTB &=~ (1<<7);
PORTC &=~ (1<<0);
PORTC |= (1<<7);
PORTB |= (1<<0);
_delay_ms(d);
PORTC &=~ (1<<7);
PORTB &=~ (1<<0);
}
}
}
I'm trying to build my first program in C for ATMEGA128 microcontroller and I have a problem with buttons. I need to light LEDs in particular order and using a button I need to be able to change the direction on the opposite direction (like on the picture
lights order )
Now the problem is that when using a button I can't just press it. It needs to be held in order to change the direction of lights. I tried some things, but nothing worked. Would appreciate any help. Thanks!
Here is my code in C:
#include <avr/io.h>
#define F_CPU 8000000UL
#include <util/delay.h>
int main(void)
{
DDRA = 0xFF;
PORTA = 0b00000001;
DDRB = 0xFF;
PORTB = 0x00;
DDRD = 0xFF;
PORTD = 0b10000000;
DDRC = 0xFF;
PORTC = 0x00;
DDRE = 0x00;
PORTE = 0xFF;
while(1)
{
int E;
int d;
d = 500;
E = PINE&(1<<PE0);
if (E==1)
{
for (int i=7; i>=0; i--)
{
PORTA = (1<<i);
PORTD = (1<<(7-i));
_delay_ms(d);
}
PORTA &=~ (1<<0);
PORTD &=~ (1<<7);
PORTC |= (1<<7);
PORTB |= (1<<0);
_delay_ms(d);
PORTC &=~ (1<<7);
PORTB &=~ (1<<0);
PORTB |= (1<<7);
PORTC |= (1<<0);
_delay_ms(d);
PORTB &=~ (1<<7);
PORTC &=~ (1<<0);
}
else
{
for (int i=0;i<=7;i++)
{
PORTA = (1<<i);
PORTD = (1<<(7-i));
_delay_ms(d);
}
PORTA &=~ (1<<7);
PORTD &=~ (1<<0);
PORTB |= (1<<7);
PORTC |= (1<<0);
_delay_ms(d);
PORTB &=~ (1<<7);
PORTC &=~ (1<<0);
PORTC |= (1<<7);
PORTB |= (1<<0);
_delay_ms(d);
PORTC &=~ (1<<7);
PORTB &=~ (1<<0);
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我的答案取决于您想要如何处理这个问题以及您打算使用哪些外围设备。
首先,我假设按钮当前连接到 PORTE0。
如果您想保持快速简单的路径并且可以接受一点延迟,您可以简单地切换一下并等待一小段时间,而不是连续轮询。
为了实现这一点,您可以使用类似的东西来代替“E = PINE&(1<
您也可以采用这种方法并使其变得更好。
防止 if 中出现双重输入的延迟会增加延迟。如果您不想这样做,您可以将该延迟“外包”给板载定时器/计数器模块之一。 数据表有一些漂亮的图表和一些关于该主题的示例(页面92+)
不过,我个人的建议是,将按钮从 PORTE0 更改为 PORTE 4-7 中的引脚。这些可以配置为外部中断源 (INT4-7)。正确配置后,您的中断服务例程几乎可以如此简单,
并且您根本不需要轮询。
但如果您使用这种方法,请不要忘记将变量 E 声明为 volatile。您需要这样做,因为中断被视为外部操作。
正如您所看到的,您有很多可能性可以实现这一目标。您可以根据您可以使用或感觉使用舒适的外围设备来选择一种。
如果您选择了适合您的方法,并且您对该方法还有其他疑问,请随时在此处发表评论。我希望我记得在一两天后回来查看。
此致
斯特罗米
My answer depends on how you want to approach this and what peripherals you intend to use.
First of all i will assume that the button is currently connected to PORTE0.
If you want to stay on the quick and easy path and are ok with a little latency you can simply toggle a bit and wait for a short time instead of continuos polling.
to achive that you could use something like this intstead of your "E = PINE&(1<<PE0);"
You can also take that approach and make it better.
That delay to prevent double inputs in the if adds latency. If you do not want that you can "outsource" that delay to one of the onboard Timer/Conter modules. The datasheet has some nice diagramms and some examples on that topic (Page 92+)
My personal recomendation however is that you change the button from PORTE0 to a pin in PORTE 4-7. These can be configured as external interrupt sources (INT4-7). After the right configuration your Interrupt-Service-Routine could be nearly as simple as
and you dont need to poll at all.
But if you use that approach dont forget to declare your variable E as volatile. You ned that because Interrupts are considered to be external operations.
As you can see you have many possibilities to make that work. You can choose one based on what peripherals you can use or feel comfortable using.
If you have chosen an approach that suits you and you have further questions regarding that approach feel free to comment here. I hope i remember to check back in one or two days.
Best regards
Stromi