循环 ATMEGA8515 中的 LED
我想读取 LED 旁边的开关,并将 LED 从 0 循环到按下的开关 如果没有按下,则延迟循环所有这些。为此,我使用了timer0。自从我工作以来 atmega8515。我用的是INT0。 这是我的实现:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#define BIT(n) (1 << n)
volatile uint8_t led, k, switches, i , j = 1;
/* uint8_t is the same as unsigned char */
int main(void)
{
DDRB = 0xff; /* use all pins on PortB for output */
led = 1; /* init variable representing the LED state */
PORTB = 0XFF;
cli( );
TCCR0|=(1<<CS02) |(1<<CS00);
//Enable Overflow Interrupt Enable
TIMSK|=(1<<TOIE0);
//Initialize Counter
TCNT0=0;
GICR = BIT(INT0);
MCUCR = BIT(ISC01) | BIT(ISC00);
sei( );
for ( ; ;);
}
ISR(TIMER0_OVF_vect)
{
if(switches == 0xff)
{
PORTB = ~led; /* invert the output since a zero means: LED on */
led <<= 1; /* move to next LED */
if (!led) /* overflow: start with Pin B0 again */
{
led = 1;
}
}
else
{
for (k = 0; k< 8;k++)
{
j = switches & (1 << k);
if(j == 0)
{
for(i=1;i<=(k +1);i++)
{
j = 1;
PORTB = ~j;
j = 1 << i;
_delay_ms(100); //without this delay it doesnt cycle the LEDS from to whichever switch is pressed
}
}
}
}
但是在 ISR 中使用延迟循环是一种不好的编程习惯。如何使用同一个定时器而不是延迟?
I want to read the switches next to the LEDS and cycle the LEDS from 0 to whichever switch is pressed
if none are pressed cycle through all of them with the delay.For this i have used timer0. Since I work on
atmega8515. I used INT0.
Here is my implementation:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#define BIT(n) (1 << n)
volatile uint8_t led, k, switches, i , j = 1;
/* uint8_t is the same as unsigned char */
int main(void)
{
DDRB = 0xff; /* use all pins on PortB for output */
led = 1; /* init variable representing the LED state */
PORTB = 0XFF;
cli( );
TCCR0|=(1<<CS02) |(1<<CS00);
//Enable Overflow Interrupt Enable
TIMSK|=(1<<TOIE0);
//Initialize Counter
TCNT0=0;
GICR = BIT(INT0);
MCUCR = BIT(ISC01) | BIT(ISC00);
sei( );
for ( ; ;);
}
ISR(TIMER0_OVF_vect)
{
if(switches == 0xff)
{
PORTB = ~led; /* invert the output since a zero means: LED on */
led <<= 1; /* move to next LED */
if (!led) /* overflow: start with Pin B0 again */
{
led = 1;
}
}
else
{
for (k = 0; k< 8;k++)
{
j = switches & (1 << k);
if(j == 0)
{
for(i=1;i<=(k +1);i++)
{
j = 1;
PORTB = ~j;
j = 1 << i;
_delay_ms(100); //without this delay it doesnt cycle the LEDS from to whichever switch is pressed
}
}
}
}
But using delay loops in ISR is a bad programming practice. How to use the same timer instead of the delay?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为在 ISR 中,您应该只更新 LED 状态,并且在主循环中您可以设置 PORTB 并读取开关值。在你的代码中,它似乎在 ISR 中占用了很多时间。
I think in the ISR, you should just update the LED status and in the main loop you could set the PORTB and read the switches values. In your code, it seems occupy so much time in ISR.