РЕШЕНО Использование таймера1 в Atmega8

Тема в разделе "Микроконтроллеры AVR", создана пользователем a1000, 16 ноя 2019.

  1. a1000

    a1000 Гуру

    Нужно организовать прерывание на таймере 1 по совпадению OCR1A.
    Тактовая частота 8 МГц, используем предделитель 1024, возьмём период в 1 сек.
    Рассчитываю значение для OCR1A 8000000 / 1024 = 7812,5
    Берём 7812 или 0х1Е84
    Заносим в OCR1A
    Код (C++):
    ; настройка OCR1A
        ldi Temp1,0x1E
        out OCR1AH,Temp1
        ldi Temp1,0x84
        out OCR1AL,Temp1
    Остальные регистры
    TCCR1A - 0b00000000
    TCCR1B - 0b00000100
    TIMSK и TIFR- 0b00010000
    В прерывании, для тестирования, просто инвертируем состояние 0 пина порта D и сбрасываем TCNT1
    Код (C++):
    TIM1_COMPA:    ;прерывание по совпадению OCR1A
       
       sbic PORTD, 0  ; проверка состояния светодиода
       rjmp NULL     ; переход если включён
       ldi Temp1, 0b00000001
       rjmp VIVOD     ; переход на вывод
     
    NULL:            
       ldi Temp1, 0b00000000
       
    VIVOD:  
       out PORTD, Temp1

       ; сбрасываем счётчик в ноль
        ldi Temp1,0b00000000
        out TCNT1H,Temp1
        out TCNT1L,Temp1

    reti
    Но светодиод, подключенный к D0 моргает с частотой раза в 2-3 чаще.
    Подскажите где я накосячил.
     
  2. a1000

    a1000 Гуру

    Нашел где накосячил. Предделитель не правильно установил. Надо TCCR1B - 0b00000101
     
    SergeiL и Daniil нравится это.
  3. SergeiL

    SergeiL Оракул Модератор

    Не заметил, там действительно 05h должно быть:
    M8.png

    Я билдером пользуюсь, он корректно регистры проставляет.