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

Обсуждаем контроллеры компании Atmel.
smac
Мучитель микросхем
Сообщения: 459
Зарегистрирован: Вс июн 01, 2008 12:16:38

Сообщение smac »

Demontrup писал(а):Ребята в процессе отладки в Протеусе выяснил что у меня не работает АЦП, кто может сказать почему? вот переписал без всего лишнего:

Тактовая частота контроллера какая?
Аватара пользователя
Demontrup
Первый раз сказал Мяу!
Сообщения: 22
Зарегистрирован: Вт мар 25, 2008 16:23:57
Откуда: Астрахань

Сообщение Demontrup »

16 МГЦ
Не бери от жизни все, а то не унесешь...
YurkaM
Нашел транзистор. Понюхал.
Сообщения: 151
Зарегистрирован: Пн сен 01, 2008 14:49:03
Откуда: Казахстан

Сообщение YurkaM »

Ожидая конца преобразования, не надо постоянно ставить в "1" ADSC. Попробуй так:

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

start: 
   sbi adcsra,ADSC
_wait_adc:
   sbic adcsr,ADSC
   rjmp _wait_adc
   in r17, ADCL
   in r18, ADCH


А ещё лучше так:

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

start:
   sbi adcsra,ADSC   ;запуск АЦП
_wait_adc:
    sbis    ADCSRA,ADIF   ;ждем конца преобразования(ADIF=1)
    rjmp    _wait_adc
    sbi    ADCSRA,ADIF   ;сбрасываем флаг ADIF
    in r17, ADCL
    in r18, ADCH


Честно говоря в первом варианте не уверен, т.к. всегда для контроля конца преобразования отслеживал именно флаг ADIF - он срабатывает когда данные готовы для считывания. Только надо не завывать его сбрасывать принудительно (если бы это было в прерывании, то он сбросился бы аппаратно).
Последний раз редактировалось YurkaM Вс фев 22, 2009 20:48:24, всего редактировалось 1 раз.
Аватара пользователя
Demontrup
Первый раз сказал Мяу!
Сообщения: 22
Зарегистрирован: Вт мар 25, 2008 16:23:57
Откуда: Астрахань

Сообщение Demontrup »

Спасибо, но все равно не хочет работать.. я уже начинаю нервничать..надо валерьяночки хлебнуть)))
Не бери от жизни все, а то не унесешь...
YurkaM
Нашел транзистор. Понюхал.
Сообщения: 151
Зарегистрирован: Пн сен 01, 2008 14:49:03
Откуда: Казахстан

Сообщение YurkaM »

Ну, не знаю... В симуляторе АВР-студио всё работает. Только естественно PIND,2 приходится руками галку ставить/убирать.
Аватара пользователя
Demontrup
Первый раз сказал Мяу!
Сообщения: 22
Зарегистрирован: Вт мар 25, 2008 16:23:57
Откуда: Астрахань

Сообщение Demontrup »

Ну в Студии у меня тоже все работает.. и даже когда я это код для АЦП просто в программу пихаю.. а вот в прерывании в Протеусе не хочет и все.... может дело в симуляторе?
Не бери от жизни все, а то не унесешь...
smac
Мучитель микросхем
Сообщения: 459
Зарегистрирован: Вс июн 01, 2008 12:16:38

Сообщение smac »

Demontrup писал(а):Ну в Студии у меня тоже все работает.. и даже когда я это код для АЦП просто в программу пихаю.. а вот в прерывании в Протеусе не хочет и все.... может дело в симуляторе?

Попробуйте делитель побольше поставить, при частоте 16 МГц у вас выставлен делитель тактирования АЦП - 8, т. е. тактовая частота АЦП - 2 МГц, а по даташиту должна быть до 200 КГц (в принципе можно и больше при уменьшении разрешающей способности, но думаю что 2МГц это перебор), могут быть из-за этого глюки, и YurkaM тоже верно говорит, я не заметил что у вас постоянно бит ADSC устанавливается. В вашем случае оптимальный делитель будет делитель 128, т.е.

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

   ldi r19, (1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0)
   out ADCSRA, r19

Конечно есть шанс, что дело в симуляторе, вобщем железо - лучший симулятор!
Аватара пользователя
Demontrup
Первый раз сказал Мяу!
Сообщения: 22
Зарегистрирован: Вт мар 25, 2008 16:23:57
Откуда: Астрахань

Сообщение Demontrup »

Спасибо, но все равно не работает))))))) на днях сваяю в железе.. посмотрю может симулятор действительно врет..
Не бери от жизни все, а то не унесешь...
YurkaM
Нашел транзистор. Понюхал.
Сообщения: 151
Зарегистрирован: Пн сен 01, 2008 14:49:03
Откуда: Казахстан

Сообщение YurkaM »

Да забей ты на этот Протеус - с ним постоянно будет вопрос "то-ли лыжи не едут, то-ли я еб...утый".........
Аватара пользователя
Demontrup
Первый раз сказал Мяу!
Сообщения: 22
Зарегистрирован: Вт мар 25, 2008 16:23:57
Откуда: Астрахань

Сообщение Demontrup »

Спасибо за помощь.. я нашел ошибки..теперь все работает!!
Если Вас не затруднит у меня еще вопрос: у меня в регистре число.Мне надо чтобы при попадании в определенный диапазон чисел я попадал на метку иначе дальше, как это реализовать на асме? например есть число 125 и два диапазона: 0-127(переход на метку 1), 128-255 (переход на метку 2), не догоню как слепить..))
Не бери от жизни все, а то не унесешь...
smac
Мучитель микросхем
Сообщения: 459
Зарегистрирован: Вс июн 01, 2008 12:16:38

Сообщение smac »

Demontrup писал(а):....Мне надо чтобы при попадании в определенный диапазон чисел я попадал на метку иначе дальше, как это реализовать на асме? например есть число 125 и два диапазона: 0-127(переход на метку 1), 128-255 (переход на метку 2), не догоню как слепить..))

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

; r16 - число
cpi r16, 127 ; сравниваем число с 127
brcc metka1 ; если флаг переноса не установлен, т. е. r16 меньше или равно 127, то переходим на метку1, иначе далее
; далее поскольку если беззнаковое целое 8-ми битное число больше
; 127, то оно в любом случае входит в диапазон 128-255, т. е здесь
; сразу может быть метка 2
metka2:
     ...some code;
    rjmp end_of_compare
metka1:
    ...some code;
    rjmp end_of_compare;

end_of_compare:
Аватара пользователя
Demontrup
Первый раз сказал Мяу!
Сообщения: 22
Зарегистрирован: Вт мар 25, 2008 16:23:57
Откуда: Астрахань

Сообщение Demontrup »

to smac Большое спасибо!!
Не бери от жизни все, а то не унесешь...
Invisible
Родился
Сообщения: 10
Зарегистрирован: Пт фев 20, 2009 19:25:14

Сообщение Invisible »

вопрос такой: почему огонек всевремя бежит, а не показывает комбинацию 10101010 по истечении 3х пробегов. вопрос конечно детский но всетаки. файлик почемуто не прикрепляется поэтому вот код
Begin:

ldi Temp,RamEnd ;инициализация стека
out SPL,Temp

ldi Temp,0b11111111 ;настройка портов
out DDRB,Temp

ldi Temp,0b00000001 ;вывод на индикацию
rcall Delay ;вызов подпрограммы задержки
ldi Temp,0b00000010 ;вывод на индикацию
rcall Delay ;вызов подпрограммы задержки
ldi Temp,0b00000100 ;вывод на индикацию
rcall Delay ;вызов подпрограммы задержки
ldi Temp,0b00001000 ;вывод на индикацию
rcall Delay ;вызов подпрограммы задержки

ldi Temp4, 3 ;загрузка числа 3 в регистр Temp4
dec Temp4 ;вычитание из Temp4
brne Begin ;переход к метке если результат преведущего действия не 0
;*************************************************
ldi temp, 0b10101010 ;записываем в temp 10101010
out PortB, temp ;вывод на порт B 10101010
;задержка***
ldi Temp1,0
ldi Temp2,0
ldi Temp3,10

Loop1: dec Temp1
brne Loop1
dec Temp2
brne Loop1
dec Temp3
brne Loop1
;подпрограмма задержки**********************************
Delay: out PortB,Temp

ldi Temp1,0
ldi Temp2,0
ldi Temp3,10

Loop: dec Temp1
brne Loop
dec Temp2
brne Loop
dec Temp3
brne Loop
ret
Invisible
Родился
Сообщения: 10
Зарегистрирован: Пт фев 20, 2009 19:25:14

Сообщение Invisible »

интересует вот это место
ldi Temp4, 3 ;загрузка числа 3 в регистр Temp4
dec Temp4 ;вычитание из Temp4
brne Begin ;переход к метке если результат преведущего действия не 0
почему не работает?
когда делаешь так
ldi Temp4, 3 ;загрузка числа 3 в регистр Temp4
dec Temp4 ;вычитание из Temp4
breq Begin1 ;переход к метке если результат преведущего действия 0
Begin1: ldi temp, 0b10101010 ; загружаем в temp 10101010
out PortB, temp ;вывод в порт B 10101010
все работает толькопробегает один раз а не 3
Аватара пользователя
asteroid7
Опытный кот
Сообщения: 703
Зарегистрирован: Вс янв 18, 2009 21:12:49

Сообщение asteroid7 »

Программа каждый раз перезагружает Temp4. Загрузку ldi Temp4, 3 нужно выносить за пределы цикла.
Аватара пользователя
Alexeus
Вымогатель припоя
Сообщения: 690
Зарегистрирован: Вс мар 04, 2007 01:17:12

Сообщение Alexeus »

Мега8

как в асме выставлять/снимать один бит порта не изменяя остальных?

например у меня пины портаБ на вход и что то на выход работает, мне нужно прочесть PB0 (вход) и выставить в зависимости от его значения на PB1 (выход) 0 или 1.

понятно что прочесть придется весь порт in r16,pinb
вход PB0 пусть оказался равен "0", это можно проверить SBRS или SBRC
а теперь мне нужно только на PB1 выставить "1" не меняя остальные биты (т.е. вариант послать в порт 0xFF не прокатывает)

как?
YurkaM
Нашел транзистор. Понюхал.
Сообщения: 151
Зарегистрирован: Пн сен 01, 2008 14:49:03
Откуда: Казахстан

Сообщение YurkaM »

Alexeus писал(а):понятно что прочесть придется весь порт in r16,pinb

Не обязательно. Применительно к твоей задаче, например так:

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

   sbic  PINB,0   ; если пин 0 порта B сброшен, то сл. команду пропустить
   rjmp  _clear   ; прыгаем на сброс B1 в "0"
   sbi   PORTB,1  ; ставим в "1" бит 1 порта B
   rjmp  _end     ; всё сделали, уходим
_clear:
   cbi   PORTB,1  ; обнуляем бит 1 порта B
_end:


Или так:

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

in tmpa,PINB   ;читаем пины порта B
com tmpa       ;инвертируем (это для твоего алгоритма)
bst tmpa,0     ;запоминаем в T значение 0-го бита
  cli  ;запрет прерываний. Это надо только если есть прерывания, работающие с портом B
in tmpa,PORTB   ;читаем текущее состояние PORTB
bld tmpa,1      ;пишем T в 1-й бит
out PORTB,tmpa  ;выводим в порт
  sei  ;разрешение прерываний. Если выше была команда cli


Можно ещё че-нить придумать наверное... :)
YurkaM
Нашел транзистор. Понюхал.
Сообщения: 151
Зарегистрирован: Пн сен 01, 2008 14:49:03
Откуда: Казахстан

Сообщение YurkaM »

А если надо изменить сразу несколько пинов порта, то удобно делать логическое ИЛИ, предварительно погасив в ноль ненужные биты в обоих регистрах. Например так:

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

;tmpb содержит байт, биты 0-3 которого надо вывести в порт B
in tmpa,PORTB
andi  tmpa,0b11110000
andi  tmpb,0b00001111
or    tmpa,tmpb
out   PORTB,tmpa
Аватара пользователя
Alexeus
Вымогатель припоя
Сообщения: 690
Зарегистрирован: Вс мар 04, 2007 01:17:12

Сообщение Alexeus »

спасибище, пошел анализировать :)
nppElM
Родился
Сообщения: 12
Зарегистрирован: Чт мар 05, 2009 10:32:23

Сообщение nppElM »

Помогите пожалуйста с иницаализацией таймера мк AtMega2561
AVRStudio

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

      ldi    TMP_Y,(1<<CS00)+(1<<CS01);запускаем счетчик OSC/64 = 1.015 msec      
   out   TCCR0B,TMP_Y ; предделитель в регистр записался
   
   ldi   TMP_Y,1<<TOV0 ; здесь в регистр записыветься
   out    TIFR0,TMP_Y ; а здесь не как не перемещается и через sts тож не в какую
   
        ldi   TMP_Y,1<<TOIE0 ; здесь в регистр записыветься
   sts    TIMSK0,TMP_Y   ;Установливаеться флаг для прерывания по переполнению

Что не так пишу???
Ответить

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