Карма: 1
Рейтинг сообщений: 3
Зарегистрирован: Пн сен 01, 2008 14:49:03 Сообщений: 151 Откуда: Казахстан
Рейтинг сообщения:0
Ожидая конца преобразования, не надо постоянно ставить в "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 раз.
Ну в Студии у меня тоже все работает.. и даже когда я это код для АЦП просто в программу пихаю.. а вот в прерывании в Протеусе не хочет и все.... может дело в симуляторе?
_________________ Не бери от жизни все, а то не унесешь...
Ну в Студии у меня тоже все работает.. и даже когда я это код для АЦП просто в программу пихаю.. а вот в прерывании в Протеусе не хочет и все.... может дело в симуляторе?
Попробуйте делитель побольше поставить, при частоте 16 МГц у вас выставлен делитель тактирования АЦП - 8, т. е. тактовая частота АЦП - 2 МГц, а по даташиту должна быть до 200 КГц (в принципе можно и больше при уменьшении разрешающей способности, но думаю что 2МГц это перебор), могут быть из-за этого глюки, и YurkaM тоже верно говорит, я не заметил что у вас постоянно бит ADSC устанавливается. В вашем случае оптимальный делитель будет делитель 128, т.е.
Код:
ldi r19, (1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0) out ADCSRA, r19
Конечно есть шанс, что дело в симуляторе, вобщем железо - лучший симулятор!
Спасибо за помощь.. я нашел ошибки..теперь все работает!!
Если Вас не затруднит у меня еще вопрос: у меня в регистре число.Мне надо чтобы при попадании в определенный диапазон чисел я попадал на метку иначе дальше, как это реализовать на асме? например есть число 125 и два диапазона: 0-127(переход на метку 1), 128-255 (переход на метку 2), не догоню как слепить..))
_________________ Не бери от жизни все, а то не унесешь...
....Мне надо чтобы при попадании в определенный диапазон чисел я попадал на метку иначе дальше, как это реализовать на асме? например есть число 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;
вопрос такой: почему огонек всевремя бежит, а не показывает комбинацию 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
интересует вот это место
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
Зарегистрирован: Вс мар 04, 2007 01:17:12 Сообщений: 690
Рейтинг сообщения:0
Мега8
как в асме выставлять/снимать один бит порта не изменяя остальных?
например у меня пины портаБ на вход и что то на выход работает, мне нужно прочесть PB0 (вход) и выставить в зависимости от его значения на PB1 (выход) 0 или 1.
понятно что прочесть придется весь порт in r16,pinb
вход PB0 пусть оказался равен "0", это можно проверить SBRS или SBRC
а теперь мне нужно только на PB1 выставить "1" не меняя остальные биты (т.е. вариант послать в порт 0xFF не прокатывает)
Карма: 1
Рейтинг сообщений: 3
Зарегистрирован: Пн сен 01, 2008 14:49:03 Сообщений: 151 Откуда: Казахстан
Рейтинг сообщения:0
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
Карма: 1
Рейтинг сообщений: 3
Зарегистрирован: Пн сен 01, 2008 14:49:03 Сообщений: 151 Откуда: Казахстан
Рейтинг сообщения:0
А если надо изменить сразу несколько пинов порта, то удобно делать логическое ИЛИ, предварительно погасив в ноль ненужные биты в обоих регистрах. Например так:
Код:
;tmpb содержит байт, биты 0-3 которого надо вывести в порт B in tmpa,PORTB andi tmpa,0b11110000 andi tmpb,0b00001111 or tmpa,tmpb out PORTB,tmpa
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 27
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения