Ассемблер (ASM) для AVR в вопросах и ответах

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
itmaker
Первый раз сказал Мяу!
Сообщения: 33
Зарегистрирован: Сб дек 11, 2010 13:40:56

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение itmaker »

спасибо, что помогли
Что хорошо для меня - полезно для всех! ;)
Реклама
Аватара пользователя
DX168B
Друг Кота
Сообщения: 4468
Зарегистрирован: Вс янв 24, 2010 19:19:52
Откуда: Главный Улей России (Moscow)
Контактная информация:

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение DX168B »

Метеор, давайте по простому, без научных терминов и преамбул. :))) :))) :)))
Когда учился в школе, у нас был сильный преподаватель по физике. Даже заядлые рас***дяи знали физику на отлично. Он объяснял всё на простых примерах и на простом языке. :)

Всё просто.
Организуем массив в ОЗУ из четырёх байтов.
Организуем приём с UART по прерыванию.
Выделим один регистр под счётчик принятых байтов
В прерывании UART запишем принятый байт в ОЗУ и увеличим счётчик на 1 и перейдём к следующей ячейке ОЗУ.
В основной программе, мы застрянем в цикле, пока значение счётчика не станет 4
После этого можно скопировать из ОЗУ любой из 4х байтов (в данном случае второй байт)
и делать с ним всё, что нам потребуется.

Покажу на примере AVR.

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

.dseg
buffer:   .byte  4  ;Выделим 4 байта в ОЗУ (организуем массив)
;----------
.cseg
.org   0x0000
rjmp   RESET
................    ; тут векторы прерываний
...................
UART_RECEIVE_COMPLETE:  ;Лучше организовать приём по прерыванию.
in    R18,   SREG  ;Спасём SREG
in    R16,   UDR   ;Копируем в R16 принятый байт из регистра UART
cpi   r17,   0x00  ;Если это второй и далее байты,
brne  RCV         ;то сразу пишем его в ОЗУ, а иначе проверим начало пакета
cpi   R16,   0xXX  ;Признак начала пакета(первый байт пакета)
breq  RCV       ;Если он верен, то запишем его, иначе выйдем из прерывания, ничего не трогая
out   SREG,  R18   ; Восстановим SREG
reti            ;Выйдем из прерывания
RCV:              ;Запись принятого байта в ОЗУ
st    Y+,    R16   ; Запишем его в ОЗУ с увеличением на 1 значения пары Y
inc   R17          ; Увеличим наш счётчик принятых байтов на 1
out   SREG,  R18   ; Восстановим SREG
reti               ;Выйдем из прерывания
;----------
RESET:             ;Тут начало программы
.............
.............
..........                 ;Настроим всё (порты, стек, UART и т.д.)
ldi   YL,    Low(buffer)      ;Прихватим парой Y наш массивчик в ОЗУ
ldi   YH,    High(buffer)
ldi   R17,   0x00         ; Этот регистр будет у нас в роли счётчика принятых байтов
;----------
LOOP:                   ; Упрёмся тут в ожидании приёма всех четырёх байтов.
cpi   R17,   0x04       ; Всё ли приняли?
brmi  LOOP             ;Если нет, то снова проверим
ldi   R17,   0x00       ; Иначе сбросим "счётчик"
lds   R16,   buffer+1    ;Загрузим второй байт из ОЗУ в R16
..........                   ;И делаем с ним всё, что нам вздумается
.............
.....

I am DX168B and this is my favourite forum on internet!
Реклама
Аватара пользователя
ibiza11
Поставщик валерьянки для Кота
Сообщения: 1900
Зарегистрирован: Сб фев 21, 2009 13:11:40
Откуда: Москва

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение ibiza11 »

DX168B, в какой-нибудь момент приемник пропустит один байт и во что это выльется не стоит писать....
Я считаю, что нужно организовать пакеты по 4 байта и ввести таймаут между пакетами. (1байт_2байт_3байт_4байт_таймаут_________________). В этом случае, если в пакете пришло не 4 байта и таймаут прошел, пакет считается "битым" и не записывается в ОЗУ. Достигается это запуском (сбросом в "0" запущенного) таймера при каждом приеме байта.
Ставим плюсы: )
Аватара пользователя
DX168B
Друг Кота
Сообщения: 4468
Зарегистрирован: Вс янв 24, 2010 19:19:52
Откуда: Главный Улей России (Moscow)
Контактная информация:

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение DX168B »

Как в Винде? Там есть и таймауты, XON char и XOFF char. :)
Для того, чтобы не вылилось это во что-то, нужно ограничить размер пакета и не давать переполняться массиву в ОЗУ выше 4х байтов. Просто это я в программе не указал. Можно просто вырубить прерывание UART после приёма всех четырёх байтов, спокойно обработать их, сброситься в ноль и снова ожидать приёма, включив прерывание UART. Если нужна ещё и целостность пакета, то можно и проверку CRC организовать, если конечно она присылается ему.
Я делал простую проверку. Конечно она может допустить тоже ошибки, но вероятности уже меньше.
Складывал все байты пакета и потом делил на их количество. Результатом и получалась примитивная контрольная сумма в виде одного байта. Только надо учесть то, чтобы ведущее устройство производило расчёт этой суммы и прикрепляло результат к пакету. Потом ведомое производит расчёт суммы, за исключением байта принятой суммы с ведущего устройства. результаты сравниваются и уже принимается решение об обработке принятого пакета.
Последний раз редактировалось DX168B Вс янв 16, 2011 19:38:09, всего редактировалось 1 раз.
I am DX168B and this is my favourite forum on internet!
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
ibiza11
Поставщик валерьянки для Кота
Сообщения: 1900
Зарегистрирован: Сб фев 21, 2009 13:11:40
Откуда: Москва

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение ibiza11 »

DX168B писал(а):Можно просто вырубить прерывание UART после приёма всех четырёх байтов, спокойно обработать их, сброситься в ноль и снова ожидать приёма, включив прерывание UART. Если нужна ещё и целостность пакета, то можно и проверку CRC организовать.
как раз в этом случае может произойти ошибка. если один байт не пройдет, то четвертый байт пакета уже будет записан из 1 байта следующего пакета. Все зависит от поставленных задач. Если устройство ответственное, то и защита должна быть соответствующая.
Ставим плюсы: )
Реклама
Аватара пользователя
DX168B
Друг Кота
Сообщения: 4468
Зарегистрирован: Вс янв 24, 2010 19:19:52
Откуда: Главный Улей России (Moscow)
Контактная информация:

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение DX168B »

Если последний байт пакета символизирует конец пакета и отличается от первого байта, то можно не заморачиваться с таймером. Достаточно его проверить. Ну а если это не конец пакета, то уже другого выхода нет - только таймаут. :)
I am DX168B and this is my favourite forum on internet!
Реклама
Аватара пользователя
ibiza11
Поставщик валерьянки для Кота
Сообщения: 1900
Зарегистрирован: Сб фев 21, 2009 13:11:40
Откуда: Москва

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение ibiza11 »

смотря какого рода данные передаются :) если байты могут принимать любое значение от 0 до 255, то невозможно определить конец пакета по значению последнего байта.
Ставим плюсы: )
Аватара пользователя
DX168B
Друг Кота
Сообщения: 4468
Зарегистрирован: Вс янв 24, 2010 19:19:52
Откуда: Главный Улей России (Moscow)
Контактная информация:

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение DX168B »

Ну и я про то же.. :)
I am DX168B and this is my favourite forum on internet!
Tom91
Встал на лапы
Сообщения: 108
Зарегистрирован: Пт окт 08, 2010 15:43:55

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Tom91 »

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

      com lbyte   ; 
      inc lbyte
      ldi digit1, -3 


Кто сможет объяснить что происходит в этих строчках?
И сразу по этим строчкам, что такое дополнительный код ?
Ethereal
Родился
Сообщения: 16
Зарегистрирован: Ср янв 19, 2011 00:34:56

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Ethereal »

Что тут может быть непонятного ?

В современных процессорах отрицательные числа представляются в виде двоичного дополнения плюс единица. Т.е.

-X = ~X + 1

Поэтому если тебе надо поменять знак числа и у данного процессора нет готовой команды NEG,
то сначала инвертируешь, потом инкрементируешь.

com lbyte
inc lbyte
- это смена знака у lbyte.

Например было 03
Инвертируем и получаем FC
Инкрементируем и получаем FD, а FD = -3
В самом деле FD + 03 = 00, т.е. -3 + 3 = 0
Tom91
Встал на лапы
Сообщения: 108
Зарегистрирован: Пт окт 08, 2010 15:43:55

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Tom91 »

Доброго времени суток!
Помогите определить точное время задержки, кварц 12Мгц (0,083мкс), при Тmp1 = 1

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

Delay1:
ldi Tmp2, 3

cycle:
dec Tmp2
brne cycle

dec Tmp1
brne Delay1
ret


Или вообщем мне нужно такую процедуру что-бы при кварце 12Мгц, выполнялось условие 2-3мкс * Tmp1 Кто что предложит?
Аватара пользователя
ibiza11
Поставщик валерьянки для Кота
Сообщения: 1900
Зарегистрирован: Сб фев 21, 2009 13:11:40
Откуда: Москва

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение ibiza11 »

с учетом вызова подрограммы командой rcall, задержка составляет 1,5мкс = 18 циклов.
Изображение
Вложения
test.JPG
(17.12 КБ) 990 скачиваний
Ставим плюсы: )
Nicke
Первый раз сказал Мяу!
Сообщения: 27
Зарегистрирован: Вт фев 09, 2010 19:21:27
Откуда: Belarus

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Nicke »

Помогите.... Вот проблема на 644 меге.
пишу на АВР студио..
считываю полученные данные с компа
ldi r16,0xff ;r16-ff
;udr - помещаю 0x49
lds r16,udr0
и после этой команды получаю в р16 - 0х00!!!!
Если делаю на меге8 все работает а на 644 при считывании с UDR я получаю 00.
Аватара пользователя
Gudd-Head
Друг Кота
Сообщения: 20092
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Re: Ассемблер (ASM) для AVR в вопросах и ответах

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

Nicke писал(а):lds r16,udr0

Попробуйте

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

in r16,udr0

Хотя, вообще не очень понятно что вы делаете и что в итоге хотите получить.
Последний раз редактировалось Gudd-Head Вт янв 25, 2011 14:44:27, всего редактировалось 1 раз.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Аватара пользователя
Engineer_Keen
Друг Кота
Сообщения: 3871
Зарегистрирован: Пт янв 29, 2010 10:27:40
Откуда: Москва

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Engineer_Keen »

Gudd-Head писал(а):
Nicke писал(а):lds r16,udr0

Попробуйте

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

in r16,udr0


Не дотянется... у меги644 адрес UDR0 - 0xC6
Думаю проблема не в этом. Нужен кусок кода по крупнее.
Аватара пользователя
DX168B
Друг Кота
Сообщения: 4468
Зарегистрирован: Вс янв 24, 2010 19:19:52
Откуда: Главный Улей России (Moscow)
Контактная информация:

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение DX168B »

Командой lds желательно считывать байты из ОЗУ, in - из регистров периферии и SREG, mov - из одного регистра РОН в другой РОН.

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

in r16, udr0
lds r16, 0x0060
mov r16, r17
I am DX168B and this is my favourite forum on internet!
Аватара пользователя
Engineer_Keen
Друг Кота
Сообщения: 3871
Зарегистрирован: Пт янв 29, 2010 10:27:40
Откуда: Москва

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Engineer_Keen »

Недостаток инструкции IN в том, что она дальше адреса 0x3F не работает :(
Кстати, посмотрел пример приема байта по UART на мегу644, там стоит IN R16,UDRn. Или я что-то не догоняю, или они примеры тупо из одного документа в другой копируют....
Аватара пользователя
Gudd-Head
Друг Кота
Сообщения: 20092
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Re: Ассемблер (ASM) для AVR в вопросах и ответах

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

Да, in/out дальше 3F не работает. Признаюсь, лень было скачивать даташит. Согласен, надо через LDS.
Возможно, студия что-то криво подставляет, и можно поробовать задать адрес напрямую:

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

LDS r16, $00C6; C6 - адрес UDR0
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Nicke
Первый раз сказал Мяу!
Сообщения: 27
Зарегистрирован: Вт фев 09, 2010 19:21:27
Откуда: Belarus

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Nicke »

Вообщем вот код.

.include "m644def.inc"
.list

.equ button1=0
.equ button2=1

.def temp=r16
.def countH=r17
.def countL=r18
.def data=r19

.dseg
buf: .byte 1000

.cseg
.org 0

;Инициализация стека
ldi temp, low(RAMEND)
out SPL, temp
ldi temp, high(RAMEND)
out SPH, temp

;Инициализация USART
ldi R16,$00 ;USART.Mode=9600,N,1(16Mhz)
sts UCSR0A,R16
ldi R16,$06
sts UCSR0C,R16
ldi R16,$67
sts UBRR0L,R16
ldi R16,$00
sts UBRR0H,R16
ldi R16,$18
sts UCSR0B,R16

;Отключаем компоратор
ldi temp, 0x80
out ACSR, temp

;Инициализация портов
ldi temp, 0xFF
out DDRB, temp
ldi temp, 0x00
out DDRC, temp ;Порт C на ввод
ldi temp, 0xFF
out PORTC, temp ;Включаем подтягивающие резисторы



;======================;
;Начало работы устройства
;======================;
start:
lds r20,UCSR0A
sbrs r20, RXC0
rjmp start
lds r16, UDR0 ;ЗДЕСЬ В R16 ПОМЕЩАЕТСЯ НУЛИ

out PORTB,r16
lds r20,UCSR0A
sbrs r20, RXC0
rjmp start1
lds r16, UDR0
rjmp (PC-4)

start1:
sts UDR0,r16
lds R16,UCSR0A
sbrs R16,UDRE0
rjmp (PC-3)

rjmp start


Пробывал адрес памяти давать на прямую тоже самое. На другом компе тоже самое, в ПРотеусе тоже не работает. Осталось только застрелиться. Хотя беру мегу8 теже операции блин работает. А lds потому что адрес "c6" а что они в даташите пишут так вообщем описывают принцип действия, хотя скорее всего копируют.
Аватара пользователя
Engineer_Keen
Друг Кота
Сообщения: 3871
Зарегистрирован: Пт янв 29, 2010 10:27:40
Откуда: Москва

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Engineer_Keen »

Nicke писал(а):в ПРотеусе тоже не работает.

Только что скопировал, скомпилировал, запустил в протеусе.
Результ: байт с USART выводится и PORTB и посылается обратно в USART.
Так ведь и должно быть по задумке?
Ответить

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