Обсуждаем контроллеры компании Atmel.
Ответить

Re: Таймеры/счётчики в AVR

Сб ноя 10, 2018 06:02:17

Да можно же в конфигураторе Codevision AVR мышкой пощелкать и посмотреть какие режимы доступны ))

Режимы чего?

Re: Таймеры/счётчики в AVR

Сб ноя 10, 2018 06:10:52

Проверил в железе на tiny2313 (Т1 не отличается mega16, встроенный генератор 4МГц). Вывод OC1A на PB3. Действительно, низкий уровень на OC1A представляет собой волос, которого хватает только для запуска осциллографа. Работает только программа с переключением.

Re: Таймеры/счётчики в AVR

Сб ноя 10, 2018 07:18:18

В самый первый проход цикла все нормально - "0" держится на OC1A, пока счетчик не досчитает до конца.
В конце цикла производится остановка таймера/счетчика, OC1A сбрасывается в "0", возврат в начало цикла, новая инициализация и запуск. И вот тут "1" появляется сразу же.
Может есть какой-то порядок запуска/остановки T/C1? Последовательность действий, которую я не соблюдаю. Может, паузу давать надо после остановки и до нового запуска, или еще что...

Re: Таймеры/счётчики в AVR

Сб ноя 10, 2018 08:40:16

Думаю, отключить COM не значит изменить память его состояния. Поэтому, когда вновь разрешается COM на лапу выводится запомненное состояние??? Переключения лапы PB3/OC1A (PD5 для mega16) добился явным указанием режима работы на сброс при сравнении.
Спойлер
Код:
.include "tn2313adef.inc"

.equ   Fo=4000000
;***** Определения портов В/В *****
;Port D:

.equ   DIRD   =0b00100000
.equ   PUPD   =0b00000000
.def   zero=R15

.CSEG
.org   $000
;      rjmp   RESET      ;Сброс вектор


;***** Программное выполнение начинается здесь *****

RESET:
;   ldi      r16,high(RAMEND)   ;назначить стек
;      out      SPH,r16;
;      ldi      r16,low(RAMEND)
;      out      SPL,r16

;*********************
;Установка портов В/В:
   SBI   DDRB,3

START:
   LDI   R16,HIGH(5*Fo/10/64-1)   ; (5*Fo/10/64-1)= 0.5 секунды
   OUT   OCR1AH,R16
   LDI   R16,LOW(5*Fo/10/64-1)
   OUT   OCR1AL,R16

   CLR   ZERO

Cycle:
      ldi      r16,(1<<COM1A1)|(1<<COM1A0)
      out      TCCR1A,r16

      ldi      r16,(1<<WGM12)|(1<<CS11)|(1<<CS10)
;Установить бит WGM12=1 (режим CTC). Предделитель CK/64 (CS12=0, CS11=1, CS10=1)
      out      TCCR1B,r16
;***********************************

   IN   ZL,TIFR
   SBRS   ZL,OCF1A
   RJMP   PC-2

   OUT   TIFR,ZL

   ldi      r16,1<<COM1A0
   out      TCCR1A,r16

   IN   ZL,TIFR
   SBRS   ZL,OCF1A
   RJMP   PC-2

   OUT   TIFR,ZL

   RJMP   START
.EXIT

Re: Таймеры/счётчики в AVR

Сб ноя 10, 2018 18:22:27

Я вот такое придумал.
Устанавливаю счетчик как обычно (OC1A=0), он считает 0.3 сек и переключает OC1A в 1.
Потом задержка ~0.3 сек. Потом счетчик перенастраиваю так, чтобы при совпадении он обнулил OC1A (для этого предделитель ставлю CK/1 и OCR1AL=1 - чтоб он быстро все это сделал). Потом возврат в начало и опять считает до появления "1". Завтра буду проверять.

Спойлер
Код:
.CSEG

.equ   Fo=4000000

;***** Определения портов В/В *****
;Port D:

.equ   DIRD   =0b00100000
.equ   PUPD   =0b00000100

;***** Векторы Прерываний *****

.CSEG
.org   $000
      rjmp   RESET      ;Сброс вектор

.org   $002
      reti
.org   $004
      reti
.org   $006
      reti
.org   $008
      reti
.org   $00A
      reti
.org   $00C
      reti
.org   $00E
      reti
.org   $010
      reti
.org   $012
      reti
.org   $014
      reti
.org   $016
      reti
.org   $018
      reti
.org   $01A
      reti
.org   $01C
      reti
.org   $01E
      reti
.org   $020
      reti
.org   $022
      reti
.org   $024
      reti
.org   $026
      reti
.org   $028
      reti

;***** Программное выполнение начинается здесь *****

RESET:   ldi      r16,high(RAMEND)   ;назначить стек
      out      SPH,r16
      ldi      r16,low(RAMEND)
      out      SPL,r16

;*********************
;Установка портов В/В:

      ldi      r16,DIRD
      out      DDRD,r16   ;установка направления PORTD
      ldi      r16,PUPD
      out      PORTD,r16   ;инициализация PORTD

;*********************



START:   

;Установка таймера
Cycle:   ldi      r16,HIGH(3*Fo/10/64-1)         ;(3*Fo/10/64-1) = 0.3 секунды
      out      OCR1AH,r16
      ldi      r16,LOW(3*Fo/10/64-1)
      out      OCR1AL,r16

      ldi      r16,(1<<WGM12)|(0<<CS12)|(1<<CS11)|(1<<CS10)   ;Установить бит WGM12=1 (режим CTC). Предделитель CK/64 (CS12=0, CS11=1, CS10=1)
      out      TCCR1B,r16

      ldi      r16,(1<<COM1A1)|(1<<COM1A0)      ;При совпадении (CTC) вывод OC1A устанавливается в "1"
      out      TCCR1A,r16                  ;Записать регистр управления таймером/счетчиком TCCR1A

      ldi      r16,1<<PSR10               ;Сбросить предделитель для всех таймеров/счетчиков
      out      SFIOR,r16

      ldi      r16,(1<<OCF1A)|(1<<OCF1B)      ;Сбросить флаги
      out      TIFR,r16
      
      clr      r16                        ;Обнулить счетчик
      out      TCNT1H,r16
      out      TCNT1L,r16

;***********************************
;Задержка
Tim_dl:   ldi      r20,$08
      ldi      r21,$60
      ldi      r22,$18

D_r_1x:   sbic   PIND,5
      nop
      dec      r22
      brne   D_r_1x
      ldi      r22,$FF
      dec      r21
      brne   D_r_1x
      ldi      r21,$FF
      dec      r20
      brne   D_r_1x

;***********************************
;Обнулить вывод OC1A Timer/Counter1:
      ldi      r16,(1<<COM1A1)|(0<<COM1A0)      ;Перенастройка T/C1 - обнулить OC1A при совпадении
      out      TCCR1A,r16

      ldi      r16,(1<<WGM12)|(0<<CS12)|(0<<CS11)|(1<<CS10)   ;Предделитель CK/1 (для быстрого счета)
      out      TCCR1B,r16

      ldi      r16,$00
      out      OCR1AH,r16
      ldi      r16,$01
      out      OCR1AL,r16

      clr      r16                                 ;Обнулить счетчик
      out      TCNT1H,r16
      out      TCNT1L,r16

      ldi      r16,(1<<OCF1A)|(1<<OCF1B)               ;Сбросить флаги
      out      TIFR,r16

;***********************************

      rjmp   Cycle


Добавлено after 23 minutes 36 seconds:
Ну понятно, решение одно. :) Ну и хорошо.

akl, а как рассчитать время задержки по вашему примеру?
Код:
   LDI   R20,BYTE3(Fo/5)
   LDI   R21,BYTE2(Fo/5)
   LDI   R22,BYTE1(Fo/5)
LOOP:
   SUBI   R22,BYTE1(1)
   SBCI   R21,BYTE2(1)
   SBCI   R20,BYTE3(1)
   BRNE   LOOP

Re: Таймеры/счётчики в AVR

Вс ноя 11, 2018 04:28:32

Просто считаете такты выполнения цикла LOOP и заносите в регистры время выдержки деленное на это число тактов.
Код:
   LDI   R20,BYTE3(6*Fo/10/5)
   LDI   R21,BYTE2(6*Fo/10/5)
   LDI   R22,BYTE1(6*Fo/10/5)   ;0,6 секунды
LOOP:
   SUBI   R22,BYTE1(1)   ;1 такт
   SBCI   R21,BYTE2(1)   ;1 такт
   SBCI   R20,BYTE3(1)   ;1 такт
   BRNE   LOOP         ;2 такта
;цикл занимает 5 тактов

Re: Таймеры/счётчики в AVR

Пн дек 24, 2018 16:55:37

Муррр, усатые!

