Всем привет!
Решил вот сделать ребенку мигающие светодиоды на велосипед (а заодно наконец покодить под микроконтроллеры).
Сам я по професии электрик (не радиотехника), но было это давно. Сечас программист на Java. Си тоже учил, но опять же давно.
Купил я ATMega8A, программатор TL866A и несколько светодиодов. Позапускал пару простых примеров, посмотрел/почитал мануалы и решил приступить к самому главному.
Мигать светодиодами надо программно и чтоб была возможность мигать одновременно с разной частотой.
В связи с этим решил не использовать delay, а сделать правильно, через таймеры.
В общем написал код для таймера, для мигания, отладил в Atmel Studio 6 (AVR Studio) и попытался проэмулировать это дело в протеусе.
Вот тут началось неладное. Светодиоды мигали на глаз со случайной частотой. В отладчике студии время между вызовами таймера примерно совпадает с ожидаемым (+- пару миллисекунд).
Упростил немного код, пробовал менять частоту мигания таймера, ничего не помогает. Я подумал что в протеусе что-то со временем во время эмуляции, и решил проверить на реальной МК.
Но когда залил код в МК, оказалось что на нем светодиод вообще не мигает а просто светит. Думал дело в частоте МК, посмотрел фьюзы, вроде частота такая же как в отладке студии.
Вот код:
Думал что что-то с МК, добавил в основной цикл мигание с delay, примерно такое:
При этом в реальном МК светодиод мигал, но не через 1 секунду, а реже. К стати в это время другие светодиоды (оставшиеся на таймере) тоже мигали, но так же с неправильной частотой (вроде гораздо чаще чем должны).
Прикрепляю схему подключения МК. но при тесте я подключал только один слабенький светодиод с резистором. Всего остального небыло.
Очень прошу вашей помощи в решении этой проблемы.
Раздел: Песочница (Q&A)
Решил вот сделать ребенку мигающие светодиоды на велосипед (а заодно наконец покодить под микроконтроллеры).
Сам я по професии электрик (не радиотехника), но было это давно. Сечас программист на Java. Си тоже учил, но опять же давно.
Купил я ATMega8A, программатор TL866A и несколько светодиодов. Позапускал пару простых примеров, посмотрел/почитал мануалы и решил приступить к самому главному.
Мигать светодиодами надо программно и чтоб была возможность мигать одновременно с разной частотой.
В связи с этим решил не использовать delay, а сделать правильно, через таймеры.
В общем написал код для таймера, для мигания, отладил в Atmel Studio 6 (AVR Studio) и попытался проэмулировать это дело в протеусе.
Вот тут началось неладное. Светодиоды мигали на глаз со случайной частотой. В отладчике студии время между вызовами таймера примерно совпадает с ожидаемым (+- пару миллисекунд).
Упростил немного код, пробовал менять частоту мигания таймера, ничего не помогает. Я подумал что в протеусе что-то со временем во время эмуляции, и решил проверить на реальной МК.
Но когда залил код в МК, оказалось что на нем светодиод вообще не мигает а просто светит. Думал дело в частоте МК, посмотрел фьюзы, вроде частота такая же как в отладке студии.
Вот код:
#include <avr/interrupt.h>
// Установить бит в 1
#define SB(reg, bit) reg |= (1<<bit)
// Установить бит в 0
#define CB(reg, bit) reg &= ~(1<<bit)
// Проверить установлен ли бит
#define VB(reg, bit) reg & (1<<bit)
// Инвертировать бит
#define TB(reg, bit) reg ^= (1<<bit)
// 0b00000001
#define T100MS 0
// 0b00000010
#define T500MS 1
// 0b00000100
#define T1000MS 2
// 0b00001000
#define T2000MS 3
// 0b00010000
#define T5000MS 4
uint8_t timer500ms = 0;
uint8_t timer1000ms = 0;
uint8_t timer2000ms = 0;
uint8_t timer5000ms = 0;
uint8_t dataTimer = 0b00000000;
// Прерывание каждые 100 миллисекунд
// Устанавливает флаг в соответствии с прошедшим временем
ISR(TIMER2_COMP_vect) {
SB(dataTimer, T100MS);
if ((++timer500ms) == 5) {
timer500ms = 0;
SB(dataTimer, T500MS);
}
if ((++timer1000ms) == 10) {
timer1000ms = 0;
SB(dataTimer, T1000MS);
}
if ((++timer2000ms) == 20) {
timer2000ms = 0;
SB(dataTimer, T2000MS);
}
if ((++timer5000ms) == 50) {
timer5000ms = 0;
TB(PORTC, 2);
TB(PORTC, 3);
TB(PORTC, 4);
TB(PORTC, 5);
SB(dataTimer, T5000MS);
}
}
int main(void)
{
DDRB |= 0b00000000;
DDRC |= 0b00111111;
DDRD |= 0b00001111;
// Пределитель 1:1
SB(TCCR2, CS20);
// Режим сброс при совпадении
CB(TCCR2, WGM20);
SB(TCCR2, WGM21);
// Прерывание при совпадении
CB(TIMSK, TOIE2);
SB(TIMSK, OCIE2);
// Количество тактов перед прерыванием
OCR2 = 100; // 1мгц
// Разрешить глобальные прерывания
asm("sei");
while(1)
{
if (VB(dataTimer, T5000MS)) {
// TB(PORTC, 2);
// TB(PORTC, 3);
// TB(PORTC, 4);
// TB(PORTC, 5);
// Сброс времени
CB(dataTimer, T5000MS);
}
}
}
Думал что что-то с МК, добавил в основной цикл мигание с delay, примерно такое:
TB(PORTC, 5);
_delay_ms(1000);
TB(PORTC, 5);
_delay_ms(1000);
При этом в реальном МК светодиод мигал, но не через 1 секунду, а реже. К стати в это время другие светодиоды (оставшиеся на таймере) тоже мигали, но так же с неправильной частотой (вроде гораздо чаще чем должны).
Прикрепляю схему подключения МК. но при тесте я подключал только один слабенький светодиод с резистором. Всего остального небыло.
Очень прошу вашей помощи в решении этой проблемы.
Раздел: Песочница (Q&A)