Ассемблер (ASM) для AVR в вопросах и ответах
РОНы обнуляются вместе со всей периферией по любым сигналам сброса, и обнулять их стоит только в том случае если вы используете "программный сброс" путем перехода на вектор сброса. Но это вообще довольно специфическое применение и усы надо держать остро... там и проблемы с инициализацией периферии могут возникнуть.
- Реклама
РОНы обнуляются вместе со всей периферией по любым сигналам сброса
- Сообщения: 758
- Зарегистрирован: Вс фев 10, 2013 15:26:00
И опять здравый смысл: РОН явно инициализируется непосредственно перед любой (разумной) попыткой им воспользоваться.
Как временная, сугубо локальная переменная.
ldi Maksimum, 100
cp TekuscheeZnachenie, Maksimum
brsh ...
или
lds Temp1, TekuscheeZnachenie
lds Temp2, Maksimum
cp Temp1, Temp2
brsh ...
Поэтому проблема (не)инициализации РОН при ресете имеет скорее академический характер, чем практический.
А за аппаратные ("периферийные") регистры вопрос отпадёт сам собой, если приглядеться например к MCUCSR.
Как временная, сугубо локальная переменная.
ldi Maksimum, 100
cp TekuscheeZnachenie, Maksimum
brsh ...
или
lds Temp1, TekuscheeZnachenie
lds Temp2, Maksimum
cp Temp1, Temp2
brsh ...
Поэтому проблема (не)инициализации РОН при ресете имеет скорее академический характер, чем практический.
А за аппаратные ("периферийные") регистры вопрос отпадёт сам собой, если приглядеться например к MCUCSR.
Возможно пишу не совсем по этой теме, за что прошу прощения.
В общем, суть проблемы(?) такова: задался целью написать на ассемблере программу для работы с датчиком DS18B20, и, в принципе, успешно ее решил. Но! В datasheet сказано, что датчик выдает при чтении 1. LSB температуры, 2. MSB температуры, 3 и 4-й байты регистры аварии верхнего и нижнего предела, 5. Регистр конфигурации, 3 резервных байта и байт CRC.
Так вот, в Proteus для корректного съема температуры приходится конвертировать 1-й и 3-й байты! Конечно, в документе есть сноска "если функция аварии DS18B20 не используется, то регистры TH and TL могут быть ячейками универсальной памяти" - Какой и как я не нашел. И как в реальности работает такой датчик?
PS Датчик один. Конфигурация: Presense, SKIP ROM, READ ROM, запись 9-ти байт по порядку в ОЗУ (.dseg .org 0x60 rec: .byte 9), Convert temperature. И, далее, с опросом состояния по циклу.
В общем, суть проблемы(?) такова: задался целью написать на ассемблере программу для работы с датчиком DS18B20, и, в принципе, успешно ее решил. Но! В datasheet сказано, что датчик выдает при чтении 1. LSB температуры, 2. MSB температуры, 3 и 4-й байты регистры аварии верхнего и нижнего предела, 5. Регистр конфигурации, 3 резервных байта и байт CRC.
Так вот, в Proteus для корректного съема температуры приходится конвертировать 1-й и 3-й байты! Конечно, в документе есть сноска "если функция аварии DS18B20 не используется, то регистры TH and TL могут быть ячейками универсальной памяти" - Какой и как я не нашел. И как в реальности работает такой датчик?
PS Датчик один. Конфигурация: Presense, SKIP ROM, READ ROM, запись 9-ти байт по порядку в ОЗУ (.dseg .org 0x60 rec: .byte 9), Convert temperature. И, далее, с опросом состояния по циклу.
«Еще я хотел бы, чтобы наши ученые изобрели какой-то новый источник энергии, чтобы мы на коленях не ползали даже перед нашими братьями, умоляя их и выпрашивая тонну нефти или кубометр газа», — рассказал белорусский президент.
- Реклама
Так я ведь так и делаю. Единственное отличие - начал смотреть все 9 байт. Сначала выводил их по UART, а потом конвертировал в hex и на 44780. Просто может модель датчика такая? С 2-мя первыми байтами дело не прошло, поэтому пришлось читать все для понимания причин...
«Еще я хотел бы, чтобы наши ученые изобрели какой-то новый источник энергии, чтобы мы на коленях не ползали даже перед нашими братьями, умоляя их и выпрашивая тонну нефти или кубометр газа», — рассказал белорусский президент.
- Сообщения: 39
- Зарегистрирован: Пн дек 31, 2012 13:16:59
Так не должно быть, а уверенны что корректно считываются все 9 байт? Быть может что-то со скоростью и датчик молчит при опросе второго байта а начинае отдавать второй когда считываете третий
В регистрах TH TL можно хранить любые 2 байта если не пользоваться командой alarm search. Это и подразумевается под ячейками универсальной памяти
В регистрах TH TL можно хранить любые 2 байта если не пользоваться командой alarm search. Это и подразумевается под ячейками универсальной памяти
Термометр в proteus работает и именно со 2-м и 0-м байтами. В спойлере участок кода приемника. Частота - 8 МГц.
/*
Операция чтения бита: Вывод микроконтроллера устанавливается
в режим выхода и на нем устанавливается логический ноль.
Выдерживается определенная пауза, вывод переводится в режим
входа в состоянии Hi-z, выдерживается пауза, а затем микроконтроллер
считывает потенциал вывода.
*/
ldi r19,8 ; Count bit
ldi r18,9 ; Count byte
clr r16 ; Очистим регистр приемника
receive_in:
; Выдадим старт-бит
rcall init_out
cbi Dataport,DATA ; Clear pin
rcall Delay_3uS ; Start slot
rcall init_in ; Вывод на вход
rcall Delay_20uS ; Прочитаем значение бита:
clc ; Clear Carry
sbic Datapin,DATA ; Пропустим команду при лог. 0
sec ; Установим Carry в 1
ror r16 ; Carry в бит 7
rcall Delay_60uS ; Ждем окончания слота времени
dec r19
brne receive_in ; next bit
; Байт прочитан. Запишем его в ячейку
cpi r18,9
brne _8_1
sts rec+0,r16
_8_1:
cpi r18,8
brne _7_1
sts rec+1,r16
_7_1:
cpi r18,7
brne _6_1
sts rec+2,r16
_6_1:
cpi r18,6
brne _5_1
sts rec+3,r16
_5_1:
cpi r18,5
brne _4_1
sts rec+4,r16
_4_1:
cpi r18,4
brne _3_1
sts rec+5,r16
_3_1:
cpi r18,3
brne _2_1
sts rec+6,r16
_2_1:
cpi r18,2
brne _1_1
sts rec+7,r16
_1_1:
cpi r18,1
brne _0_1
sts rec+8,r16
_0_1:
clr r16 ; Очистим приемник
dec r18
cpi r18,0
brne receive_in
ret
Вот - дальнейшая обработка:
; Но, сначала определимся со знаком
lds r16,rec+0
lds r17,rec+2
sbrs r17,6
rjmp positiv
Появится время - проверю код в железе и отпишусь. Пока нет индикатора, поэтому придется передать данные на комп...
Спойлер
receive:/*
Операция чтения бита: Вывод микроконтроллера устанавливается
в режим выхода и на нем устанавливается логический ноль.
Выдерживается определенная пауза, вывод переводится в режим
входа в состоянии Hi-z, выдерживается пауза, а затем микроконтроллер
считывает потенциал вывода.
*/
ldi r19,8 ; Count bit
ldi r18,9 ; Count byte
clr r16 ; Очистим регистр приемника
receive_in:
; Выдадим старт-бит
rcall init_out
cbi Dataport,DATA ; Clear pin
rcall Delay_3uS ; Start slot
rcall init_in ; Вывод на вход
rcall Delay_20uS ; Прочитаем значение бита:
clc ; Clear Carry
sbic Datapin,DATA ; Пропустим команду при лог. 0
sec ; Установим Carry в 1
ror r16 ; Carry в бит 7
rcall Delay_60uS ; Ждем окончания слота времени
dec r19
brne receive_in ; next bit
; Байт прочитан. Запишем его в ячейку
cpi r18,9
brne _8_1
sts rec+0,r16
_8_1:
cpi r18,8
brne _7_1
sts rec+1,r16
_7_1:
cpi r18,7
brne _6_1
sts rec+2,r16
_6_1:
cpi r18,6
brne _5_1
sts rec+3,r16
_5_1:
cpi r18,5
brne _4_1
sts rec+4,r16
_4_1:
cpi r18,4
brne _3_1
sts rec+5,r16
_3_1:
cpi r18,3
brne _2_1
sts rec+6,r16
_2_1:
cpi r18,2
brne _1_1
sts rec+7,r16
_1_1:
cpi r18,1
brne _0_1
sts rec+8,r16
_0_1:
clr r16 ; Очистим приемник
dec r18
cpi r18,0
brne receive_in
ret
Спойлер
; Для корректного отображения нужно поделить значение на 16; Но, сначала определимся со знаком
lds r16,rec+0
lds r17,rec+2
sbrs r17,6
rjmp positiv
«Еще я хотел бы, чтобы наши ученые изобрели какой-то новый источник энергии, чтобы мы на коленях не ползали даже перед нашими братьями, умоляя их и выпрашивая тонну нефти или кубометр газа», — рассказал белорусский президент.
Тут камрад как-то давно (может даже в статьях) выкладывал код (?) с выводом трёх (?) значащих цифр (напряжение свинцового аккума вроде) на один светодиодdr.doc писал(а):Пока нет индикатора
Количество длинных миганий — десятки, мигания покороче — единицы и совсем короткие — десятые доли вольта.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Тогдауж, морзянкой... так можно тексты целые выводить.
Это для совсем тру радиолюбителейAlexeyslav писал(а):Тогдауж, морзянкой...
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Причем на слухAlexeyslav писал(а):Тогдауж, морзянкой... так можно тексты целые выводить.
Да хватит стебаться. Написать вывод на семисегментник, по кнопке в порт, по UART в комп не проблема. Проблема, что на железо пока нет времени.
«Еще я хотел бы, чтобы наши ученые изобрели какой-то новый источник энергии, чтобы мы на коленях не ползали даже перед нашими братьями, умоляя их и выпрашивая тонну нефти или кубометр газа», — рассказал белорусский президент.
Подскажите, пожалуйста, как правильно использовать ветвление в макросах?
Как обычно - делаешь метку в тексте макроса и JMP/BRxx на неё из кода макроса.
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
А при многократном использовании макроса проблем не возникнет? Как компилятор разрешает дублирование меток в этом случае?
Нет, проблем не возникает. Макрос обрабатывается особым образом. Метки объявленные в макросе видны только в коде макроса. Соответственно, можно делать одинаковые метки в разных макросах, и метку в макросе одинаковую с меткой в основной программе и это не будет вызывать ошибок и будет работать как надо. Для AvrAssembler2, который в 4ой, 5ой и 6ой Студии, вроде как, тут уже это обсуждалось и на практике подтверждали.
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
- Сообщения: 758
- Зарегистрирован: Вс фев 10, 2013 15:26:00
А скачать AVR Studio, установить, скомпилировать и посмотреть на файл *.lst?
Микросхема не знает никаких меток, у неё только инструкции, машинные коды. А в машинных кодах переходы выполняются как "перейти на адрес 1234 на плюс Х адресов или на минус Х адресов от самой команды перехода" - т.е. при компиляции выражение BRNE ERROR будет понято как BRNE ERROR-PC, где ERROR-PC = автоматически рассчитанная компилятором и подставленная в машинный код константа.
Или смысл в общении.
Микросхема не знает никаких меток, у неё только инструкции, машинные коды. А в машинных кодах переходы выполняются как "перейти на адрес 1234 на плюс Х адресов или на минус Х адресов от самой команды перехода" - т.е. при компиляции выражение BRNE ERROR будет понято как BRNE ERROR-PC, где ERROR-PC = автоматически рассчитанная компилятором и подставленная в машинный код константа.
Или смысл в общении.
Kavka, спасибо за подробный ответ. Вы развеяли все мои опасения.

Да.nirq писал(а):Или смысл в общении.

Сегодня столкнулся с таким багом при использовании avra на Linux:
Компилятор не проверяет значение параметров, передаваемых командам in/out lds/sts
Так, например, вот этот код (tiny2313)
не вызвал у компилятора никаких подозрений, хотя программа, естественно, не работала. (TIMSK = 0x39, что меньше, чем 0x3F, так что тут нужен out) ушел почти день на отловку этого бага.
Пользуюсь avra уже давно, но на эту штуку наткнулся в первый раз, т.к. обычно использую макрос, который сам подстаяляет нужный out или sts, а тут понадобилось сделать вручную.
Ну зато пока ловил этот баг, повычищал прогу от всех остальных
Такие дела.
Компилятор не проверяет значение параметров, передаваемых командам in/out lds/sts
Так, например, вот этот код (tiny2313)
Код: Выделить всё
sts TIMSK, R16Пользуюсь avra уже давно, но на эту штуку наткнулся в первый раз, т.к. обычно использую макрос, который сам подстаяляет нужный out или sts, а тут понадобилось сделать вручную.
Ну зато пока ловил этот баг, повычищал прогу от всех остальных
Такие дела.


