Ассемблер (ASM) для AVR в вопросах и ответах
Смотри исходник с дефайном (область объявления констант/имен) в том проекте.

- Реклама
не увидел я там ничего такого
можете изясниться яснее ?
можете изясниться яснее ?
Tell Me The Truth
- Сообщения: 31
- Зарегистрирован: Сб сен 17, 2016 18:56:30
_SFR_IO_ADDR это макрос
Код: Выделить всё
#define __SFR_OFFSET 0x20
#define _SFR_IO_ADDR(sfr) ((sfr) - __SFR_OFFSET)
ок, спасибо
ну а почему тогда производится вычитание смиещения ?
http://images.slideplayer.com/16/526396 ... ide_29.jpg
насколько я понимаю то сначала идут GPR а далее SFR
и как по мне то для правильного указания действительного адреса следовало бы записать SFR+0x20
ну а почему тогда производится вычитание смиещения ?
http://images.slideplayer.com/16/526396 ... ide_29.jpg
насколько я понимаю то сначала идут GPR а далее SFR
и как по мне то для правильного указания действительного адреса следовало бы записать SFR+0x20
Tell Me The Truth
- Сообщения: 31
- Зарегистрирован: Сб сен 17, 2016 18:56:30
Для компилятора avrasm (avrasm2) использование данного макроса не имеет смысла, так как в аппнотовских файлах (.inc) адреса регистров уже скорректированы для использования в инструкциях in/out либо lds/sts. Этот макрос в avrasm и не применяется. Возможно в каких-то других средах программирования что-то как-то происходит иначе. Я знаю только avrasm, пока не было необходимости в чём то другом.
О, вспомнил: в GCC это используется, смотрите в его документации.
О, вспомнил: в GCC это используется, смотрите в его документации.
- Реклама
dimmer писал(а):Для компилятора avrasm (avrasm2) использование данного макроса не имеет смысла, так как в аппнотовских файлах (.inc) адреса регистров уже скорректированы для использования в инструкциях in/out либо lds/sts. Этот макрос в avrasm и не применяется. Возможно в каких-то других средах программирования что-то как-то происходит иначе. Я знаю только avrasm, пока не было необходимости в чём то другом.
О, вспомнил: в GCC это используется, смотрите в его документации.
Ой-ой!
Где ж это в инк-файлах "адреса скорректированы"?
Там только встречается комент " ; MEMORY MAPPED" - типа "адресуется исключительно как память".
Стандартно приводится ряд адресации для команд in/out (если все регистры вписываются в область 0х01 -0х3F),
а для работы с РСФ в диапазоне адресов 0х01 -0х3F как с ОЗУ (ld/st lds/sts) используется "имя регистра+0x20".
Плюс особое внимание кристаллам с расширенной областью РСФ, где надо внимательно
в даташит глядеть (что в любом случае не лишним будет) в раздел "register summary".
Ибо "что сывше 0х3F (0х5F как ОЗУ)" доступно исключительно как ОЗУ
и уже не требует пресловутого "+0x20".
очепятку исправил
Доброго времени суток
Небольшая загвоздка с таймером1 в меге8
Значит, установил режим СТС, разрешил прерывания таймера по совпадению с OCR1A, загрузил числа в OCR1A. По прерыванию инвертируем состояние портаB. В avrstudio4 работает нормально, в протеусе и железе - почему-то частота инвертирования порта не зависит от OCR1AH, т.е. все происходит только по младшему регистру.
Спойлер
Код: Выделить всё
;разрешим сон idle mode
in temp, MCUCR
ori temp, 0b10000000
andi temp, 0b10001111
out MCUCR, temp
;таймер
ser temp ; устанавливаем числа, с которыми будет сравниваться таймер
out OCR1AL, temp
out OCR1AH, temp
clr temp
out TCCR1A, temp ; ОС1А отключен
ldi temp, 0b00001001
out TCCR1B, temp ; режим СТС
ldi temp, (1<<OCIE1A)
out TIMSK, temp ; разрешаем прерывания по совпадению
sei
Nope1:
sleep
rjmp nope1
tim1_compa: ; обработка прерывания - ставим в лог. 1 нулевой бит портаB
ldi temp, 0x0F
out ddrb, temp
in temp, portb
com temp
andi temp, 0x0F
out portb, temp
retiПолный чайник.
Поменяй строки местами
out OCR1AL, temp
out OCR1AH, temp
out OCR1AL, temp
out OCR1AH, temp
Запись в 16 разрядные регистры периферии старший-младший, чтение наоборот.
1. Читаем правила обращения к 16 разрядным регистрам таймер-счетчиков.neoneon писал(а):Доброго времени сутокНебольшая загвоздка с таймером1 в меге8
Значит, установил режим СТС, разрешил прерывания таймера по совпадению с OCR1A, загрузил числа в OCR1A. По прерыванию инвертируем состояние портаB. В avrstudio4 работает нормально, в протеусе и железе - почему-то частота инвертирования порта не зависит от OCR1AH, т.е. все происходит только по младшему регистру.
![]()
...
2. загрузка начального значения OCR1A должна производится ДО установки режима работы таймера
Всем спасибо, заработало
Что-то может быть "не так", если, например, счетчик тактируется с большим делителем, а сразу после установки режима записать значение OCR1A?BOB51 писал(а):2. загрузка начального значения OCR1A должна производится ДО установки режима работы таймера
Полный чайник.
Старт режима будет с предшествующим произвольным значением содержимого регистров.
Перенос значения в момент времени в соответствии с заданным режимом.

