езда на велосипеде через светодиоды - PullRequest
1 голос
/ 09 ноября 2010

Пожалуйста, помогите мне с этим кодом, он сводит меня с ума.Это очень простая программа с 8-битным таймером, циклически перебирающая все 8 светодиодов (по одному).Я использую плату ATSTK600.

Мои таймеры работают хорошо, я думаю, что есть некоторые проблемы с циклами (когда я отлаживаю эту программу с помощью avr studio-gcc, я вижу, что все светодиоды работают, как я хочу, но когдаЯ передаю его на борт ... светодиоды не мигают).Я схожу с ума от такого поведения.

Вот мой код:

#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)
    {

    }
}

Ответы [ 4 ]

3 голосов
/ 09 ноября 2010

Ваша процедура прерывания ошибочна.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, как в вашем закомментированном коде, позволит избежатьнеобходимость в счетчике прерываний и уменьшении ненужных программных издержек.

1 голос
/ 09 ноября 2010
  1. Вы уверены, что загруженный на плату код не оптимизирован?
  2. Прикрепили ли вы атрибут volatile к идентификатору PORTB?
  3. Есть ли способ замедлить код (вне отладчика)? Есть ли шанс, что он работает, но быстро, что вы его не видите?
  4. Можете ли вы убедиться в том, что заданный код действительно запущен (вне отладчика)?
0 голосов
/ 09 ноября 2010

Когда происходит прерывание, обработчик очень быстро считает 62 * 9 раз и, наконец, устанавливает PORTB на 0x00, поэтому светодиоды делают только очень короткую вспышку, которая не видна.Вы видите это в сумматоре только потому, что он работает медленнее и не эмулирует эффект визуального затемнения при быстром переключении портов.Программа имеет недостаток дизайна: она пытается сделать полный цикл мигания за одно прерывание.Это неправильно - в вызове прерывания должен быть выполнен только один шаг.Поэтому обработчик должен выглядеть следующим образом:

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

Попробуйте это.

На обработчиках прерываний есть руководство: обработчик прерываний должен быть максимально быстрым и коротким.Не выполняйте сложные задачи в прерываниях (цикл цикла является одним из них, если вы получаете цикл в прерывании, попробуйте удалить его).Не ждите и не задерживайте прерывания.

0 голосов
/ 09 ноября 2010

Если вы видите поведение, которое вы хотите при отладке с помощью avr studio-gcc, то это дает вам некоторую уверенность в том, что ваша программа «хороша» (в некотором смысле слова «хорошо»).Похоже, вам нужно сосредоточиться на другой области: в чем разница между вашей средой отладки и вашей автономной загрузкой?

Когда вы выполняете автономную загрузку, знаете ли вы, что ваша программаработает вообще?

Светодиоды мигают или вообще включаются?Вы не говорите прямо в своем вопросе, но этот вопрос может быть очень актуален для процесса отладки.Похоже ли это на правильное поведение, работающее с другой скоростью?Если это так, то ваша программа, вероятно, не выполняет какую-либо инициализацию, которую выполнял отладчик.

При выполнении автономной загрузки программа компилируется с другими настройками по сравнению с версией отладки?Возможно, настройки оптимизации компилятора меняют временные характеристики вашей программы.

(Ваш вопрос был бы лучше, если бы вы дали более подробную информацию о том, что делает автономная загрузка. В общем, кому-то сложно отладить удаленныйсистема, когда им дается мало или нет подробностей о том, что происходит. Все / некоторые светодиоды вообще включаются?)

...