Правильнее было бы написать PORTB=0x01; Просто потому что так понятнее (для себя), что ты обращаешься именно к порту. Пин - это одна нога МК. Порт - совокупность ног, объединенных под одной буквой (PORTA, PORTB, PORTC).
Теперь по коду:
Код
#include <mega8.h> Мы программируем атмегу8 unsigned int sek; // инициализируем переменную для хранения секунд // далее попробуем обойтись без флага-защелки. Проверять, включен светодиод или нет, будем по самой ноге, на которой он висит.
void main(void) // это называется основным циклом. Все крутится в нем, но в С тела написанных тобой функций располагаются вне него. { PORTB=0x01; // Задействуем нулевую ногу на порте B на выход DDRB=0x01; // этот регистр указывает, какие ноги на порте B работают как выход. // здесь была ошибка, все ноги были выставлены как входы (DDRB=0x00; все равно что DDRB=0b00000000; а 0 - показатель входа).
if(sek>=3) // проверяем, стало ли значение переменной sec больше 3 { if(PIND.0!=1) // если светодиод выключен { PIND.0=1; // включаем светодиод } else // в противном случае (если включен) { PIND.0=0; // выключаем светодиод } sek=0; // а здесь сбрасываем количество насчитанных секунд } } // конец главной функции
До этого у тебя светодиод погас бы сразу же, как только включился - ты бы и не заметил, как он мигнет. Вот только переменная sec у тебя никак не считается, значение в ней само по себе не появится. Нужно прикрутить сюда один из таймеров МК. Делается это как-то вот так:
Код
#include <mega8.h> Мы программируем атмегу8 unsigned int sek; // инициализируем переменную для хранения секунд
// Timer 1 output compare A interrupt service routine interrupt [TIM1_COMPA] void timer1_compa_isr(void) // Timer 1 output compare A interrupt service routine interrupt [TIM1_COMPA] void timer1_compa_isr(void) { TCNT1H=0; TCNT1L=0; sec++; // когда срабатывает прерывание таймера, прибавляем значение переменной sec }
void main(void) // начало основного цикла { PORTB=0x01; // Задействуем нулевую ногу на порте B на выход DDRB=0x01; // этот регистр указывает, какие ноги на порте B работают как выход. // Timer/Counter 1 initialization // Clock source: System Clock // Clock value: 7,813 kHz // Mode: Normal top=FFFFh // OC1A output: Discon. // OC1B output: Discon. // Noise Canceler: Off // Input Capture on Falling Edge // Timer 1 Overflow Interrupt: Off // Input Capture Interrupt: Off // Compare A Match Interrupt: On // Compare B Match Interrupt: Off TCCR1A=0x00; TCCR1B=0x05; TCNT1H=0x00; TCNT1L=0x00; ICR1H=0x00; ICR1L=0x00; OCR1AH=0x1E; OCR1AL=0x85; OCR1BH=0x00; OCR1BL=0x00;
if(sek>=3) // проверяем, стало ли значение переменной sec больше 3 { PIND.0=~PIND.0; // оператором "=~" инвертируем состояние порта (если было 0, станет 1, и наоборот) sek=0; // а здесь сбрасываем количество насчитанных секунд } } // конец главной функции
Витинари, Так то понятней! Гораздо! Спасибо огромное! Одно не понятно, что за коды добавились к таймеру? Можешь указать их значение, для чего они служат, если не трудно Благодарю.
Добавлено (09.04.2015, 20:27) --------------------------------------------- Почему то мигания не происходят, просто горит светодиод..
Когда происходит прерывание: TCNT1H=0; // обнуляем таймер TCNT1L=0; // обнуляем таймер
это
Код
// Timer/Counter 1 initialization // Clock source: System Clock // Clock value: 7,813 kHz // Mode: Normal top=FFFFh // OC1A output: Discon. // OC1B output: Discon. // Noise Canceler: Off // Input Capture on Falling Edge // Timer 1 Overflow Interrupt: Off // Input Capture Interrupt: Off // Compare A Match Interrupt: On // Compare B Match Interrupt: Off TCCR1A=0x00; TCCR1B=0x05; TCNT1H=0x00; TCNT1L=0x00; ICR1H=0x00; ICR1L=0x00; OCR1AH=0x1E; OCR1AL=0x85; OCR1BH=0x00; OCR1BL=0x00;
настройки параметров таймера. По идее, перед самими параметрами в том же порядке даются комментарии (после //), но сам я в них пока не до конца врубаюсь, этот кусок кода скопировал в Сети. Чтобы точнее понять, что к чему, нужно смотреть даташит на 8-ю мегу (не любят в atmel придумывать понятные имена для регистров ).
Цитата[PC
Boil-:D;245277]Почему то мигания не происходят, просто горит светодиод..
а если это:
Код
if(sek>=3) // проверяем, стало ли значение переменной sec больше 3 { PIND.0=~PIND.0; // оператором "=~" инвертируем состояние порта (если было 0, станет 1, и наоборот) sek=0; // а здесь сбрасываем количество насчитанных секунд }
заменить на это:
Код
if(sek>=3) // проверяем, стало ли значение переменной sec больше 3 { if(PIND.0!=1) { PIND.0=1; } else { PIND.0=0; } sek=0; // а здесь сбрасываем количество насчитанных секунд }
Сейчас посмотрел, как в codevision запускать таймеры в мега8 Это безумие какое-то, половина кода вообще на ассемблере написано. Поговаривают еще, что в кодвижн можно настроить прерывания таймеров через мастер создания проекта. Он и сгенерирует готовый код. Создай новый проект, и в окошке CodeWizardAVR перейди на вкладку Timers. И выставь вот такие настройки для Timer1:
Витинари, Я эти настройки уже выставлял, когда секундомер на LCD делал, там там 1 секунда идет 10секунд, не знаю с чем это связанно, возможно фьюзы не выставлены были..
Добавлено (09.04.2015, 21:36) --------------------------------------------- Вообщем, выставил, и все равно не работает..
Добавлено (10.04.2015, 23:14) --------------------------------------------- Вот что я нарыл посмотрев даташит.. У атмеги 8 выход первого таймера на 11 ноге, может этот порт нужно указывать в прошивке??
У атмеги 8 выход первого таймера на 11 ноге, может этот порт нужно указывать в прошивке??
Вряд ли. Таймер генерирует событие прерывания, а уж как ты его (это событие) используешь - дело десятое. Прерывание - это как бы условный сигнал, типа маяка. Он вспыхивает - ты используешь этот свет на свое усмотрение. И от того, откуда к этому маяку идут провода, его свет не меняется. У меня сильное подозрение, что прерывание просто не сбрасывается, вот таймер досчитывает до определенной точки и останавливается.