реклама на сайте
подробности

 
 
> Программирование MCS-51, Настройка портов на ввод
Jead
сообщение Jan 2 2012, 18:23
Сообщение #1





Группа: Участник
Сообщений: 12
Регистрация: 30-10-11
Пользователь №: 68 056



Ребят, тут такая ситуация, написал код для программы, вроде синтаксически правильный и т.д. Но при этом не работал. Подкинули идею, что я не настроил порты на ввод и вывод.. Тут с прискорбием пришлось признать, что я не в курсе как это делается.. Знаю, что это основы, но видать прослушал на лекциях. помню что-то про установление единицы в фиксатор, но не знаю, как сделать.

Собственно, сам код.

Код
SJMP BEGIN
ORG 0000h
BEGIN:             MOV                  P1,#00001000b
M4:
                  MOV            A,#00000000b
          JNB                  P1.0,M1
                  INC                   A
M1:
                  JNB                  P1.1,M2
                  INC                   A
M2:
                  JNB                  P1.2,M3
                  INC                   A
M3:
                  JZ                      M4
                  MOV                  P1,#00000000b
                  DJNZ                  A,M5
          DJNZ                  A,M6
          MOV                  P1#01000000b
                  SJMP                   M4
M5:
                  MOV                  P1,#00010000b
                  SJMP                   M4  
M6:
          MOV                  P1,#00100000b
                  SJMP                   M4
                  END


Сообщение отредактировал Jead - Jan 2 2012, 18:25
Go to the top of the page
 
+Quote Post
2 страниц V   1 2 >  
Start new topic
Ответов (1 - 22)
kovigor
сообщение Jan 2 2012, 19:17
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 5 273
Регистрация: 30-03-10
Пользователь №: 56 295



Цитата(Jead @ Jan 2 2012, 21:23) *
Ребят, тут такая ситуация, написал код для программы, вроде синтаксически правильный и т.д. Но при этом не работал. Подкинули идею, что я не настроил порты на ввод и вывод.. Тут с прискорбием пришлось признать, что я не в курсе как это делается.. Знаю, что это основы, но видать прослушал на лекциях. помню что-то про установление единицы в фиксатор, но не знаю, как сделать.


Давно дело было, не хочу выдумывать. Посмотрите книжечку Урусова:

http://lord-n.narod.ru/walla.html
Go to the top of the page
 
+Quote Post
Harbinger
сообщение Jan 2 2012, 20:19
Сообщение #3


старший лаборант
******

Группа: Свой
Сообщений: 2 702
Регистрация: 30-09-05
Из: ЮЗЖД
Пользователь №: 9 097



Озвучьте конкретную модель микроконтроллера. В классических интеловских 51 порты были квазидвунаправленными и, чтобы линия работала на ввод, было достаточно записать 1 в соответствующий бит регистра порта. Но во всевозможных деривативах другая ситуация, имеются дополнительные регистры для задания режимов работы портов, при этом у каждого производителя своя идеология...


--------------------
Китайская комплектация - европейское качество! ;)
Go to the top of the page
 
+Quote Post
Jead
сообщение Jan 2 2012, 21:20
Сообщение #4





Группа: Участник
Сообщений: 12
Регистрация: 30-10-11
Пользователь №: 68 056



Цитата(Harbinger @ Jan 2 2012, 23:19) *
Озвучьте конкретную модель микроконтроллера. В классических интеловских 51 порты были квазидвунаправленными и, чтобы линия работала на ввод, было достаточно записать 1 в соответствующий бит регистра порта. Но во всевозможных деривативах другая ситуация, имеются дополнительные регистры для задания режимов работы портов, при этом у каждого производителя своя идеология...

Классический..
Go to the top of the page
 
+Quote Post
Harbinger
сообщение Jan 2 2012, 23:37
Сообщение #5


старший лаборант
******

Группа: Свой
Сообщений: 2 702
Регистрация: 30-09-05
Из: ЮЗЖД
Пользователь №: 9 097



Тогда установка, допустим, P0.7 на ввод будет выглядеть как orl P0, #10000000b или orl P0, #80h (состояние остальных линий при этом не меняется).
С нулевым портом ещё нюанс аппаратного плана - чтобы можно было выводить туда единицу, надобно подтянуть соответствующую линию к плюсу питания резистором. Там в первом приближении выходы - открытый сток.


