"неравномерно" Идущие Часы - Проблема С Контроллером

27-11-2013, 14:09 От: admin Посмотрели: 790
Добрый день! Собрал часы по инструкции из статьи http://habrahabr.ru/post/130594/. К проекту прилагается только исходный код, поэтому откомпилировал в Code::Blocks, прошил с помощью USBasp. Но вот беда, часы идут очень медленно (приблизительно раз в 10 медленнее реального времени). Сначала думал кварц не тот, проверил в Протеусе - то же самое. Думаю ошибка в программе, но мои знания в AVR весьма поверхностны, что бы ее найти. Смотрю на код - вроде все нормально, а на деле - не работает. Помогите, кто чем может. Заранее спасибо.


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

// таблица длительностей интервалов (в тиках)
const uint8_t intervals [] __attribute__ ((progmem)) =
{
0x01, 0x05, 0x04, 0x04,
0x05, 0x09, 0x04, 0x02,
0x09, 0x02, 0x02, 0x07,
0x02, 0x03, 0x03, 0x03,

0x03, 0x05, 0x05, 0x07,
0x04, 0x06, 0x07, 0x01,
0x02, 0x01, 0x05, 0x02,
0x03, 0x03, 0x0C, 0x04,

0x06, 0x02, 0x01, 0x0D,
0x02, 0x03, 0x04, 0x03,
0x01, 0x01, 0x06, 0x04,
0x06, 0x04, 0x02, 0x06,

0x02, 0x04, 0x06, 0x01,
0x07, 0x04, 0x02, 0x02,
0x01, 0x05, 0x03, 0x04
};

ISR (TIM0_COMPA_vect) // Прерывание по таймеру
{
static uint8_t polarity =0;
static uint8_t tick_no =0;
static uint8_t next_tick_no =0;
static uint8_t interval_no =0;

if (tick_no == next_tick_no)
{

if (polarity)
{ // положительный импульс
PORTB |= (1 << 2)|(1 << 4);
}
else
{ // отрицательный импульс
PORTB |= (1 << 0)|(1 << 1);
}
polarity ^= 0x01;

if (interval_no < 59)
{
next_tick_no += intervals [interval_no];
interval_no++;
}
else
{ // началась новая минута
next_tick_no = 0;
interval_no = 0;
}
}

if (tick_no < 239)
tick_no ++;
else
tick_no = 0;
}

ISR (TIM0_COMPB_vect) // Второе прерывание, через 100 мс после первого
{ // отключаем двигатель
PORTB &= ~((1 << 0)|(1 << 1)|(1 << 2)|(1 << 4));
}

void main(void) __attribute__((noreturn));

void main(void)
{
DDRB |= (1 << 0)|(1 << 1)|(1 << 2)|(1 << 4);
TCCR0A = (1 << WGM01); // режим работы таймера "сброс по совпадению"
TCCR0B = (1 << CS02); // предделитель таймера 1/256
OCR0A = 0x1F; // Верхняя граница счета
// 32768 / 256 / 0x20 = 4 Hz - частота следования прерываний
OCR0B = 0x0С; // примерно 100 мс от сброса счетчика до второго прерывания
TIMSK0 = (1 << OCIE0A)|(1 << OCIE0B); // разрешить прерывания по таймеру
set_sleep_mode (SLEEP_MODE_IDLE);
sei (); // глобальное разрешение прерываний
for (;;)
sleep_enable (); // в спячку!
}

Раздел: AVR

Уважаемый посетитель, Вы зашли на сайт как незарегистрированный пользователь.
Мы рекомендуем Вам зарегистрироваться, либо войти на сайт под своим именем.

Обсудить на форуме


На момент добавления "неравномерно" Идущие Часы - Проблема С Контроллером все ссылки были рабочие.
Все публикации статей, книг и журналов, представлены на этом сайте, исключительно для ознакомления,
авторские права на эти публикации принадлежат авторам статей, книг и издательствам журналов!
Подробно тут | Жалоба
Информация
Посетители, находящиеся в группе Гости, не могут оставлять комментарии к данной публикации.


Опрос

Ваши предпочтения в TRX


Одинарное преобразование
Двойное преобразование
Прямое преобразование
SDR
Другое
Мне всё равно

Популярные новости
Календарь новостей
«    Май 2024    »
ПнВтСрЧтПтСбВс
 12345
6789101112
13141516171819
20212223242526
2728293031