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

Обсуждаем контроллеры компании Atmel.
Ответить
Нашел транзистор. Понюхал.
Аватара пользователя
Сообщения: 183
Зарегистрирован: Вт сен 14, 2010 23:07:10
Откуда: Ростов

Сообщение baron_P »

Спасибо, понято. Эту строчку я пропустил "The counter counts from BOTTOM to TOP (defined as OCR1C) then restarts from BOTTOM".
We do what we must because we can (c) GLaDOS
Реклама
Друг Кота
Аватара пользователя
Сообщения: 20093
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Сообщение Gudd-Head »

GreenDer писал(а):подскажите в какую сторону копать.
Поставить RTC.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Реклама
Первый раз сказал Мяу!
Сообщения: 25
Зарегистрирован: Ср авг 20, 2014 17:15:53

Сообщение GreenDer »

Gudd-Head писал(а):
GreenDer писал(а):подскажите в какую сторону копать.
Поставить RTC.
Понял, спасибо.
Хотелось-бы конечно средствами самого контроллера это организовать, но если иначе никак то ладно.
Друг Кота
Аватара пользователя
Сообщения: 20093
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Сообщение Gudd-Head »

GreenDer писал(а):Хотелось-бы конечно средствами самого контроллера это организовать
Вы, извините, хотите и на ёлку влезть, и жопу не ободрать.
Если жалко таймер заюзать, можно извратиться и какой-нибудь внешней RC-цепочкой периодически вызывать внешнее прерывание и инкрементировать переменную. Точность будет нувыпонели.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Реклама
Эиком - электронные компоненты и радиодетали
Первый раз сказал Мяу!
Сообщения: 25
Зарегистрирован: Ср авг 20, 2014 17:15:53

Сообщение GreenDer »

Gudd-Head писал(а):
GreenDer писал(а):Хотелось-бы конечно средствами самого контроллера это организовать
Вы, извините, хотите и на ёлку влезть, и жопу не ободрать.
Именно так и хотел :) Но прийдётся юзать RTC.
Реклама
Друг Кота
Аватара пользователя
Сообщения: 20093
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Сообщение Gudd-Head »

GreenDer писал(а):Но прийдётся юзать RTC.
Коллеги подсказывают как для счёта можно обойтись средствами МК, не задействуя таймеры:
http://radiokot.ru/forum/viewtopic.php? ... 5#p2108695
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Реклама
Первый раз сказал Мяу!
Сообщения: 25
Зарегистрирован: Ср авг 20, 2014 17:15:53

Сообщение GreenDer »

Гм... Интересно. Уже читаю.
Спасибо :)
Последний раз редактировалось ibiza11 Ср авг 27, 2014 11:50:38, всего редактировалось 2 раза.
Причина: 2.7 Запрещается бездумное вложенное цитирование, а так же полное, бессмысленное цитирование предыдущего поста.
Открыл глаза
Аватара пользователя
Сообщения: 54
Зарегистрирован: Пт окт 03, 2014 14:41:16

Сообщение alexan9er »

Здравствуйте!
У меня очень загадошная проблема, нужен совет опытных товарищей!
МК atmega328p-pu.

Сначала написал простую программку для мигания светодиодом - без таймеров, пауза выдерживается циклом. Всё ОК. И в PROTEUS и на макетке.

Написал вторую - через таймер 1, прерывание по порогу компаратора, таймер от встроенного генератора. В PROTEUS работает отлично, на макетке же очень странно: иногда помигает и замрёт либо со включённым, либо с выключенным светодиодом. Причём если нажать на МК пальцем, начинает отлично мигать! Такое впечатление что он об меня заземляется. Если положить на подоконик или на металлический крашеный корпус системника - тоже работает! Только снимаю - опять глюки.

Добавил резистор 10 КОм на RESET к питанию, конденсатор 24 мФ на землю ему - не помогает.
Что за фокусы?
Помогите плз, вчера всю ночь с ним воевал =)
Опытный кот
Аватара пользователя
Сообщения: 721
Зарегистрирован: Ср июн 11, 2014 09:43:13
Откуда: США