--------------------
Китайская комплектация - европейское качество! ;)
Go to the top of the page
 
+Quote Post
Jead
сообщение Jan 9 2012, 11:13
Сообщение #6





Группа: Участник
Сообщений: 12
Регистрация: 30-10-11
Пользователь №: 68 056



Спасибо! Т.е, если мне надо настроить все разряды на ввод это будет выглядеть как orl P1,#11111111b?
Go to the top of the page
 
+Quote Post
Jead
сообщение Jan 11 2012, 12:17
Сообщение #7





Группа: Участник
Сообщений: 12
Регистрация: 30-10-11
Пользователь №: 68 056



Глупый вопрос задал, извиняюсь... А на вывод как настроить, не подскажете? Или они уже настроены, т.к. 0 стоит?

Сообщение отредактировал Jead - Jan 11 2012, 12:18
Go to the top of the page
 
+Quote Post
Палыч
сообщение Jan 11 2012, 15:30
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(Jead @ Jan 11 2012, 16:17) *
Глупый вопрос задал, извиняюсь... А на вывод как настроить, не подскажете? Или они уже настроены, т.к. 0 стоит?

1. При выдачи нолика в регистр порта открывается ключ, соединяющий землю с ногой порта, - на выходе имеем низкий потенциал. При выдаче единицы, ключ закрыт, через Pull-Up резистор на ноге порта появляется высокий потенциал.
2. При чтении регистра порта читается фактическое состояние уровня сигнала на ноге порта.
3. П.2 действителен, и неважно откуда взялся низкий уровень на ноге порта: через ключ или "навалился" извне. Что, собственно, позволяет использовать порт для ввода выдав в регистр порта единицу!
Прикрепленное изображение

P.S. Т.е. при использовании порта для ввода: выдаём единицу (закрываем ключ) и контролируем (читаем) состояние - ноль может появиться, если низкий уровень будет подан на ногу извне!
Go to the top of the page
 
+Quote Post
Jead
сообщение Jan 13 2012, 09:38
Сообщение #9





Группа: Участник
Сообщений: 12
Регистрация: 30-10-11
Пользователь №: 68 056



Все равно что-то возмущается... на этот раз на SJMP BEGIN.. Illegal mnemonic. Когда в машинные коды переводит... До этого вроде не было, быть может программа глючит просто?

Полный код
Код
SJMP BEGIN
ORG 0000h
BEGIN:            ORL               P1,#00000111b
          MOV                  P1,#00001000b
M4:
                  MOV                     A,#00000000b
                JNB                  P1.0,M1
                  INC                   A
M1:
                  JNB                  P1.1,M2
                  INC                   A
M2:
                  JNB                  P1.2,M3
                  INC                   A
M3:
                  JZ                      M4
                  MOV                  P1,#00000000b
                  DJNZ                  A,M5
                 DJNZ                  A,M6
                MOV                  P1,#01000000b
                  SJMP                   M4
M5:
                  MOV                  P1,#00010000b
                  SJMP                   M4  
M6:
                 MOV                  P1,#00100000b
                  SJMP                   M4
END
Go to the top of the page
 
+Quote Post
Палыч
сообщение Jan 13 2012, 10:56
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(Jead @ Jan 13 2012, 13:38) *
Все равно что-то возмущается...

Уж, не знаю - что это у Вас транслятор возмущается?
Но, не вникая в то, что должна делать Ваша программа, вижу ошибки:
1. Поменять местами первые две строки.
2. Команда DJNZ (строки 18, 19) первым операндом должна иметь один из регистров R0-R7 или ячейку ОЗУ. У Вас же в этой команде - аккумулятор.


Да, вот ещё несуразица:
Код
BEGIN: ORL  P1,#00000111b
          MOV  P1,#00001000b

Первая из этих команд - безсмысленна: следующая команда "перетрёт" (сбросит в ноль) установку последних трёх бит регистра Р1
Go to the top of the page
 
+Quote Post
Jead
сообщение Jan 13 2012, 11:36
Сообщение #11





Группа: Участник
Сообщений: 12
Регистрация: 30-10-11
Пользователь №: 68 056



Менял первые 2 строки местами, все равно ругается. А по поводу несуразицы, как тогда настроить порты на ввод, чтоб потом было возможно обнулить все порты?
Go to the top of the page
 
+Quote Post
MaslovVG
сообщение Jan 13 2012, 12:08
Сообщение #12


Профессионал
*****

Группа: Свой
Сообщений: 1 210
Регистрация: 24-01-05
Из: Россия Волгодонск
Пользователь №: 2 134



Цитата(Jead @ Jan 13 2012, 15:36) *
Менял первые 2 строки местами, все равно ругается. А по поводу несуразицы, как тогда настроить порты на ввод, чтоб потом было возможно обнулить все порты?

А раве BEGIN не является зарезервировим словом и может использоватся в качестве имени метки?
Go to the top of the page
 
+Quote Post
Палыч
сообщение Jan 13 2012, 12:56
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(Jead @ Jan 13 2012, 15:36) *
Менял первые 2 строки местами, все равно ругается.
Может быть, Вы что-то изменили в опциях проекта? Попробуйте создать проект заново...

Цитата(Jead @ Jan 13 2012, 15:36) *
А по поводу несуразицы, как тогда настроить порты на ввод, чтоб потом было возможно обнулить все порты?
Не понятно: что вы хотите сделать? Зачем обнулять все порты коль они настроены на ввод? Попробуйте сформулировать вопрос по-другому.

Цитата(MaslovVG @ Jan 13 2012, 16:08) *
А раве BEGIN не является зарезервировим словом и может использоватся в качестве имени метки?
Это у ТС нужно узнать: каким компилятором он пользуется? У Keil такого зарезервированного слова нет.
Go to the top of the page
 
+Quote Post
Jead
сообщение Jan 13 2012, 13:19
Сообщение #14





Группа: Участник
Сообщений: 12
Регистрация: 30-10-11
Пользователь №: 68 056



Ну не совсем обнулять, а скажем послать в него определенную комбинацию, н-р: MOV P1,#01000000b.
Go to the top of the page
 
+Quote Post
MaslovVG
сообщение Jan 13 2012, 13:47
Сообщение #15


Профессионал
*****

Группа: Свой
Сообщений: 1 210
Регистрация: 24-01-05
Из: Россия Волгодонск
Пользователь №: 2 134



Цитата(Jead @ Jan 13 2012, 17:19) *
Ну не совсем обнулять, а скажем послать в него определенную комбинацию, н-р: MOV P1,#01000000b.

Если вы некоторые биты порта предназначили только для ввода.то посылать в них (бит) 0 нельзя никакими командами.
Go to the top of the page
 
+Quote Post
Палыч
сообщение Jan 13 2012, 15:01
Сообщение #16


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(Jead @ Jan 13 2012, 17:19) *
Ну не совсем обнулять, а скажем послать в него определенную комбинацию, н-р: MOV P1,#01000000b.

Наверное, Вы хотели спросить следующее:
Допустим, что младшие 3 бита порта Р1 предназначены для ввода, а старшие 5 бит - для вывода. Как, настроив младшие биты порта Р1 на ввод, изменять значение битов порта Р1 на вывод, при этом не затрагивая биты этого порта, настроенные на ввод?

Ответ:
1. Допустим, что в начале работы программы значения выходных пинов (битов) порта Р1 - низкий уровень (ноль). Настройка (инициализация) порта Р1 осуществляется следующим образом:
MOV P1, #00000111b
В случае, если некоторые пины (биты) порта Р1, предназначенные для вывода, в начале работы программы должны иметь высокий уровень (единицу), то инициализация будет выглядеть так (например, самый старший разряд - высокий.единица):
MOV P1, #10000111b
2. Например, теперь необходимо сигнал на третьем (считаем с нуля!) пине (бите) сделать сигнал высокого уровня. Делается это так:
ORL P1, #00001000b
или так
SETB P1.3
3. Теперь, например, на этом (третьем) пине (бите) нужен низкий уровень:
ANL P1,#NOT 00001000b
или
CLR P1.3
4. Если нужно установить сразу два бита (например, четвертый и пятый):
ORL P1,#00110000b
сбросить в ноль эти два бита
ANL P1,#NOT 00110000b
5. Если нужно изменить значение одного бита (например, третьего) на противоположное:
CPL P1.3

Ну, вот, как-то таким образом.
Go to the top of the page
 
+Quote Post
Harbinger
сообщение Jan 13 2012, 15:41
Сообщение #17


старший лаборант
******

Группа: Свой
Сообщений: 2 702
Регистрация: 30-09-05
Из: ЮЗЖД
Пользователь №: 9 097



Цитата(Палыч @ Jan 13 2012, 12:56) *
2. Команда DJNZ (строки 18, 19) первым операндом должна иметь один из регистров R0-R7 или ячейку ОЗУ. У Вас же в этой команде - аккумулятор.

С SFR, в т.ч. с аккумулятором тоже работает, но не в таком написании, а DJNZ ACC, label.
Раньше работал с древним досовским пакетом от 2500 A.D.Software, там фокус с DJNZ A, label проходил. А TASM и кейловский ассемблер ругаются.


--------------------
Китайская комплектация - европейское качество! ;)
Go to the top of the page
 
+Quote Post
Jead
сообщение Jan 18 2012, 19:59
Сообщение #18





Группа: Участник
Сообщений: 12
Регистрация: 30-10-11
Пользователь №: 68 056



Палыч, сделал все как Вы подсказали, вышло вот так

Код
SJMP BEGIN
ORG 0000h
BEGIN:            MOV               P1,#01111111b
          ORL                  P1,#00001000b
M4:
                  MOV                     A,#00000000b
                JNB                  P1.0,M1
                  INC                   A
M1:
                  JNB                  P1.1,M2
                  INC                   A
M2:
                  JNB                  P1.2,M3
                  INC                   A
M3:
                  JZ                      M4
                  CLR                  P1.3
                  DJNZ                  A,M5
                 DJNZ                  A,M6
                SETB                  P1.6
                  SJMP                   M4
M5:
                  SETB                 P1.4
                  SJMP                   M4  
M6:
                 SETB                  P1.5
                  SJMP                   M4
END

Но вот только я не совсем понимаю, если мы делаем MOV P1, #00000111b(настраиваем порты на ввод), то как нам потом снимать значения, т.е. есть ли там единица или нет? Грубо говоря, биты с нулевого по второй у нас подключены к кнопкам, с третьего по шестой - к светодиодам. И надо считывыя с Р.0, Р.1 и Р.2 результат (есть ли единица там или нет, т.е. нажата ли кнопка) определить какое количество кнопок нажато и зажечь определенный светодиод. Но когда мы настраиваем порты на ввод и вывод компилятор видит во всех этих настроенных битах единицы и, соответственно, не реагирует.
Go to the top of the page
 
+Quote Post
Палыч
сообщение Jan 18 2012, 20:27
Сообщение #19


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(Jead @ Jan 18 2012, 23:59) *
Но вот только я не совсем понимаю, если мы делаем MOV P1, #00000111b(настраиваем порты на ввод), то как нам потом снимать значения, т.е. есть ли там единица или нет?

При обращении к порту возможны три типа команд:
1. запись (пример: MOV P1,#0)
2. чтение (MOV А,P1 или JNB P1.0,метка)
3. чтение-модификация-запись (ANL P1,#NOT 00001000b)

Команда первого типа (запись) помещает некое значение в ячейку памяти (триггер), состояние которого определяет состояние ключа, соединяющего пин с землёй.

Команда второго типа (чтение) помещает значение в соответствии с уровнем сигнала на пине порта в "получатель", заданный в команде. При этом не важно, что выдавалось ранее в порт и зафиксированно состоянием триггера, важен только уровень на пине (как уже объяснял выше: высокий уровень, заданный выданной в порт единицей может "пересилить" низкий уровень "навалившийся" извне).

А, вот, для команд третьего типа, как раз, не важен уровень сигнала на пине порта, а принимается в расчет состояние того самого триггера, о котором говорилось выше.

Так вот: для настройки на ввод и установки состояния выводов используются команды первого и третьего типа, а для ввода - команды второго типа.
Go to the top of the page
 
+Quote Post
Jead
сообщение Jan 18 2012, 20:51
Сообщение #20





Группа: Участник
Сообщений: 12
Регистрация: 30-10-11
Пользователь №: 68 056



Спасибо большое за информацию, но я видать совсем дурак =(



В компиляторе мне для проверки программы мне надо подать единицы на первые три пина порта Р.1 (в рамке), но там УЖЕ единицы... =(
Go to the top of the page
 
+Quote Post
Палыч
сообщение Jan 18 2012, 21:17
Сообщение #21


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(Jead @ Jan 19 2012, 00:51) *
но там УЖЕ единицы... =(

Если говорить "грубо", то: регистры параллельных портов имеют два значения (или можно представить - два регистра под одним адресом и именем): один - для ввода, другой - для вывода. Их значения одинаковы, если извне микроконтроллера никто не вмешивается в работу порта. Но могут быть и разные, разница может быть только одна: там где у регистра на вывод единица, у регистра на ввод может появиться ноль, если извне кто-то вмешался в работу порта и "пересилил" высокий уровень на пине низким уровнем.

Вы пытаетесь изучать работу МК с помощью симулятора... Ваш симулятор мне не знаком. Но, насколько я заметил на рисунке: у портов так же два значения (вероятно, одно - для ввода, другое - для вывода; Вы их обвели красным). Вероятно, одно из них (то, что "для ввода") можно произвольно изменять "руками", имитируя нажатие кнопки...
Go to the top of the page
 
+Quote Post
Палыч
сообщение Jan 19 2012, 06:23
Сообщение #22


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Чтобы Вам втолковать работу параллельных портов в классическом МК51, мне в голову пришла такая аналогия:

Представьте, что в некоем доме (это - МК) есть входная дверь (это - пин порта). Два человека, один изнутри, а второй - снаружи, пытаются её открыть/закрыть. Состояние двери будет определяться - кто же из двух человек сильнее. Так вот: человек внутри с большой силой может держать дверь закрытой (МК "держать" низкий уровень), а открывать дверь - у него силёнок не хватает пересилить того человека, что снаружи.
В МК51 настройка порта "на ввод" - некая абстракция: порт всегда работает на вывод (пытается открыть/закрыть "дверь"), но всегда можно узнать истинное значение уровня сигнала на пине (состояние "двери"). МК с силой "держит" низкий уровень (удерживает "дверь" закрытой), а высокий уровень (открыть "дверь") - силенок не хватает (вернее - маловато: может это сделать, если ему кто-то сильный не препятствует). Если мы желаем знать "намерения" человека снаружи (определить уровень сигнала на выходе какой-либо микросхемы, подключив его к пину порта - "ввести" сигнал), то прикладывать силу к двери не нужно, и тогда дверь перейдёт в состояние соответствующее намерениям человека снаружи.
Как было сказано выше: состояние порта МК, когда "сила" не прикладывается - высокий уровень сигнала на пине (единица). Если к пину подключена линия на которой низкий уровень, то при достаточной мощности внешнего сигнала уровень на пине "опустится" и это можно зафиксировать чтением состояния порта. Именно поэтому, "настраивая" порт на ввод выдают в него единицу.
Если оставить на пине низкий уровень, который МК удерживает "сильно" (см. выше), то при мощном сигнале высокого уровне извне произайдёт "разрушение" выходных цепей пина (в аналогии выше - оба человека очень сильно тянут дверь каждый в свою сторону: ручки у двери оторвутся biggrin.gif). Это - ещё один веский аргумент установки порта в единицу при подключении к пину внешнего сигнала.

Вот - как-то так. Как ещё Вам рассказать про работу параллельного порта МК уж и не знаю...
Go to the top of the page
 
+Quote Post
Harbinger
сообщение Jan 19 2012, 08:49
Сообщение #23


старший лаборант
******

Группа: Свой
Сообщений: 2 702
Регистрация: 30-09-05
Из: ЮЗЖД
Пользователь №: 9 097



Цитата(Палыч @ Jan 19 2012, 08:23) *
Представьте, что в некоем доме (это - МК) есть входная дверь (это - пин порта).
...
sm.gif
Как вариант: единица - закрытая дверь, удерживается в этом состоянии пружиной. Потянули за ручку - дверь открылась (ноль) - но пружина-то никуда не делась, если ручку отпустить - дверь захлопнется (снова единица).


--------------------
Китайская комплектация - европейское качество! ;)
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 20th July 2025 - 01:07
Рейтинг@Mail.ru


Страница сгенерированна за 0.01622 секунд с 7
ELECTRONIX ©2004-2016