Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Микроконтроллеры (MCU) и микропроцессоры (MPU) > TMR0


Автор: fol 23.1.2007, 23:13

Всем привет.
Если кто сможет помогите разобраться.
Возникла проблема такого рода. 
Несколько лет работал исключительно с PIC контроллерами.
Но вот как уже с пол года потихоньку въезжаю в AVR.
Пользую Atmega16. По разным причинам именно этот
камень нравиться. Все шло гладко. Но вот на той неделе понадобилось 
срочно собрать систему управления для одного станка. 
Так себе станок, обычный средней степени киборг, десяток датчиков,
десяток исполнялок, пара кнопок... 
Решил что все на меге16 пойдет. И пошло. Почти.
Затык в том что в определенном месте работы киборга, при определенных
обстоятельствах необходимо выполнять (оценивать) действия в реальном,
человеческом времени. То есть секунды, минуты и т.д.
В общем не проблема. Подумаешь, чай не первый год...
Зарядил TMR0 под это дело. И вот он затык. Полное фиаско.
Так и не удалось откалибровать TMR0 таким образом чтоб он выдавал
прерывания каждые 0,01 сек. сейчас объясню почему.
Ну а управлялку для киборга конечно сделал. Но такой гибрид, что самому
стыдно. Хотя заказчик и не подозревает что его станком мутант 
рулит. Так как работа была очень срочная, цех стоит, люди шатаются,
было некогда делать другую плату. Я подвесил на имеющуюся еще одну с PIC
контроллером. Когда киборг должен работать в реальном времени, 
то AVR контроллер передает управление PICу. после того как PIC
отработает, снова рулит AVR. Мне лично стыдно.
Поэтому, че как, объясните.
А суть вот в чем. 
Обычно, в приложениях под PIC контроллеры, делал так.
Заряжаешь TMR0, и пока он считает, прога гоняет где нибудь, 
например выводит данные на дисплей. Как только TMR0 переполнится,
прога уходит по вектору прерывания, там декрементирует счетный
регистр и снова (если счетный регистр не опустел) валит куда нибудь,
чтоб сделать что нибудь полезное, и не торчать на одном месте. 
Поэтому каждое декрементирование счетного регистра, это есть
период переполнения TMR0. если этот период например равен 9990 мкс,
и нужно его увеличить до 10000 мкс, просто устанавливаешь небольшую
задержку, например перед декрементированием счетных регистров,
тем самым путь проги увеличивается, и дело в шляпе.
Но вот для AVR, оказалось не так. Пытался устанавливать задержки
в разных местах. И вне, и внутри тела обработчика прерываний.
Без толку. Не получается тонкой доводки. Либо вообще счетчик 
куклов (в среде AVR Studio) показывает что куклов не стало больше,
либо сразу, количество куклов переваливает через какую то степень.
То есть еще наблюдается какая то зависимость от установки делителя TMR0.
Извиняйте что так путано объясняю, но уже трудно состредоточится.
Пару дней надо передохнуть.
Может лыжи мои не едут, да и как поедут, с такой зимой.
Уф. Вот лучше приведу кусок тестовой проги, на нем наглядно видно,
что и при установленной паузе "PLUS_PAUZE" и без нее, 
счетчик к-ва куклов показывает одно и то же. 

ВРЕМЯ ПРОХОДА ТЕСТОВОГО МОДУЛЯ:
Без задержки (удалить задержку PLUS_PAUZE)  3584 кукла
С установленной задержкой 3583 - 3585 куклов


;--- Мои вопросы ---

1. Возможно ли плавное (плюс/минус 1 кукл) изменение времени
   прерывания от TMR0.

2. Если возможно, то хотя бы в двух словах, как?





   ;****************************************************************
   ;******** ТЕСТОВЫЙ МОДУЛЬ. Упрощенный (сокращенный) вид *********

.org  0x0012
   ;------ ПРОИЗОШЛО ПЕРЕПОЛНЕНИЕ  TMR0 ----------------------
   ;------ Обработчик прерывания по переполнению Timer0 ------

    rcall  STOP_TMR0        ; Стоп TMR0

    rcall  PLUS_PAUZE       ; Тестовая задержка (+25 куклов)
                                ; Ей пытался затянуть время. Тщетно.


;---->  КОНТРОЛЬНАЯ ТОЧКА ОТНОСИТЕЛЬНО КОТОРОЙ ИЗМЕРЯЛОСЬ ВРЕМЯ
    sbi    PortB,0           ; Установить 1 на выводе PortB,0
;---->  КОНТРОЛЬНАЯ ТОЧКА ОТНОСИТЕЛЬНО КОТОРОЙ ИЗМЕРЯЛОСЬ ВРЕМЯ


    rcall  START_TMR0_64    ; Старт TMR0 (вкл. предделителя 1:64)

    sei                     ; Разрешение прерываний


     ;--- Здесь ожидаем прерывание ---
SNOVA:
    rjmp   SNOVA
     ;--------------------------------

   ;*************** ОКОНЧАНИЕ  ТЕСТОВОГО  МОДУЛЯ *******************
   ;****************************************************************




START_TMR0_64:
   ;************************************************************
   ;============   ЗАПУСТИМ  РАБОТУ  TMR0    ===================
   ;=== УСТАНОВКА ПАРАМЕТРОВ Timer0 с коф. предделителя 1:64 ===

    ldi    Temp, 0b00000000 ; Установка коэффициента деления предделителя
    out    TCCR0, Temp      ; Сейчас выключим делитель. СТОП  TMR0

    ldi    Temp, 0b00000001 ; Таким образом определим, что прерывание
    out    TIMSK, Temp      ; произойдет по ПЕРЕПОЛНЕНИЮ TMR0

    ldi    Temp,  200       ; Предварительная загрузка счетного
    out    TCNT0, Temp      ; регистра TMR0. Для значения 0 можно не
                            ; делать. Так как при сбросе он очищается
    ldi    Temp, 0b00000011 ; Установка-включение коэффициента
    out    TCCR0, Temp      ; деления предделителя (ПУСК ТАЙМЕР)
                            ; Установили коф. = f/64
    ret



STOP_TMR0:
   ;************************************************************
   ;---------------- ОСТАНОВИТЬ  СЧЕТ  TMR0 ----------------------
   ;------- ЗАПРЕТИТЬ ПРЕРЫВАНИЕ ПО ПЕРЕПОЛНЕНИЮ TMR0 ------------

    ldi    Temp, 0b00000000 ; Выключим предделитель, таким образом
    out    TCCR0, Temp      ; остановим работу  TMR0

    ldi    Temp, 0b00000000 ; 
    out    TIMSK, Temp      ; ЗАПРЕТИТЬ ПРЕРЫВАНИЕ ПО ПЕРЕПОЛНЕНИЮ TMR0

    ret

    .EXIT


Все, устал...


Автор: Alexei 24.1.2007, 11:56
Цитата(fol @  23.1.2007,  23:13 Найти цитируемый пост)
1. Возможно ли плавное (плюс/минус 1 кукл) изменение времени
   прерывания от TMR0.

Вам надо использовать прерывание не по "переполнению", а по совпадению.
Загружаете один раз нужное число в регистр OCRx и выбираете прерывание.
И возможно, Вам лучше использовать 16 разрядный таймер.
Но если Вы используете предделитель,  то  изменение времени  возможно только кратно ему.

Автор: PILOT 26.1.2007, 01:34
Алексей прав.

Если лень заниматься программированием, то займитесь подбором кварца smile
Но при нормальной частоте кварца всегда можно достичь требуемых отсчетов времени (если они не крошечные и сравнимы с частотой кварца).

СУВ.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)