Ассемблер (ASM) для AVR в вопросах и ответах
Это сделано для проверки работы USART. А вот у меня работать так и не начала. Кварц 16МГц. не в железе не симуляторе. Посылаю 0x46 вижу на порту Б 0xFF.
- Реклама
ну у меня хотя бы в симуляторе работает
Может фьюзы не так выставлены, или скорость в терминале, или линии RxD-TxD перепутаны...
Видели, что в заголовочнике на мегу644 пишут?
0х3F - это SREG. Дальше него идёт уже под меткой MEMORY MAPPED.
Код: Выделить всё
; Definitions marked "MEMORY MAPPED"are extended I/O ports
; and cannot be used with IN/OUT instructions
.equ UDR1 = 0xce ; MEMORY MAPPED
.equ UBRR1L = 0xcc ; MEMORY MAPPED
.equ UBRR1H = 0xcd ; MEMORY MAPPED
.equ UCSR1C = 0xca ; MEMORY MAPPED
.equ UCSR1B = 0xc9 ; MEMORY MAPPED
.equ UCSR1A = 0xc8 ; MEMORY MAPPED
.equ UDR0 = 0xc6 ; MEMORY MAPPED
.equ UBRR0L = 0xc4 ; MEMORY MAPPED
.equ UBRR0H = 0xc5 ; MEMORY MAPPED
.equ UCSR0C = 0xc2 ; MEMORY MAPPED
.equ UCSR0B = 0xc1 ; MEMORY MAPPED
.equ UCSR0A = 0xc0 ; MEMORY MAPPED
.equ TWAMR = 0xbd ; MEMORY MAPPED
.equ TWCR = 0xbc ; MEMORY MAPPED
.equ TWDR = 0xbb ; MEMORY MAPPED
.equ TWAR = 0xba ; MEMORY MAPPED
.equ TWSR = 0xb9 ; MEMORY MAPPED
.equ TWBR = 0xb8 ; MEMORY MAPPED
.equ ASSR = 0xb6 ; MEMORY MAPPED
.equ OCR2B = 0xb4 ; MEMORY MAPPED
.equ OCR2A = 0xb3 ; MEMORY MAPPED
.equ TCNT2 = 0xb2 ; MEMORY MAPPED
.equ TCCR2B = 0xb1 ; MEMORY MAPPED
.equ TCCR2A = 0xb0 ; MEMORY MAPPED
.equ OCR1BL = 0x8a ; MEMORY MAPPED
.equ OCR1BH = 0x8b ; MEMORY MAPPED
.equ OCR1AL = 0x88 ; MEMORY MAPPED
.equ OCR1AH = 0x89 ; MEMORY MAPPED
.equ ICR1L = 0x86 ; MEMORY MAPPED
.equ ICR1H = 0x87 ; MEMORY MAPPED
.equ TCNT1L = 0x84 ; MEMORY MAPPED
.equ TCNT1H = 0x85 ; MEMORY MAPPED
.equ TCCR1C = 0x82 ; MEMORY MAPPED
.equ TCCR1B = 0x81 ; MEMORY MAPPED
.equ TCCR1A = 0x80 ; MEMORY MAPPED
.equ DIDR1 = 0x7f ; MEMORY MAPPED
.equ DIDR0 = 0x7e ; MEMORY MAPPED
.equ ADMUX = 0x7c ; MEMORY MAPPED
.equ ADCSRB = 0x7b ; MEMORY MAPPED
.equ ADCSRA = 0x7a ; MEMORY MAPPED
.equ ADCH = 0x79 ; MEMORY MAPPED
.equ ADCL = 0x78 ; MEMORY MAPPED
.equ PCMSK3 = 0x73 ; MEMORY MAPPED
.equ TIMSK2 = 0x70 ; MEMORY MAPPED
.equ TIMSK1 = 0x6f ; MEMORY MAPPED
.equ TIMSK0 = 0x6e ; MEMORY MAPPED
.equ PCMSK2 = 0x6d ; MEMORY MAPPED
.equ PCMSK1 = 0x6c ; MEMORY MAPPED
.equ PCMSK0 = 0x6b ; MEMORY MAPPED
.equ EICRA = 0x69 ; MEMORY MAPPED
.equ PCICR = 0x68 ; MEMORY MAPPED
.equ OSCCAL = 0x66 ; MEMORY MAPPED
.equ PRR0 = 0x64 ; MEMORY MAPPED
.equ CLKPR = 0x61 ; MEMORY MAPPED
.equ WDTCSR = 0x60 ; MEMORY MAPPED
.equ SREG = 0x3f
I am DX168B and this is my favourite forum on internet!
Ну так поэтому через LDS, и как я говорил - в симуляторе работает.
Да нет фьюзы точно норм стоят да и остальное проверилEngineer_Keen писал(а):ну у меня хотя бы в симуляторе работаетМожет фьюзы не так выставлены, или скорость в терминале, или линии RxD-TxD перепутаны...
Вот качаю 4.6 авр студио попробую поставить.
Вот скрин шоты ошибки на 5 компах пробывал все одинаково!!!
- Вложения
-
- 1a.JPG
- (183.14 КБ) 388 скачиваний
-
- 2.JPG
- (183.22 КБ) 245 скачиваний
-
- 1.JPG
- (183.18 КБ) 391 скачивание
- Реклама
Вот выкладываю весь проект. Может в нем и че не так сейчас начну искать.
- Вложения
-
- project.RAR
- (21.6 КБ) 209 скачиваний
CLKDIV8 - запрограмморован, я же говорил с фьюзами косяк...
Да вы правы. Огромное спасибо! В протеусе работает (даже не обратил внимание на фьюз). Хотя в авр студио если делаешь тоже на меге8 можно назначить udr и он попадает в регистр, а вот мега644 так не работает. Завтра на железе фьюзы проверю.
100% доверять можно только железу. И у авр-студии и у протеуса есть свои косяки, но обычно или там, или там программа работает 
Да-да-да. Только если не стоит задача впарить лажу преподуEngineer_Keen писал(а):100% доверять можно только железу.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Моя очередь спрашивать
Уже пол дня туплю
По логике, вызов сей процедуры должен передавать через UART (в данном случае далее по RS485) 5 байт находящихся в ячейках buffer...buffer+5. И это так и происходит в протеусе. На деле, терминальная программа принимает на 2 байта меньше. Если поставить в сравнении buffer+6, +7 или +8, то принимаются соответственно 4, 5 или 6 байт (в протеусе соответственно 6, 7 или 8 ). Вот в чем косяк? Регистры XL-XH больше нигде не используются, SREG везде где надо сохраняется. Может в железе дело...
...Ну да, ступил немного, нужно перед переключением на прием MAX487 проверить что передача закончилась. Сделал, все равно один байт куда-то девается
...Поставил еще и задержку (опытным путем - 1.5 мс), теперь все передается правильно. В даташите на MAX487 нигде нет задержек такого порядка
Уже пол дня туплю
Код: Выделить всё
RS_TX: SBI PORTB,PB0 ;MAX487 на передачу
LDI XL,low(Buffer) ;Х на начало данных
TX_NEXT:LD R16,X+
WDR
TX_LOOP:SBIS UCSRA,UDRE ;ждем окончания
RJMP TX_LOOP ;предыдущей передачи
OUT UDR,R16 ;посылаем байт
CPI XL,low(Buffer+5) ;??? должно бы быть +5, но работает только с +7!!!
BRLO TX_NEXT ;если данные переданы не все... ^^^
LDI XL,low(Buffer) ;Х на начало
CBI PORTB,PB0 ;MAX487 на прием
RET
...Ну да, ступил немного, нужно перед переключением на прием MAX487 проверить что передача закончилась. Сделал, все равно один байт куда-то девается
...Поставил еще и задержку (опытным путем - 1.5 мс), теперь все передается правильно. В даташите на MAX487 нигде нет задержек такого порядка
Последний раз редактировалось Engineer_Keen Ср янв 26, 2011 15:34:59, всего редактировалось 1 раз.
Это шесть байтEngineer_Keen писал(а):5 байт находящихся в ячейках buffer...buffer+5
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Не много не правильно выразился, на самом деле конечно buffer...buffer+4, а buffer+5 - это критерий проверки адреса, но суть была не в этом 
Да на железе проверил, там с фьюзами норм, окозалась панелька хреновая на RX контакта не было, вот только тажа проблема получаю байт посылаю три в ответ а на компе 2 байта. Вот ставить задержку это идея, вот после каждого байта или нет?
можно ли в ассемблере для авр отдельно устанавливать биты в регистрах?
например, меня в какой-то момент программы не волнует, что стоит в битах GICR, нужно лишь чтобы 6-й установился после определенной команды.
и еще вопрос. если я хочу на время отключить прерывание таймера, мне достаточно в регистре TIMSK его запретить, ведь так? текущее значение таймера при этом сбросится или по разрешению он дальше побежит?
например, меня в какой-то момент программы не волнует, что стоит в битах GICR, нужно лишь чтобы 6-й установился после определенной команды.
и еще вопрос. если я хочу на время отключить прерывание таймера, мне достаточно в регистре TIMSK его запретить, ведь так? текущее значение таймера при этом сбросится или по разрешению он дальше побежит?
Нет таймер продолжит дальше работать, дёргая своим флагом прерывания. Можно просто отрубить его подделитель и он остановится. Прерывание его можно не запрещать в этом случае. Как только снова закинете значение в его подделитель, то он побежит дальше.
На счёт отдельных битов в регистрах специального назначения:
Для облегчения ввода отдельных битов, Вы можете записывать так:
В АВР Студии сбоку есть список всех регистров, сделанных в виде квадратиков.
От туда Вы можете узнать названия всех регистров и битов в них.
В даташите тоже есть описания регистров и названий их битов.
Вот и пользуйтесь названиями битов.
На счёт отдельных битов в регистрах специального назначения:
Для облегчения ввода отдельных битов, Вы можете записывать так:
Код: Выделить всё
;ATTINY2313
;--------------------------------------
ldi temp0, (1<<CS01) ;Настроим поделитель Таймера 0
out TCCR0B, temp0
ldi temp0, (1<<CS11) ;Настроим поделитель Таймера 1
out TCCR1B, temp0
ldi temp0, (1<<TOIE1)|(1<<TOIE0)
out TIMSK, temp0 ;Разрешим прерывания по переполнению обоих
;таймеров
;--------------------------------------
;Пример настройки порта.
ldi temp0, (1<<PD0)|(1<<PD3)
out DDRD, temp0 ;Настроим выводы PD0 и PD3 на выход.
;Теперь по очереди дёрнем каждой из этих ног.
sbi PORTD, PD0 ;Включим PD0
cbi PORTD, PD0 ;Выключим PD0
sbi PORTD, PD3 ;Включим PD3
cbi PORTD, PD3 ;Выключим PD3
От туда Вы можете узнать названия всех регистров и битов в них.
В даташите тоже есть описания регистров и названий их битов.
Вот и пользуйтесь названиями битов.
Последний раз редактировалось DX168B Ср янв 26, 2011 22:10:40, всего редактировалось 2 раза.
I am DX168B and this is my favourite forum on internet!
SBR,CBR,SBI,CBI,SEI,CLI и т.д.Necroteeth писал(а):можно ли в ассемблере для авр отдельно устанавливать биты в регистрах?
если напрямую SBI/CBI не получится (адрес больше 31), то можно загрузить в РОН, там его обработать командой SBR/CBR, и сохранитьNecroteeth писал(а): например, меня в какой-то момент программы не волнует, что стоит в битах GICR, нужно лишь чтобы 6-й установился после определенной команды.
Можно отключить прерывание (в TIMSK), можно отключить счет (биты прескалера в TCCRnB), можно сбросить (TCNT)- и все это независимо друг от друга.Necroteeth писал(а): и еще вопрос. если я хочу на время отключить прерывание таймера, мне достаточно в регистре TIMSK его запретить, ведь так? текущее значение таймера при этом сбросится или по разрешению он дальше побежит?
Вот тут у меня тоже непонятки. Запись (1<<TOIE1)|(1<<TOIE0) я понимаю, сдвиг влево на нужное количество бит и операция ИЛИ, в итоге получаем маску. А как тогда сбросить эти биты (я имею ввиду так же наглядно)DX168B писал(а):Нет таймер продолжит дальше работать, дёргая своим флагом прерывания. Можно просто отрубить его подделитель и он остановится. Прерывание его можно не запрещать в этом случае. Как только снова закинете значение в его подделитель, то он побежит дальше.
На счёт отдельных битов в регистрах специального назначения:
Для облегчения ввода отдельных битов, Вы можете записывать так:Код: Выделить всё
;ATTINY2313 ;-------------------------------------- ldi temp0, (1<<CS01) ;Настроим поделитель Таймера 0 out TCCR0B, temp0 ldi temp0, (1<<CS11) ;Настроим поделитель Таймера 1 out TCCR1B, temp0 ldi temp0, (1<<TOIE1)|(1<<TOIE0) out TIMSK, temp0 ;Разрешим прерывания по переполнению обоих ;таймеров ;-------------------------------------- ;Пример настройки порта. ldi temp0, (1<<PD0)|(1<<PD3) out DDRD, temp0 ;Настроим выводы PD0 и PD3 на выход.
Повторить тоже самое, но только с записью (0<<BITNAME0) в тех битах, которые надо сбросить и (1<<BITNAME1) в тех битах, которые должны остаться установленными. По сути, при такой записи в ассемблере не делается никакого сдвига влево и операции "ИЛИ" так как такая запись выполняется за 1 такт, просто компилятор просчитывает по именам указанных битов значение, которое в итоге должно сформироваться в регистре. Операция сдвига происходит только в Сишных кодах, при такой записи.
Последний раз редактировалось DX168B Ср янв 26, 2011 22:39:10, всего редактировалось 1 раз.
I am DX168B and this is my favourite forum on internet!


