通过 LED 循环

发布于 2024-10-01 02:00:13 字数 980 浏览 2 评论 0原文

请帮助我处理这段代码,它让我发疯。这是一个非常简单的程序,带有 8 位定时器,循环显示所有 8 个 LED(一个接一个)。我使用 ATSTK600 板。

我的计时器运行良好,我认为循环存在一些问题(当我使用 avr studio-gcc 调试该程序时,我可以看到所有 LED 按我想要的方式工作,但是当我将其转移到板上时...LED 不工作不要眨眼)。我对这种行为感到疯狂。

这是我的代码:

#include <avr/io.h>
#include <avr/interrupt.h>

volatile unsigned int intrs, i, j = 0;

void enable_ports(void);
void delay(void);

extern void __vector_23 (void) __attribute__ ((interrupt));

void enable_ports()
{
    DDRB = 0xff;

    TCCR0B = 0x03;

    TIMSK0 = 0x01;

    //TIFR0 = 0x01;

    TCNT0 = 0x00;

    //OCR0A = 61;

    intrs = 0;
}

void __vector_23 (void)
{
    for(i = 0; i<=8; i++)
    {
        while(1)
        {
            intrs++;
            if(intrs >= 61)
            {
                PORTB = (0xff<<i);
                intrs = 0;
                break;
            }

        }
    }
    PORTB = 0xff;
}

int main(void)
{
    enable_ports();
    sei();

    while(1)
    {

    }
}

Please help me with this code, it is making me crazy. This is a very simple program with 8-bit timer, cycling through all 8 leds (one-by-one). Am using ATSTK600 board.

My timers are working well, I think there is some problem with the loops (when I debug this program using avr studio-gcc, I can see all the leds working as I want but when I transfer it on board...leds don't blink). Am going crazy with this type of behavior.

Here is my code:

#include <avr/io.h>
#include <avr/interrupt.h>

volatile unsigned int intrs, i, j = 0;

void enable_ports(void);
void delay(void);

extern void __vector_23 (void) __attribute__ ((interrupt));

void enable_ports()
{
    DDRB = 0xff;

    TCCR0B = 0x03;

    TIMSK0 = 0x01;

    //TIFR0 = 0x01;

    TCNT0 = 0x00;

    //OCR0A = 61;

    intrs = 0;
}

void __vector_23 (void)
{
    for(i = 0; i<=8; i++)
    {
        while(1)
        {
            intrs++;
            if(intrs >= 61)
            {
                PORTB = (0xff<<i);
                intrs = 0;
                break;
            }

        }
    }
    PORTB = 0xff;
}

int main(void)
{
    enable_ports();
    sei();

    while(1)
    {

    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(4

感情废物 2024-10-08 02:00:14

如果您在使用 avr studio-gcc 进行调试时看到了您想要的行为,那么这会给您一些信心,让您相信您的程序是“好”的(对于“好”这个词的某种意义)。因此,听起来您似乎需要关注不同的领域:调试环境和独立下载之间有什么区别?

当进行独立下载时,您知道您的程序是否正在运行吗?

LED 是否闪烁或完全亮起?您没有在问题中明确说明,但该问题可能与调试过程非常相关。以不同的速度运行看起来是正确的行为吗?如果是这样,那么您的程序可能没有执行调试器正在执行的某种初始化。

进行独立下载时,与调试版本相比,程序是否使用不同的设置进行编译?也许编译器优化设置正在改变程序的时序特征。

(如果您提供有关独立下载正在执行的操作的更多详细信息,您的问题会更好。一般来说,当某人很少或根本没有有关正在发生的事情的详细信息时,他们很难调试远程系统。执行所有操作/有些 LED 灯会亮吗?)

If you're seeing the behaviour you want when debugging with avr studio-gcc, then that gives you some confidence that your program is "good" (for some sense of the word "good"). So it sounds as though you need to focus on a different area: what is the difference between your debug environment and your stand-alone download?

When doing a stand-alone download, do you know if your program is running at all?

Are the LEDs blinking, or turning on at all? You don't explicitly say in your question, but that question could be very relevant to the debugging process. Does it look like the right behaviour, running at a different speed? If so, then your program is probably not doing some sort of initialisation that the debugger was doing.

When doing a stand-alone download, is the program being compiled with different settings compared to the debug version? Perhaps compiler optimisation settings are changing your program's timing characteristics.

(Your question would be better if you gave more detail about what the stand-alone download is doing. In general, it is hard for someone to debug a remote system when they're given few or no details about what is happening. Do all/some of the LEDs turn on at all?)

南汐寒笙箫 2024-10-08 02:00:13

你的中断例程有缺陷。 intrs 仅计算循环执行的次数,而不是顾名思义的定时器中断的次数。该循环的 61 次迭代将花费很少的时间。如果没有示波器,您将看不到任何可感知的东西。

以下内容可能更接近您的需要:

void __vector_23 (void)
{
    intrs++;
    if(intrs > 60)
    {
        intrs = 0;
        PORTB = (0xff<<i);

        i++ ;
        if(i == 8 )
        {
            i = 0 ;
            PORTB = 0xff;
        }
    }
}

尽管将比较寄存器 OCR0A 设置为 61(如注释掉的代码中所示)将避免对中断计数器的需要并减少不必要的软件开销。

Your interrupt routine is flawed. intrs counts only the number of times the loop has executed, not the number of timer interrupts as its name suggests. 61 iterations of that loop will take very little time. You will see nothing perceivable without an oscilloscope.

The following may be closer to what you need:

void __vector_23 (void)
{
    intrs++;
    if(intrs > 60)
    {
        intrs = 0;
        PORTB = (0xff<<i);

        i++ ;
        if(i == 8 )
        {
            i = 0 ;
            PORTB = 0xff;
        }
    }
}

Although setting the compare register OCR0A to 61 as in your commented out code would avoid the need for the interrupt counter and reduce unnecessary software overhead.

恋你朝朝暮暮 2024-10-08 02:00:13
  1. 您确定下载到板上的代码没有经过优化吗?
  2. 您是否已将易失性属性附加到 PORTB 标识符?
  3. 有没有办法减慢代码速度(在调试器之外)?有没有可能它正在运行,但速度很快,而您却看不到它?
  4. 您能否验证您想要的代码实际上正在运行(在调试器之外)?
  1. Are you sure that the code downloaded to the board is not optimized?
  2. Have you attached volatile attribute to the PORTB identifier?
  3. Is there a way for you to slow down the code (outside the debugger)? Any chance it's running but fast that you don't see it?
  4. Can you verify that your intended code is in fact running (outside the debugger)?
夜未央樱花落 2024-10-08 02:00:13

当中断发生时,处理程序很快计数 62*9 次,最后将 PORTB 设置为 0x00,因此 LED 只闪烁很短的时间,这是不可见的。您在模拟器中看到它只是因为它运行速度较慢并且不模拟快速端口切换的视觉调光效果。程序有一个设计缺陷:它试图在单个中断中完成完整的闪烁周期。这是错误的——在中断调用中只应该执行一个步骤。所以处理程序应该如下所示:

void __vector_23 (void)
{
    intrs++;
    if(intrs >= 61)
    {
        PORTB = (0xff<<i);
        intrs = 0;
        i++;
        if(i>8) i = 0;
    }
}

试试这个。

关于中断处理程序有一个指导原则:中断处理程序应该尽可能快和短。不要在中断中执行复杂的任务(循环循环就是其中之一,如果中断中出现循环,请尝试将其删除)。不要等待或延迟中断。

When interrupt occurs, handler very quickly counts 62*9 times and finally sets PORTB to 0x00, so leds do only very short flash which is not visible. You see it in sumulator just because it runs slower and do not emulate visual dimming effect of fast port switching. Program has a design flaw: it tries to do full blinking cycle in single interrupt. That's wrong--only a single step should be performed in interrupt call. So handler should look like this:

void __vector_23 (void)
{
    intrs++;
    if(intrs >= 61)
    {
        PORTB = (0xff<<i);
        intrs = 0;
        i++;
        if(i>8) i = 0;
    }
}

Try this.

There is guidelin on interrupts handlers: Interrupt handler should be as fast and short as possible. Do not perform complex tasks in interrupts (cycle loop is one of them, if you get cycle in interrupt, try to remove it). Do not wait or delay in interrupts.

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