Кому-то удалось затактировать модуль USI от таймера T0? В режиме I2C в симуляторе вроде и 4-бит счетчик считает и на прерывание уходит, вроде как и сдвиговый регистр сдвигает данные к выходу. Но нога SCK не дрыгается, на ноге DATA данных тоже нет. В железе так же. Такое ощущение, что выходные драйверы отвязаны от пинов в режиме тактирования от таймера. Может, оно только для режима SPI предназначено? Самое что мурррргрюмое, в дашике ни слова о том, как связаны регистры PORT и модуль USI.

Re: Таймеры/счётчики в AVR

Вт дек 25, 2018 13:53:18

А почему в ATtiny2313 (таймер №1) канал совпадения “A” генерит прерывания многократно, а “B” генерит только единожды? Традиционно-тинийские удешевления?

Re: Таймеры/счётчики в AVR

Вт дек 25, 2018 13:57:23

это как это? вроде оба канала идентично себя ведут

Re: Таймеры/счётчики в AVR

Вт дек 25, 2018 14:00:37

Может и непрерывно в зависимости от настройки. Может вообще без прерываний, если выводить на OC1B.

Re: Таймеры/счётчики в AVR

Вт дек 25, 2018 14:11:43

Да, забыл добавить, что режим CTC - сброс при совпадении (не ШИМ, не вэйв). Сделал секундное мигание светодиодом (подпрога меняет Т-флаг и порт) от "A" мигает, от "B" только зажигается и горит... :dont_know:

Re: Таймеры/счётчики в AVR

Вт дек 25, 2018 14:15:40

экстрасенсы все в отпуске... я просто угадываю: у вас ошибка в коде :)))

Re: Таймеры/счётчики в AVR

Вт дек 25, 2018 14:23:01

Хм..., но код то не меняю, меняю только выбор железа "A" или "B". Может контрик "битый"? И в даташите (стр.106, таблица 46) мод 4, прописано только OCR1A... (а не OCRnA или CTCn, как в более мощных контриках) :dont_know:
Последний раз редактировалось Серый_ Вт дек 25, 2018 14:39:26, всего редактировалось 1 раз.

Re: Таймеры/счётчики в AVR

Вт дек 25, 2018 14:39:06

Можно попробовать режим 12.

Re: Таймеры/счётчики в AVR

Вт дек 25, 2018 14:51:15

если мне не изменяет память, у 2313 в режиме стс верхней границей всегда является OCR1A (нет для этого отдельного регистра). А когда с "Б" работаешь в "А" что записано?

Re: Таймеры/счётчики в AVR

Вт дек 25, 2018 15:00:52

Можно попробовать режим 12.

Имхо не оно, это о "каптуре эвенте" (основная суть почему "B" дурит?)
...верхней границей всегда является OCR1A (нет для этого отдельного регистра). А когда с "Б" работаешь в "А" что записано?

Да и в "A" и в "B" подсовываю делитель "15625", в любой незаюзанный из них = ничего не залито (временно 1 МГц внутка, предмасштабатор /64, /15625 получим 1 сек.)

Re: Таймеры/счётчики в AVR

Вт дек 25, 2018 15:26:19

т.к. тор=ocr1a, то делитель надо записывать в "а" в любом случае.

Добавлено after 3 minutes 4 seconds:
либо тор=icr1 (режим 12) и делитель записать в icr (только ногу захвата придется заземлить, иначе делитель собьётся) в этом случае регистры "а" и "б" будут равнозначными (если оно тебе надо).

Re: Таймеры/счётчики в AVR

Вт дек 25, 2018 15:45:44

В таблице написано значение MAX (что не есть значение TOP). Получается в "A" можно/нужно записывать значение FFFF или не меньшее чем в "B" (15625)? Иначе говоря, если "B" запустили, но "A" уже нельзя использовать "вольно" или с меньшим значением? :dont_know:

Re: Таймеры/счётчики в AVR

Вт дек 25, 2018 15:57:32

в режиме СТС, ТОР=OCR1A на скорость хода твоих часов может повлиять только значение в "а", значение в "б" может повлиять только на фазу (опережение/отставание прерывания б от прерывания а) если "б" меньше или равно "а". если б>а то прерывание б вообще не будет вызываться.

Re: Таймеры/счётчики в AVR

Вт дек 25, 2018 16:28:46

Нда, ребят, вот вам и "2 равноценно независимых..." :))) Практика показала, включаем только "B", в "A" просто лежит...:
1) ...делитель тоже что и в "B" = светодиод мигает посекундно/нормально
2) ...FFFF = светодиод мигает с интервалом в несколько секунд
3) ...меньше чем в "B" = процесс не идёт
Спс за разъяснения. Я бы это назвал функцией "удешевлённо-битого контроллера"... :)))
Ответить