循环 ATMEGA8515 中的 LED

发布于 2024-11-04 04:53:58 字数 1574 浏览 0 评论 0原文

我想读取 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

简单爱 2024-11-11 04:53:58

我认为在 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文