James D. 0 8 ноября, 2018 Опубликовано 8 ноября, 2018 (изменено) · Жалоба Не пойму, почему T/C1 по-разному считает в каждом прогоне. Здесь у меня бесконечный цикл. В начале T/C1 настраивается и запускается. 0.5 секунды он считает; после окончания счета выставляет "1" на 5 пине порта D. После проходит еще ~0.5 сек., T/C1 останавливается и обнуляется ("0" на 5 пине порта D). И по-новой. 0.5 сек - "0", 0.5 сек - "1". Но, почему-то, с момента, когда устанавливается TCCR1B и счетчик начинает считать, и до момента окончания счета, когда выставляется флаг OCF1A проходит разное время. 500195.00 мкс, 500156.50 мкс, 500030.50 мкс и т.д. (кварц на 4 МГц). AVRStudio 4.06. А если предделитель не использовать, то считает одинаково раз за разом. ldi r16,$07 ;$07A1 = 0.5 секунды out OCR1AH,r16 ldi temp,$A1 out OCR1AL,r16 ;*********************************** ;Разрешить Timer/Counter1 Cycle: ldi r16,(1<<COM1A1)|(1<<COM1A0) out TCCR1A,r16 ldi r16,(1<<WGM12)|(1<<CS12)|(1<<CS10) ;Установить бит WGM12=1 (режим CTC). Предделитель CK/1024 (CS12=1, CS11=0, CS10=1) out TCCR1B,r16 ;*********************************** ;Временная задержка (1.011491 сек) на 4 МГц Tim_dl: ldi r20,$15 ldi r21,$A9 ldi r22,$18 D_r_1x: dec r22 brne D_r_1x ldi r22,$FF dec r21 brne D_r_1x ldi r21,$FF dec r20 brne D_r_1x ;*********************************** ;Запретить и обнулить Timer/Counter1 ldi r16,(0<<WGM12)|(0<<CS12)|(0<<CS10) out TCCR1B,r16 ldi r16,(0<<COM1A1)|(0<<COM1A0) out TCCR1A,r16 clr r16 out TCNT1H,r16 out TCNT1L,r16 ldi r16,1<<OCF1A out TIFR,r16 ;*********************************** rjmp Cycle Изменено 8 ноября, 2018 пользователем James D. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Палыч 5 8 ноября, 2018 Опубликовано 8 ноября, 2018 · Жалоба Вероятно, потому, что пределитель - обычный двоичный счётчик, состояние которого не определено в момент записи в регистр TCCR1B. Для сброса счетчика пределителя в ноль используется регистр SFIOR. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
James D. 0 8 ноября, 2018 Опубликовано 8 ноября, 2018 (изменено) · Жалоба Хорошо, я добавил в начале сброс предделителей, но ничего не изменилось.: Cycle: ldi r16,1<<PSR10 out SFIOR,r16 ldi r16,(1<<COM1A1)|(1<<COM1A0) out TCCR1A,r16 ldi r16,(1<<WGM12)|(1<<CS12)|(1<<CS10) ;Установить бит WGM12=1 (режим CTC). Предделитель CK/1024 (CS12=1, CS11=0, CS10=1) out TCCR1B,r16 Изменено 8 ноября, 2018 пользователем James D. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
James D. 0 8 ноября, 2018 Опубликовано 8 ноября, 2018 (изменено) · Жалоба Я переписал временнУю задержку, чтоб удобнее было отслеживать появление "1" на 5 пине порта D. Сначала нужно обнулить Stop Watch в AVRStudio в момент, когда 5 пин очищается - после записи (0<<COM1A1)|(0<<COM1A0) в TCCR1A. Теперь достаточно поставить курсор на оператор "nop" и нажать Ctrl+F10. Stop Watch в AVRStudio показывает разное прошедшее время. ;Временная задержка (1.011491 сек) на 4 МГц Tim_dl: ldi r20,$15 ldi r21,$A9 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 Изменено 8 ноября, 2018 пользователем James D. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
James D. 0 8 ноября, 2018 Опубликовано 8 ноября, 2018 · Жалоба Заметил, что время, через которое срабатывает счетчик не гуляет бессистемно, а все время увеличивается от прогона к прогону. Сначала счетчик срабатывает через 499990.00 мкс, на следующем прогоне через 500012.50 мкс, потом через 500035.00 мкс и т.д. Дошло до 500214.50 мкс и следующая задержка уже была 499981.25 мкс и опять начала увеличиваться (500003.75 мкс ...). Все время увеличиваясь на одну и ту же величину - 22.5 мкс (90 тактов на 4 МГц). Тогда я добавил в цикл 90 пустых команд "nop", и счетчик стал срабатывать через одинаковое время - 500223.25 мкс. Но это же никуда не годится... Что это за 22.5 мкс такие? Вот полная моя программа: .include "m16def.inc" .CSEG ;***** Определения портов В/В ***** ;Port D: .equ DIRD =0b00100000 .equ PUPD =0b00000000 ;***** Векторы Прерываний ***** .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: ldi r16,$07 ;$07A1 = 0.5 секунды out OCR1AH,r16 ldi r16,$A1 out OCR1AL,r16 Cycle: in r16,SFIOR sbr r16,00000001 ; ldi r16,1<<PSR10 out SFIOR,r16 nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop ldi r16,(1<<COM1A1)|(1<<COM1A0) out TCCR1A,r16 ldi r16,(1<<WGM12)|(1<<CS12)|(1<<CS10) ;Установить бит WGM12=1 (режим CTC). Предделитель CK/1024 (CS12=1, CS11=0, CS10=1) out TCCR1B,r16 ;*********************************** ;Временная задержка (1.011491 сек) на 4 МГц Tim_dl: ldi r20,$15 ldi r21,$A9 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 ;*********************************** ;Запретить и обнулить Timer/Counter1 ldi r16,(0<<WGM12)|(0<<CS12)|(0<<CS10) out TCCR1B,r16 ldi r16,(0<<COM1A1)|(0<<COM1A0) ;Обнулить вывод 5 порта D out TCCR1A,r16 clr r16 out TCNT1H,r16 out TCNT1L,r16 ldi r16,1<<OCF1A out TIFR,r16 ;*********************************** rjmp Cycle Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zombi 0 8 ноября, 2018 Опубликовано 8 ноября, 2018 · Жалоба Вы AVRStudio чтоль тестируете? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
James D. 0 9 ноября, 2018 Опубликовано 9 ноября, 2018 · Жалоба 19 hours ago, James D. said: AVRStudio 4.06. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ILYAUL 0 9 ноября, 2018 Опубликовано 9 ноября, 2018 · Жалоба Включите ему прерывание и в нем отслеживайте. Ваша временная задержка тоже тратит время Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей 0 9 ноября, 2018 Опубликовано 9 ноября, 2018 · Жалоба Из вашего программного кода ничего не понятно. Зачем Вам таймер, если вы его не используете!!! Абсолютная бессмыслица. Как правильно уже было сказано ILYAUL, такие вещи делаются через прерывания. И дебагу от AVRStudio доверять не стоит. Есть такой прибор осциллограф называется))) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
James D. 0 9 ноября, 2018 Опубликовано 9 ноября, 2018 (изменено) · Жалоба 38 minutes ago, Сергей said: Зачем Вам таймер, если вы его не используете!!! Счетчик использую - он выдает "1" на PD5 в конце своего счета. Конечно, будет работать не в таком бесконечном цикле, это просто для проверки. AVRStudio 4.06 врет в отношении этой программки - в нем работает, а в железе - нет. Пробовал я AVR Studio 5.1, Atmel Studio 6.2 и Atmel Studio 7.0 (какие же они тяжелые в работе), заметил, что в них как-то странно этот пин PD5 себя ведет - практически всегда выдает лог. "1" и только на короткое время выдает "0" (хотя в программе я сделал меандр). Так вот, в железе, схема ведет себя именно так. Теперь буду отлаживать в одной из этих новых студий. Изменено 9 ноября, 2018 пользователем James D. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться