Что-то у меня ум за разум заходит. Не удаётся написать тривиальную программу для Arduino UNO. Хочу чтобы светодиод (который на ноге digital 13) моргал.
Алгоритм такой. Есть таймер, который каждые N миллисекунд вызывает прерывание, где добавляет 1 к переменной-счётчику. В основном цикле крутится проверка значения этой переменной. Если значение достигло некоторой величины, то меняем уровень сигнала на digital 13, и обнуляем переменную-счётчик. Вроде бы всё просто, но не работает. ЧЯДНТ?
Да, Arduino, конечно, offtopic на linux'овом сайте. Но надеюсь мне кто-нибудь поможет.
Вот код:
#include <avr/interrupt.h>
int status; // Глобальная переменная в которой лежит состояние светодиода, горит-не_горит.
int tick_counter; // Переменная-счётчик вызовов прерывания.
void init (void) {
cli(); // Запрещаем все прерывания на время инициализации.
DDRB |= (1<<PB5); // Set D13 as output pin.
//PORTB |= (1<<PB5); // Set D13 level high.
status = 0;
tick_counter = 0;
OCR0A = 65535;
TIMSK0 |= (1<<TOIE0); // Включаем прерывание по достижению Timer/Counter0 значения OCR0A.
TCCR0A |= (1<<WGM01) | (1<<WGM00); // Работаем в режиме FastPWM.
TCCR0B |= (1<<WGM02) | (1<<CS02) | (1<<CS00); // Делитель 1/1024. С таким делителем и OCR0A прерывание будет вызываться примерно каждые 4 мс.
sei(); // Закончили инициализацию, разрешаем все прерывания.
}
void run() {
while(1) {
if (tick_counter >= 5) {
if (status == 1) {
PORTB &= ~(1<<PB5);
status = 0;
}
else {
PORTB |= (1<<PB5);
status = 1;
}
tick_counter = 0;
}
}
}
ISR(TIMER0_OVF_vect) {//Обработка прерывания по переполнению Timer/Counter0
tick_counter++;
}
int main(void) {
init();
run();
return 0;
}