Перенос значения в момент времени в соответствии с заданным режимом.
Для полноты картины, сбрасывать флаг(и)
Спойлер
Код: Выделить всё
;таймер
ser temp ; устанавливаем числа, с которыми будет сравниваться таймер
out OCR1AH, temp
out OCR1AL, temp
; out OCR1AH, temp
clr temp
out TCCR1A, temp ; ОС1А отключен
ldi temp, (1<<OCIE1A)
out TIMSK, temp ; разрешаем прерывания по совпадению
out TIFR, temp ; Cброс флага OCF1A
ldi temp, 0b00001001
out TCCR1B, temp ; режим СТС :1
seiЯ к тому, что при больших делителях это некритично; таймер не успеет единичку отсчитать, а у нас уже записано верное значение OCR1A.BOB51 писал(а):Старт режима будет с предшествующим произвольным значением содержимого регистров.
akl, да, точно, я не подумал о сбросе флага, благодарю
Полный чайник.
при такой последовательности
ldi R16, 159
out OCR1AH, ZH ; ZH (R31) = 0
out OCR1AL, R16
ldi R16, 0b00000000 ; таймер1, Normal port operation, OC1A/OC1B disconnected
out TCCR1A, R16
ldi R16, 0b00001010 ; таймер1, Compare Match, предделитель 8
out TCCR1B, R16
флаг в TIFR не устанавливается, поэтому и сбрасывать его не надо.
ldi R16, 159
out OCR1AH, ZH ; ZH (R31) = 0
out OCR1AL, R16
ldi R16, 0b00000000 ; таймер1, Normal port operation, OC1A/OC1B disconnected
out TCCR1A, R16
ldi R16, 0b00001010 ; таймер1, Compare Match, предделитель 8
out TCCR1B, R16
флаг в TIFR не устанавливается, поэтому и сбрасывать его не надо.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Да, флаг не устанавливается, если нет предистории. Если она есть и связана с другими режимами работы Т1, сбрасывать обязательно. Например, генерация 1 секунды без сброса флага И генерация того же ,но со сбросом флагаStarichok51 писал(а):...флаг в TIFR не устанавливается, поэтому и сбрасывать его не надо.
я имел в виду без предыстории...
а что, если в первом случае еще покрутить отладчик, разве потом не установится ровно 1с?
а что, если в первом случае еще покрутить отладчик, разве потом не установится ровно 1с?
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
А это как раз не первый, а последующий(е) периоды, так же как и на картинке со сбросом флага.
Помогите разобраться. есть вот такой код:
; Main.asm file generated by New Project wizard
;
; Created: Пн фев 27 2017
; Processor: ATtiny13
; Compiler: AVRASM (Proteus)
;==============
; предделители и частоты
; рабочая частота 128 кГц
; делитель на 8 выкл.
; предделитель 1024
; сброс при совпадении
; регистр сравнения = 125-1
; результат = прерывание 1 сек
;
;==============
; DEFINITIONS
;==============
;==============
; VARIABLES
;==============
.def Temp=r20
.def Temp1=r21
.def Second=r22
.def Minutes=r23
;==============
; вектора прерываний
;==============
.cseg
.org 0
rjmp Reset
.org 6
rjmp T0_COMPA ;Timer/Counter0 Compare Match A
rjmp Start
Reset: ldi Temp,0b11111111
out DDRB,Temp
ldi temp, low(RAMEND) ; инициализацыя стека
out SPL,temp
ldi Temp,0
out TCNT0,Temp ;обнуляем счетный регистр
ldi Temp,124 ;регистр сравнения
out OCR0A,Temp
ldi Temp,0b00000100 ;разрешить прерывание по совпадению таймера/счетчика 0
out TIMSK0,Temp
ldi Temp,0b00000100 ;Флаг наступления прерывания по совпадению
out TIFR0,Temp
ldi Temp,0b00000101 ;тактовый сигнал = CK/1024
out TCCR0B,Temp
ldi Temp,0b00000010 ;
out TCCR0A,Temp
ldi Temp1,0
clr Second
clr Minutes
sei
rjmp Start
T0_COMPA:
inc Second
cpi Second,60
brne Exit_compa
ldi Second,0
inc Minutes
Exit_compa:
reti
;==============
Start: out PortB,Minutes
rjmp Start
По идее на 5й ноге должен изменятся сигнал каждую минуту (60 сек), но в реальности это происходит каждые 69 сек. Proteus 8,5 моделирует красиво, прошитый контроллер считает криво.
программа прошивки: progisp 1,7
програматор: USBasp
Спойлер
;==============; Main.asm file generated by New Project wizard
;
; Created: Пн фев 27 2017
; Processor: ATtiny13
; Compiler: AVRASM (Proteus)
;==============
; предделители и частоты
; рабочая частота 128 кГц
; делитель на 8 выкл.
; предделитель 1024
; сброс при совпадении
; регистр сравнения = 125-1
; результат = прерывание 1 сек
;
;==============
; DEFINITIONS
;==============
;==============
; VARIABLES
;==============
.def Temp=r20
.def Temp1=r21
.def Second=r22
.def Minutes=r23
;==============
; вектора прерываний
;==============
.cseg
.org 0
rjmp Reset
.org 6
rjmp T0_COMPA ;Timer/Counter0 Compare Match A
rjmp Start
Reset: ldi Temp,0b11111111
out DDRB,Temp
ldi temp, low(RAMEND) ; инициализацыя стека
out SPL,temp
ldi Temp,0
out TCNT0,Temp ;обнуляем счетный регистр
ldi Temp,124 ;регистр сравнения
out OCR0A,Temp
ldi Temp,0b00000100 ;разрешить прерывание по совпадению таймера/счетчика 0
out TIMSK0,Temp
ldi Temp,0b00000100 ;Флаг наступления прерывания по совпадению
out TIFR0,Temp
ldi Temp,0b00000101 ;тактовый сигнал = CK/1024
out TCCR0B,Temp
ldi Temp,0b00000010 ;
out TCCR0A,Temp
ldi Temp1,0
clr Second
clr Minutes
sei
rjmp Start
T0_COMPA:
inc Second
cpi Second,60
brne Exit_compa
ldi Second,0
inc Minutes
Exit_compa:
reti
;==============
Start: out PortB,Minutes
rjmp Start
программа прошивки: progisp 1,7
програматор: USBasp
Если я чего-то не знаю, это не говорит о моем невежестве, а только о том, что раньше этот вопрос лежал вне сферы моих интересов.


