Привет всем, у меня вопрос такой: можно ли "склеить" 2 таймера на Меге8 - таймер1 и таймер2 с расчётом получить 24 битный таймер? Необязательно напрямую, можно через прерывания, например, таймер2 по переполнению а таймер1 работал бы в режиме СТС?. Просто нехватает точности 16-разрядного. Мне нужен 1-секундный интервал. Сейчас имею: частота ядра 16Мгц от внешнего генератора SG51P, предделитель 1/256, считаем до 62500. Получаю слишком длинную секунду. При 62499 - слишком короткую. Вот и думаю, если выключить прескалер и склеить таймеры, можно было бы иметь секунду с точностью 0,0625 мкс. Или есть способ попроще? Типа сделать секунду короче и выключить на некоторое время таймер1? Но нехочется делать тупых задержек. Подскажите, пожалуйста.
ПС. Питание стабильное, температура-тоже. Пишу в Студии на асме
_________________ Я всё-всё узнAю и стану профессором.
Расширить Т1 дополнительной регистровой парой, в которой считать число переполнений. Т1 без предделителя, после 244 переполнений досчитать ещё 9'216 тактов.
Последний раз редактировалось akl Пн июл 18, 2016 10:12:54, всего редактировалось 1 раз.
Расширить Т1 дополнительной регистровой парой, в которой считать число переполнений. Т1 без предделителя.
Ну блин!!, А что сам-то не додумался? Этож надо- на ровном месте! Спасибо, akl! ARV, и Вам спасибо, только с 16-разрядным счётчиком как ни крути, а точность интервала зависит только от точности генератора и его частоты., Я уже пробовал всякие варианты. Вывод - надо увеличить разрядность счётчика
_________________ Я всё-всё узнAю и стану профессором.
Потеря емкости аккумулятора напрямую зависит от условий хранения и эксплуатации. При неправильном хранении даже самый лучший литиевый источник тока с превосходными характеристиками может не оправдать ожиданий. Технология, основанная на рекомендациях таких известных производителей литиевых источников тока, как компании FANSO и EVE Energy, поможет организовать правильный процесс хранения батареек и аккумуляторов.
Ну вот и программка, ещё не симулял. Это если я правильно понял. Зае заразмножался с подсчётом что надо (в идеале) подсунуть в регистр Sekunda. И я не уверен, что подсчитал правильно, наверно, в железе надо будет тестить. Спойлер
.def temp r16 .def cnt1 r17 .def cnt2 r18 .def ;............... reset: ldi temp,Low(RAMEND) out SPL,temp ldi temp,High(RAMEND) out SPH,temp ;PORT ini.... ;other settings clr temp out TCCR1A,temp ldi temp,1<<CS10 out TCCR1B,temp
ldi temp,1<<TOIE1 out TIMSK,temp ldi cnt1,244 sei main: rjmp main
OvfT1: in r1,sreg ;1 dec cnt1 ;1 brne exit1 ;2/1 ldi temp,high(Sekunda) ;prepare timer1 ;1 out OCR1AH,temp ;to count in CTC mode ;1 ldi temp,low(Sekunda) ;1 out OCR1AL,temp ;1 ldi temp,(1<<WGM12)|(1<<CS10) ;1 out TCCR1B,temp ;1 clr temp ;do I need this "clr"? ;1 ldi temp,1<<OCIE1A ;1 out TIMSK,temp ;1 exit1: out sreg,r1 ;1 reti ;4 ;total OvfT1: 8/17 cycles or 0,5/1,0625 uS @16MHz approx.+rjmp=2*244+reti=4*244 ;14/23, with rjmp/reti, timer1=65536+2+4=65542 ;243*(65542+14)+65542+23+6=15995679 uS ;Sekunda=4321 MatchT1: in r1,sreg ;1 ldi cnt1,244 ;1 clr temp ;1 out TCCR1A,temp ;1 ldi temp,1<<CS10 ;1 out TCCR1B,temp ;1 =6 ticks=0,375 uS, timer starts here ldi temp,1<<TOIE1 ;1 out TIMSK,temp ;1
; Have 1 Second here...
out sreg,r1 reti
_________________ Я всё-всё узнAю и стану профессором.
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
наверное, можно, не вникал. но принципиально - зачем это может быть необходимо? все-таки достаточно "частые" прерывания по считающему на 16МГц таймеру - это весьма приличная нагрузка на ядро - оно действительно необходимо?
например, человечество не заморачивается с тем, что Земля облетает Солнце не ровно за 365 дней... а просто раз в 4 года добавляют сутки, и все. если у вас кварц не точный, то, например, для часов было бы достаточно каждую, допустим, 12845-ю секунду увеличивать счетчик секунд не на 1, а на 2, или наоборот, пропускать инкремент счетчика - и точность хода часов была бы 1 секунда в год.
_________________ если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе при взгляде на многих сверху ничего не меняется...
Ув. ARV, в системах охраны так и сделано (DSC). Есть ячейка, в которой записано количество секунд последней в сутках минуты. По дефолту там 60. Но.. надо так.. akl, спасибо Вам, сейчас разбираюсь как и что в Вашем коде (в перерывах между основной работой ). Ещё не понял, почему Sekunda-1 и зачем писать в TIFR?. По даташиту :
Цитата:
• Bit 4 – OCIE1A: Timer/Counter1, Output Compare A Match Interrupt Enable When this bit is written to one, and the I-flag in the Status Register is set (interrupts globally enabled), the Timer/Counter1 Output Compare A match interrupt is enabled. The corresponding Interrupt Vector (see “Interrupts” on page 46) is executed when the OCF1A Flag, located in TIFR, is set.
Вот я почему-то и подумал, что флаг устанавливается аппаратно.
Где я сморозил?
_________________ Я всё-всё узнAю и стану профессором.
If TCNT equals OCR1x the comparator signals a match. A match will set the Output Compare Flag (OCF1x) at the next timer clock cycle. If enabled (OCIE1x = 1), the Output Compare Flag generates an Output Compare interrupt.
Следовательно, для точного сравнения нужно заносить значение на 1 меньшее требуемого.
dgrett писал(а):
Вот я почему-то и подумал, что флаг устанавливается аппаратно.
Да, а вот сбрасываются они аппаратно при обработке прерывания или программной записью лог. 1. Флаги в AVR всегда расположены на той же позиции в регистре локально разрешающем оные. Запись типа
Код:
ldi temp,1<<TOIE1 out TIMSK,temp OUT TIFR,temp
означает разрешение прерывания переполнения и сброс флага.
Последний раз редактировалось akl Вт июл 19, 2016 08:28:04, всего редактировалось 1 раз.
Опять вопрос, хотя работает и так. Но может необязательно каждую секунду загружать OCR1A ? Можно его грузить единожды в общих настройках. Ведь менять я его не собираюсь в ходе программы? Или тут ещё какие камни под водой с острыми краями?
_________________ Я всё-всё узнAю и стану профессором.
В такой программе можно и единожды загружать OCR1A. Но, По возможности, подтверждать режим работы считаю более надежным решением. Или, например, программу можно переписать, используя только прерывание OC1A.
Спасибо, я тоже так подумал, для надёжности, ведь несколько доп. тактов (их количество не меняется в ходе программы) не "спасёт отца русской демократии".
_________________ Я всё-всё узнAю и стану профессором.
Подскажите что может быть. Есть atmega 168, работает на 8 МГц, в Makefile тоже указано 8000000. Таймер с максимальным предделителем на 1024 срабатывает по переполнению, срабатывает в четыре раза медленнее чем нужно. Считал так. 1/(8 000 000/1 024/1 024)*1 000 = 131 мс В реальности получается 32 миллисекунды Что это за глюк и как с ним боротся?
Доброго времени суток. Есть странный затуп с МК ATMega8. Хочу использовать для генерации ШИМ-сигнала Т/С1 в режиме FastPWM со счетом до ICR1. ... Вся эта штука работает правильно, если выбран обычный FastPWM или, например, PhaseCorrectPWM c отсчетом до ICR1. А если выбрать нужный мне FastPWM с отсчетом до ICR1, то не работает функция считывания нажатия кнопок. Если режим переключить переменной, то все ок (запускается ШИМ и тд.), а включить вручную никак: состояние PINC (на котором висят кнопки и входные сигналы) ни в какую не хочет считываться. Подскажите, пожалуйста, куда примерно думать. Что-то совсем не могу понять, как это может быть связано между собой.
Нашел проблему. При такой
Код:
TCCR1A |= (1 << COM1A1)
инициализации Т/С1, на соответствующем выводе при включении МК висит единица. А у меня дальше идет цикл ожидания нуля на этом выводе, который становится бесконечным из-за этого. Лечится инверсией состояния вывода
Код:
TCCR1A |= (1 << COM1A1) | (1 << COM1A1)
А скважность теперь можно задавать как разность максимума счета и требуемого задания скважности
Код:
OCR1A = ICR1 - PWM_ref
_________________ We do what we must because we can (c) GLaDOS
Теоретически, никто не запрещает использовать статические переменные в обработчике прерывания. Единственное, я бы убрал начальную инициализацию, т.к. static по требованию стандарта зануляется перед первым употреблением. Оно, конечно, и в таком виде абсолютно законно, но несколько двусмысленно. По аналогии с обычными переменными возникает ассоциация, что переменная обнуляется при каждом входе в обработчик, что на самом деле не так.
А ничего что у m168 таймер T2 восьмибитный? Да и остальная логика на первый взгляд странная.
Цитата:
TCCR2A |= (1 << WGM21);
Чему равны остальные биты этого регистра? Лучше при настройке делать прямое присваивание. TCCR2B |= (1 << CS21); делитель F_CPU/8 = 125 кГц OCR2A = 0x1E85; если предположить, что этот регистр 16-битный, делитель равен 7814 Тогда прерывание возникает с частотой F_CPU/8/7814 = 16 Гц, то есть с интервалом 62,5 мс.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 14
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения