Перейти к содержанию

первые шаги программирования микроконтроллеров AVR


Гость vasek_vasechek

Рекомендуемые сообщения

литература: Дж. Мортон "микроконтроллеры вводный курс"

программное обеспечение: AVR Studio 5

proteus 7.7

 

суть проблемы:

в какой то степени успешно изучил главу посвященную теории, перешел к практическому программированию и тут завалился,

программа заключается во включении светодиода при помощи кнопки, и первое и второе подключено к МК

если переписывать текст программы из учебника - то все работает, если пойти своим путем - то на выходе от попы уши

вот схема в proteus'e:post-20436-1392894115_thumb.png

 

вот текст программы с комментариями:

;*******************************

;Автор: Vasechek

;Дата:

;Версия:

;Название файла:

;Для AVR: ATtiny2313

;тактовая частота: 8 МГц

;*******************************

 

;выполняемые функции: включение светодиода при нажатии кнопки

 

;*******************************

.def temp=r16 ; присвоение регситру r16 имени temp

ser temp ; установка значения temp в 1

out ddrb, temp; определение порта вкачестве ВЫХодного

ldi temp,0b11111110; оределение

out ddrd,temp; pd0 в качестве ВХодного

clr temp; очистка рабочего регистра

out portb, temp; отключение подтягивающих регистров

out portd, temp; отключение подтягивающих регистров

rjmp check; переход к проверке состояния кнопки

check:; проверка сост кнопки

in temp,pind; запись в temp состояния кнопки

out portb,temp; включение СИД

rjmp check; переход на проверку состяния кнопки

 

 

во время эмуляции при первом нажатии на кнопку СИД загорается и в дальнейшем горит независимо от состояния кнопки,

пытаясь выяснить в чем дело - уже весь мозг сломал :smile: :smile: :smile:

Ссылка на комментарий
Поделиться на другие сайты

У вас в программе присутствует только код, отвечающий за включение светодиода. А нужно сделать условный оператор. Если светодиод горит, выключить, если не горит, включить.

Прежде чем писать код, нарисуйте алгоритм, не так уж это и долго. Зато всё сразу станет понятно.

Ссылка на комментарий
Поделиться на другие сайты

это ничего не изменит, вот блок-схема:post-20436-1392919490.png

проблема в том, что данный алгоритм можно программно и в железе реализовать двумя способами:

 

1) на кнопку подать напряжение,

с входного порта - отключить подтягивающий регистр,

СИД к подключить к выходному порту и к "земле"

 

тогда програмно:

мы считываем а) нажата кнопка- напряжение источника подано вх.порт - "1"

б) отжата кнопка - напряжение равно нулю на вх. порте - "0"

затем перезаписываем через рабочий регистр temp значение порта D в порт B при помощи команд pinD & out

таким образом в случае а) на выход подается логическая "1"=напряжению высокого уровня => СИД должен загореться

б) на выход подается логический "0" = нулевому напряжению => СИД должен погаснуть

на самом деле - он до нажатия - не горит как ему и положено

после нажатия - загорается

как отпускаешь кнопку - ПРОДОЛЖАЕТ ГОРЕТЬ!!!

2) кнопка подключается к земле

на входной порт - подключается подтягивающий регистр

СИД подключается к шине питания и выходному порту

 

в этом случае: а)нажата кнопка- снимается напряжение с вх.порта - устанавливается тем самым "0"

б) отжата кнопка - напряжение соответствует напряжению подтягивающего регистрана вх. порта - т.е. "1"

 

затем проделываем те же самые операции что и в первом случае

в итоге - нажата кнопка - горит СИД

отпустили кнопку - погас СИД

вот схема и код программы по второму варианту(как в учебнике)

post-20436-1392921582_thumb.png

 

.def temp=r16 ; присвоение регситру r16 имени temp

ser temp ; установка значения temp в 1

out ddrb, temp; определение порта вкачестве ВЫХодного

ldi temp,0b11111110; оределение

out ddrd,temp; pd0 в качестве ВХодного

clr temp; очистка рабочего регистра

out portb, temp; отключение подтягивающих регистров

ldi temp,0b00000001; подключение

out portd, temp; подтягивающего регистра в порт pb0

rjmp check; переход к проверке состояния кнопки

check:; проверка сост кнопки

in temp,pind; запись в temp состояния кнопки

out portb,temp; включение СИД

rjmp check; переход на проверку состяния кнопки

 

НУ ПОЧЕМУ 2 ВАРИАНТ РАБОТАЕТ, А 1 (МОЙ) НЕТ???? :smile:

Ссылка на комментарий
Поделиться на другие сайты

во-первых схема:

а) нажата кнопка- напряжение источника подано вх.порт - "1"

б) отжата кнопка - напряжение равно нулю на вх. порте - "0"

У вас в симуляции кнопка подключена на землю, всё работает наоборот. Нажатие даёт ноль, отпускаем - единица.

 

Далее:

clr temp; очистка рабочего регистра
out portb, temp; отключение подтягивающих [b]резисторов[/b]
out portd, temp; отключение подтягивающих [b]резисторов[/b]

подтягивающий регистр? что за бред?

Мы очищаем ячейку temp(r16), в ней оказывается 0b00000000, и ничего туда не перезаписываем.

Следующими двумя строчками все резисторы портов B И D отключены! А на PD0 должен быть подтягивающий резистор, иначе его состояние не определено. Достаточно подать на этот вход разок ноль, так он там и останется (по крайней мере в симуляторе)

 

Как этот участок выглядит в работающий программе:

clr temp; очистка рабочего регистра
out portb, temp; отключение подтягивающих резисторов
ldi temp,0b00000001; подключение
out portd, temp; подтягивающего резистора в порт pb0

вот тут резистор включается как надо.

 

Кстати, отключаемые/подключаемые резисторы у атмель полная фигня имеют очень большой номинал, так что желательно на входах использовать внешние резисторы

Попробуйте не меняя программу добавить в протеусе отдельный подтягивающий резистор, должно всё заработать.

Изменено пользователем yamazaki
Ссылка на комментарий
Поделиться на другие сайты

схема, приведенная в первом моем сообщении соответствует первому моему случаю(который не работает)

 

2 схема приведенная во втором сообщении соответствует второму случаю (под цифрой 2)

 

так что в плане подключения я считаю что все правильно:

1) снимается 1 со входа - перезаписывается на выход и уходит через диод на землю

2) снимается 0 со входа - перезаписывается на выход и убирает 1 с выхода, т. о. ток течет из + через диод в МК

 

 

 

Добавлено после раздумий:

все наконец получилось!!!

да, согласен подтягивающие резисторы называл регистрами - это косяк, невнимательно читал литературу, но не в них было дело вот две схемы:

 

 

1)post-20436-1392970034_thumb.png - это мой первоначальный вариант - который не работал

 

2) post-20436-1392970235_thumb.png -здесь входной порт выведен на землю через резистор, тем самым снимая установленную "1" во входной порт D

 

текст программы оставил без изменений:

 

.def temp=r16 ; присвоение регситру r16 имени temp
ser temp ; установка значения temp в 1
out ddrb, temp; определение порта вкачестве ВЫХодного
ldi temp,0b11111110; оределение
out ddrd,temp;       pd0 в качестве ВХодного 
clr temp; очистка рабочего регистра
out portb, temp; отключение подтягивающих резисторов
out portd, temp; отключение подтягивающих резисторов
rjmp check; переход к проверке состояния кнопки
check:; проверка сост кнопки
in temp,pind; запись в temp состояния кнопки
out portb,temp; включение СИД
rjmp check; переход на проверку состяния кнопки

 

хочу еще отметить что попытка снять "1" с pd0 программно (а не резистором) результата не дала

Ссылка на комментарий
Поделиться на другие сайты

Встроенные резисторы подтягивают всегда к Vcc, т.к. они "pullup"

Соответственно, кнопка должна подключаться на землю.

 

Можно сделать чтобы кнопка подключала вход к Vcc, но тогда подтягивающий резистор на землю должен быть внешний.

Изменено пользователем yamazaki
Ссылка на комментарий
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...