Сообщение Pink-Pank »

а на компаратор прерывание Вы как заводите? подтяжка ноги компаратора к какому-либо уровню есть? или оно в воздухе висит?
Fucking static initialization order fiasco
Контактная информация:
Открыл глаза
Аватара пользователя
Сообщения: 54
Зарегистрирован: Пт окт 03, 2014 14:41:16

Сообщение alexan9er »

Я похоже некорректно выразился. Я имел ввиду что прерывание по счётчику таймера, не по переполнению.
В ходе экспериментов я пришел к выводу что какие-то электромагнитные наводки. Достаточно руку рядом поднести к МК и начинает работать как ожидается. Очень странно, ни у кого такого не было?
Опытный кот
Аватара пользователя
Сообщения: 721
Зарегистрирован: Ср июн 11, 2014 09:43:13
Откуда: США

Сообщение Pink-Pank »

Уровень питания какой? При низком уровне и высокой частоте может быть сильное влияние окружающего ЭМИ. Если есть кварц - пропаяйте хорошо дорожки от него к МК, заземлите его корпус и почистите от флюса плату. А в целом, ищите косяк в своей схемотехнике - чудеса бывают, но очень редко. А в Вашем случае (новичек в МК) - шанс 1 на миллиард.
Fucking static initialization order fiasco
Контактная информация:
Открыл глаза
Аватара пользователя
Сообщения: 54
Зарегистрирован: Пт окт 03, 2014 14:41:16

Сообщение alexan9er »

Питание от USB порта, использую только питание и землю. Что и где мерять по уровню питания? Я думал что USB даёт достаточно стабильный ток.
Собрано всё на макетке в которую просто всё втыкается, поэтому пропаивать не получится.
Схема простая - на одной ноге висит светодиод с резистором.
Попробую запрограмировать на низкую частоту таймера, сейчас на 10 МГц.
А как теоретически влияет ЭМИ? Он перезагружается или что?
Опытный кот
Аватара пользователя
Сообщения: 721
Зарегистрирован: Ср июн 11, 2014 09:43:13
Откуда: США

Сообщение Pink-Pank »

При низком питании могут меняться внутреннее содерджимое ячеек памяти. Т.е. будут сбои в работе, неправильные инструкции, ошибочные данные и т.д. Но для этого нужен очень большой уровень помех (например, запуск вблизи мощного электрического двигателя) . В обычном окружении такого нет.
Fucking static initialization order fiasco
Контактная информация:
Открыл глаза
Аватара пользователя
Сообщения: 54
Зарегистрирован: Пт окт 03, 2014 14:41:16

Сообщение alexan9er »

Может быть меня облучают а я и не знаю =)
Имеет смысл втыкать стабилизатор напряжения? Или USB от компа даёт априори стабильное питание? Пробовал также от розетки адаптер USB - та же картина.
Опытный кот
Аватара пользователя
Сообщения: 721
Зарегистрирован: Ср июн 11, 2014 09:43:13
Откуда: США

Сообщение Pink-Pank »

Не имеет. В компе напряжение достаточно стабильно. Процентов на 90 - косяк во внешней обвязке. Бывают, например, микротрещины в дорожках и из-за них устройство работает не правильно. А если дорожку пропаять - становится все хорошо. Бывает, плохой контакт спаянных деталей. Например, паяли без флюса и плохо прогрели. В результате капля олова на деталях есть, а контакта нет. Вот, еще посмотрите по поводу борьбы с шумами: http://www.williamson-labs.com/480_byp.htm
Fucking static initialization order fiasco
Контактная информация:
Открыл глаза
Аватара пользователя
Сообщения: 54
Зарегистрирован: Пт окт 03, 2014 14:41:16

Сообщение alexan9er »

Спасибо за ссылку!
По поводу обвязки - та же схема при другой прошивке работает корректно (когда светодиодом моргаю через задержку, без использования таймера). Прошивку меняю через ISP, ничего не вынимаю не втыкаю.
Получается что дело всё-таки во внутреннем таймере МК.
Опытный кот
Аватара пользователя
Сообщения: 721
Зарегистрирован: Ср июн 11, 2014 09:43:13
Откуда: США

Сообщение Pink-Pank »

маловерятно это. Очень маловероятно. Скиньте архив с кодом.
Fucking static initialization order fiasco
Контактная информация:
Открыл глаза
Аватара пользователя
Сообщения: 54
Зарегистрирован: Пт окт 03, 2014 14:41:16

Сообщение alexan9er »

Извиняюсь, не заню как тут архив прикладывать.
Код вот.
Спойлер

Код: Выделить всё

/*
 * ledblinktimer.asm
 *
 * Created: 02.10.2014 1:34:25
 * Author: Alexander
 */ 

.device     ATMEGA328P
.include    "m328Pdef.inc"
.def        VarReg = R16 ; технологический регистр
.def        ViewReg = R18 ; регистр состояния порта B

.cseg
.org 0

; векторы прерываний
.org 0x000  rjmp    RESET           ; Reset Handler
.org 0x002  reti                    ; IRQ0 Handler
.org 0x004  reti                    ; IRQ1 Handler
.org 0x006  reti                    ; PCINT0 Handler
.org 0x008  reti                    ; PCINT1 Handler
.org 0x00A  reti                    ; PCINT2 Handler
.org 0x00C  reti                    ; Watchdog Timer Handler
.org 0x00E  reti                    ; Timer2 Compare A Handler
.org 0x010  reti                    ; Timer2 Compare B Handler
.org 0x012  reti                    ; Timer2 Overflow Handler
.org 0x014  reti                    ; Timer1 Capture Handler
.org 0x016  reti                    ; Timer1 Compare A Handler
.org 0x018  rjmp    INTTIM1COMPB    ; Timer1 Compare B Handler
.org 0x01A  reti                    ; Timer1 Overflow Handler
.org 0x01C  reti                    ; Timer0 Compare A Handler
.org 0x01E  reti                    ; Timer0 Compare B Handler
.org 0x020  reti                    ; Timer0 Overflow Handler
.org 0x022  reti                    ; SPI Transfer Complete Handler
.org 0x024  reti                    ; USART, RX Complete Handler
.org 0x026  reti                    ; USART, UDR Empty Handler
.org 0x028  reti                    ; USART, TX Complete Handler
.org 0x02A  reti                    ; ADC Conversion Complete Handler
.org 0x02C  reti                    ; EEPROM Ready Handler
.org 0x02E  reti                    ; Analog Comparator Handler
.org 0x030  reti                    ; 2-wire Serial Interface Handler
.org 0x032  reti                    ; Store Program Memory Ready Handler

; инициализация
RESET:
            cli

            ; грузим признак выхода в регистр управления портом "B"
            ldi     VarReg, 0b11111111
            out     DDRB, VarReg

            ; начальное состояние порта
            ldi     ViewReg, 0b00000010
            out     PORTB, ViewReg

            ; разрешить прерывание компаратора B
            ldi     VarReg, 0b00000100
            sts     TIMSK1, VarReg

            ; тактовая частота 8 МГц
            ; требуемая частота срабатывания прерывания 1 сек
            ; делитель 256
            ; значение компаратора 0x7A12

            ; тактовый сигнал = CK/256
            ldi     VarReg, 0b00000100
            sts     TCCR1B, VarReg

            ; инициализация порога компаратора B
            ldi     VarReg, 0x7A
            sts     OCR1BH, VarReg
            ldi     VarReg, 0x12
            sts     OCR1BL, VarReg

            ; установка указателя стека
            ldi     VarReg, high(RAMEND)
            sts     SPH, VarReg
            ldi     VarReg, low(RAMEND)
            sts     SPL, VarReg

            ; обнуление таймера
            ldi     VarReg, 0
            sts     TCNT1H, VarReg
            sts     TCNT1L, VarReg

            sei

; основной цикл
BEGIN:
            sleep
            rjmp    BEGIN

; прерывание компаратора B первого таймера
INTTIM1COMPB:
            ; обнуление таймера
            ldi     VarReg, 0
            sts     TCNT1H, VarReg
            sts     TCNT1L, VarReg

            ; инвертируем 1-й бит порта B
            ldi     VarReg, 0b00000010
            eor     ViewReg, VarReg
            out     PORTB, ViewReg

            reti

END:
Опытный кот
Аватара пользователя
Сообщения: 721
Зарегистрирован: Ср июн 11, 2014 09:43:13
Откуда: США

Сообщение Pink-Pank »

Клевая книжка, по которой учитесь! Все довольно четко. Единственное, не совсем привычны названия регистров, используемых автором.

Итак, замечания по программе:
1. В режиме таймера Сброс По Совпадению для точного счета в регистр сравнения записывать необходимо число на единицу меньшее, чем требуемое количество тактов (забываете про 0).
2. Обнулять регистр счета таймера в прерывании не обязательно - он обнуляется автоматически.
3. Инвертирование бита порта B можно сделать проще (работает только в современных моделях, появилось недавно):

Код: Выделить всё

out PINB, ViewReg
4. Забыли отключить сторожевой таймер - контроллер периодически будет сбрасываться.
5. Необязательно ставить заглушки на все прерывания. По умолчанию во флеш 0x0000 - соответствует инструкции nop (ничего не делать). Т.е. Можно объявить так:

Код: Выделить всё

.org 0x000  rjmp    RESET           ; Reset Handler
.org 0x016  reti                    ; Timer1 Compare A Handler
.org 0x018  rjmp    INTTIM1COMPB    ; Timer1 Compare B Handler
.org 0x032  reti                    ; Store Program Memory Ready Handler
6. Вместо

Код: Выделить всё

ldi     VarReg, 0b00000100
куда удобнее писать

Код: Выделить всё

ldi     VarReg, (1<<2)
заместо понятнее написать соответственно, инициализация будет выглядеть так:

Код: Выделить всё

; инициализация порога компаратора B
            ldi     VarReg, high(31249) ; помним про -1
            sts     OCR1BH, VarReg
            ldi     VarReg, low(31249)
            sts     OCR1BL, VarReg
вместо какого-нибудь

Код: Выделить всё

ldi     VarReg, 0b00000100
sts     TCCR1B, VarReg
понятнее будет

Код: Выделить всё

ldi     VarReg, (1<<CS12) | (0<<CS11) | (0<<CS10);
sts     TCCR1B, VarReg
7. Стек лучше инициализировать сразу после сброса, а не потом (Сразу же после команды запрета прерываний).
8. А где Вы выбрали режим работы таймера по совпадению????
9. И где Вы разрешили переход в спящий режим?
10. Добавить файл к сообщению можно выбрав его, нажав соответствующую кнопку под окном сообщения во время его создания/редактирования. Прокрутите окошко браузера немного вниз, если не видите данной кнопки.
Fucking static initialization order fiasco
Контактная информация:
Открыл глаза
Аватара пользователя
Сообщения: 54
Зарегистрирован: Пт окт 03, 2014 14:41:16

Сообщение alexan9er »

Спасибо за советы! Например про то что CS12 объявлены уже в .inc я и не додумался, очень удобные приёмы вы показали!
Непонятно следующее:
п. 4 - я думал сторожевой таймер отключается фьюзом WDTON, я его выставил в 1. Теперь я вижу что нужно было ещё в WDTCSR биты WDE и WDIE выставить в 0 - этого достаточно?
п. 8 - я выставил в TIMSK1 бит OCIE1B в 1 - в даташите написано что так разрешается прерывание таймера (Timer/Counter1 Output Compare B Match interrupt is enabled). Это разве не то что требуется?
п. 9 - честно говоря я просто нашёл эту команду и думал что она означает "ждать прерывание и ничего не делать". В примере который я использовал был просто пустой цикл и мне это не понравилось =) Как её правильно использовать?
Ответить

Вернуться в «AVR»