|
Программа для микроконтроллера, Как работает код |
|
|
|
Apr 14 2010, 14:53
|
Местный
  
Группа: Свой
Сообщений: 323
Регистрация: 25-08-09
Пользователь №: 52 032

|
Здравствуйте. Мне нужно запрограммировать МК C8051F020. В ассемблере я не силен, а с Си доводилось работать, поэтому решил использовать последний. Скачал книгу: Магда Ю.С. "Микроконтроллеры серии 8051: практический подход". По ней и планирую программировать. В процессе изучения возник вопрос касательно применения ассемблера в коде Си (в книге говорится может понадобится). Код: Цитата #pragma asm SETB ET0; SETB EA; #pragma endasm; SETB EA - запрет на любые прерывания, а что такое SETB ET0.
|
|
|
|
|
 |
Ответов
(1 - 68)
|
Apr 15 2010, 14:32
|
Местный
  
Группа: Свой
Сообщений: 323
Регистрация: 25-08-09
Пользователь №: 52 032

|
Выполнил программу по учебнику, а она работает не до конца. Цитата #include <stdio.h> #include <stdio.h> #include <REG52.h>
sbit Bit0 = P1^0; void INT0Isr (void) interrupt 0 using 1 {
EX0 = 0; Bit0 = ~ Bit0; printf("Interrupt 0 occured. \n"); EX0 = 1; }
void main (void)
{ SCON = 0x50; TH1 = 0xFD; TMOD |= 0x20; TR1 = 1; TI = 1;
IT0 = 1; EX0 = 1; EA = 1; while (1);
} При выполнении в пошаговом режиме не инвестируется бит порта Р1 и в порт не выдается значение.
Сообщение отредактировал Aleksandr_KPI - Apr 15 2010, 14:33
Эскизы прикрепленных изображений
|
|
|
|
|
Apr 16 2010, 07:18
|
Местный
  
Группа: Свой
Сообщений: 323
Регистрация: 25-08-09
Пользователь №: 52 032

|
Цитата Чем Вы там пользуетесь для отладки Вашей программы? Использую среду Keil uVision. Цитата Можно ли поставить точку останова в процедуру обработки прерывания от таймера и запустить программу в автомате? Остановится ли программа на точке останова? Честно сказать, я не знаю как это сделать. Программу я запускал и в пошаговом и в непрерывном режимах, результат отрицательный.
|
|
|
|
|
Apr 16 2010, 07:28
|
Местный
  
Группа: Свой
Сообщений: 323
Регистрация: 25-08-09
Пользователь №: 52 032

|
Цитата Бросайте хренью заниматься, возьмите реальную железку. Так, а на реальной железке писать программу методом проб и ошибок, ее ведь откомпилировать нужно.
|
|
|
|
|
Apr 16 2010, 07:35
|
Местный
  
Группа: Свой
Сообщений: 323
Регистрация: 25-08-09
Пользователь №: 52 032

|
Цитата Бросайте хренью заниматься, возьмите реальную железку. Цитата естественно, а до этого ещё и написать. Тогда я не понял сути. Что Вы имеете ввиду?
|
|
|
|
|
Apr 16 2010, 07:47
|

Беспросветный оптимист
     
Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646

|
Цитата(Aleksandr_KPI @ Apr 16 2010, 11:50)  Тогда я не понял сути. Что Вы имеете ввиду? Я имею в виду, что нужно поставить задачу и попытаться её решить. Хотя бы с/д моргнуть. А лучше чего-нибудь посущественней. Игры с симулятором с примерами из учебника мало что дают в плане обучения. Вот к примеру, что делает ваша программа? Инициализировала порт и тупо зависла в бесконечном цикле. А вы чего-то ждёте. Ну сделайте хотя бы софтовую задержку, тогда и в симуляторе увидите результат.
--------------------
Программирование делится на системное и бессистемное. ©Моё :) — а для кого-то БГ — это Bill Gilbert =)
|
|
|
|
|
Apr 16 2010, 08:09
|
Местный
  
Группа: Свой
Сообщений: 323
Регистрация: 25-08-09
Пользователь №: 52 032

|
Цитата Я имею в виду, что нужно поставить задачу и попытаться её решить. Хотя бы с/д моргнуть. А лучше чего-нибудь посущественней. Игры с симулятором с примерами из учебника мало что дают в плане обучения. Задача есть, он для этого нужны азы. Цитата Вот к примеру, что делает ваша программа? Инициализировала порт и тупо зависла в бесконечном цикле. А вы чего-то ждёте. Из книги: Цитата В этой программе используется программа обработчик внешнего прерывания 0 (INT0). Каждый раз при возникновении прерывания в последовательный порт выводится соответствующее сообщение и инвертируется бит 0 порта P1. Цикл я убрал и выяснил, что программа не выполняет прерывание (откомпилировал пошагово). Выходит код не правильный в примере?
|
|
|
|
|
Apr 16 2010, 09:34
|
Местный
  
Группа: Свой
Сообщений: 323
Регистрация: 25-08-09
Пользователь №: 52 032

|
По задумке автора прерывание вызывается программно. Цитата IT0 = 1; EX0 = 1; EA = 1;
|
|
|
|
|
Apr 17 2010, 10:38
|

Местный
  
Группа: Участник
Сообщений: 217
Регистрация: 13-08-07
Из: Санкт-Петербург
Пользователь №: 29 745

|
watchdog отключите: Код PCA0MD &= ~0x40;
--------------------
|
|
|
|
|
Apr 19 2010, 09:39
|
Местный
  
Группа: Свой
Сообщений: 323
Регистрация: 25-08-09
Пользователь №: 52 032

|
Выдает ошибку. Код error C202: 'PCA0MD': undefined identifier
|
|
|
|
|
Apr 19 2010, 10:46
|

Местный
  
Группа: Участник
Сообщений: 217
Регистрация: 13-08-07
Из: Санкт-Петербург
Пользователь №: 29 745

|
Код WDTCN = 0xDE; // Disable watchdog timer WDTCN = 0xAD; вот так. соррри.
--------------------
|
|
|
|
|
Apr 19 2010, 19:01
|
Местный
  
Группа: Свой
Сообщений: 323
Регистрация: 25-08-09
Пользователь №: 52 032

|
Странно, пишет: Код error C202: 'WDTCN': undefined identifier error C202: 'WDTCN': undefined identifier
Сообщение отредактировал Aleksandr_KPI - Apr 19 2010, 19:01
|
|
|
|
|
Apr 20 2010, 05:57
|

Местный
  
Группа: Участник
Сообщений: 217
Регистрация: 13-08-07
Из: Санкт-Петербург
Пользователь №: 29 745

|
Код #include <C8051F020.h>
--------------------
|
|
|
|
|
Apr 20 2010, 08:14
|
Местный
  
Группа: Свой
Сообщений: 323
Регистрация: 25-08-09
Пользователь №: 52 032

|
Сначала выдавало ошибку: Код Error C231 Redefinition Я исправил, запустил, а результат тот же: прерывание отсутствует.
Сообщение отредактировал Aleksandr_KPI - Apr 20 2010, 08:15
|
|
|
|
|
Apr 20 2010, 12:31
|
Местный
  
Группа: Свой
Сообщений: 323
Регистрация: 25-08-09
Пользователь №: 52 032

|
Разобрался, MrYuran был прав. Цитата Ну вот у вас там окошечки с регистрами периферии. Попробуйте подёргать за ноги, соответствующие INT0 - а вдруг сработает? Я прерывание не на том порту вызывал, книга о одном микроконтроллере, а я другой в программе указал. Но всетаки один момент не работает, в последовательный порт после инвертирования битов не выдается сообщение. Код printf("Interrupt 0 occured. \n");
|
|
|
|
|
Apr 20 2010, 13:06
|

Беспросветный оптимист
     
Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646

|
Цитата(Aleksandr_KPI @ Apr 20 2010, 16:46)  Но всетаки один момент не работает, в последовательный порт после инвертирования битов не выдается сообщение. Код printf("Interrupt 0 occured. \n"); А это надо ручками putchar() написать, скорее всего. Или заполнить содержанием готовую обёртку. Но это неправильный подход. printf() выдаёт строку посимвольно, и для каждого символа вызывает putchar(). В случае с УАРТом это будет неоправданные потери времени. Лучше использовать sprintf(), который формирует строку в буфере, а потом буфер отправлять в УАРТ.
--------------------
Программирование делится на системное и бессистемное. ©Моё :) — а для кого-то БГ — это Bill Gilbert =)
|
|
|
|
|
Apr 20 2010, 14:34
|
Местный
  
Группа: Свой
Сообщений: 323
Регистрация: 25-08-09
Пользователь №: 52 032

|
Цитата Но это неправильный подход. printf() выдаёт строку посимвольно, и для каждого символа вызывает putchar(). Спасибо за рекомендацию. С проблемой я разобрался. Версия keil uvision с глюками. Она выводит в последовательный порт данные в белом цвете и 732 шрифтом  . Не знаете где можно скачать нормальную версию?
|
|
|
|
|
Apr 21 2010, 08:00
|
Местный
  
Группа: Свой
Сообщений: 323
Регистрация: 25-08-09
Пользователь №: 52 032

|
Подскажите как правильно понимать работу регистра SBUF. Есть код: Код #include <stdio.h> #include <string.h> #include <REG52.H>
void fputchar (unsigned char c1) { SBUF = c1; while (!TI); TI = 0; }
void main(void) { idata char src[] = "Output string"; idata char *psrc = src; int len, cnt;
SCON = 0x50; TH1 = 0xFD; TMOD |= 0x20; TR1 = 1; TI = 0; len = strlen(src);
for (cnt = 0; cnt < len; cnt++) { fputchar(*psrc); psrc++; }
while(1); Когда запускаю в пошаговом режиме в последовательный порт не выводит ничего при достижении команды: Код SBUF = c1; Нажимаю RUN выводит Output string.
|
|
|
|
|
Apr 21 2010, 08:10
|

Беспросветный оптимист
     
Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646

|
Цитата(Aleksandr_KPI @ Apr 21 2010, 12:15)  Когда запускаю в пошаговом режиме в последовательный порт не выводит ничего при достижении команды: Код SBUF = c1; Нажимаю RUN выводит Output string. Наверно, нужно много раз понажимать. Скорость вывода отличается от тактовой частоты процессора в сотни раз
--------------------
Программирование делится на системное и бессистемное. ©Моё :) — а для кого-то БГ — это Bill Gilbert =)
|
|
|
|
|
Apr 21 2010, 11:43
|
Местный
  
Группа: Свой
Сообщений: 323
Регистрация: 25-08-09
Пользователь №: 52 032

|
Спасибо понял. Дошел до работы с вставками ассемблерного кода в код Си. При сборке выдает ошибку: Цитата linking... *** WARNING L1: UNRESOLVED EXTERNAL SYMBOL SYMBOL: ?C_STARTUP MODULE: Prog2.obj (PROG2) Program Size: data=18.0 xdata=0 code=61 Читал на официальном сайте о проблеме, но как исправить не понял.
|
|
|
|
|
Apr 23 2010, 08:02
|
Местный
  
Группа: Свой
Сообщений: 323
Регистрация: 25-08-09
Пользователь №: 52 032

|
Вот нашел на одном форуме: Цитата Короче, не используйте #pragma asm в кейле. Я не использую. Оно как-то плохо на него реагирует. Либо перепишите процедуру на си либо создаёте отдельный .asm файл и должным образом его оформляете со всеми директивами типа SEGMENT, extrn global и т.п. Так что использовать не удастся. Подскажите почему при выполнении следующего кода: Код NAME PROCS T2CON EQU 0C8h RCAP2H EQU 0CBh RCAP2L EQU 0CAh CSEG AT 0 USING 0 JMP start SerINT: ORG 23h JBC RI, RCV RETI RCV: MOV P1, SBUF RETI ;—————————————— start: MOV P1, #0h MOV SCON, #50h CLR T2CON.0 CLR T2CON.1 SETB T2CON.4 SETB T2CON.5 MOV RCAP2H, #0FFh MOV RCAP2L, #0B2h SETB T2CON.2 SETB ES SETB EA SETB TI SJMP $ В порте Р1 всегда установлены в единицу 4 и 5 биты.
Эскизы прикрепленных изображений
|
|
|
|
|
Apr 23 2010, 09:14
|

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

|
Цитата(Aleksandr_KPI @ Apr 23 2010, 11:17)  Подскажите почему при выполнении следующего кода... В порте Р1 всегда установлены в единицу 4 и 5 биты. Если посмотреть на Ваш код, то легко увидеть, что регистр Р1 изменяется в двух местах Вашей программы: 1) в main заносится ноль 2) в прерывании заносится содержимое SBUF. Очевидно, что биты Р1.4 и Р1.5 и устанавливаются командой в прерывании (копируются из SBUF), а в SBUF эти биты установлены. Почему в SBUF эти биты установлены? Издалека сказать трудно... Но с этим SBUF - некоторая беда (разработчики МК немножко намудрили). Дело в том, что в МК два регистра под одним адресом и именем SBUF - один для принятых данных (приёмника - можно только читать), другой - для передаваемых данных (передатчика - можно только записывать в него). Помниться (а, может быть я - не прав), что в окошке Keil "Serial channel" изменяется как раз второй (для передачи) регистр SBUF. Если Вы отлаживая свою программу изменяли значение в этом окне, то в регистре SBUF, куда должны помещатся принятые данные (SBUF приёмника) - изменений не происходит. А копируете Вы в Р1 как раз SBUF приёмника. Чтобы изменить SBUF приёмника, нужно что-нибуть набрать в окне Keil "Serial Window". Ещё мне кажется, что Вы настроили неверно UART. В регистр SCON Вы заносите 50h: один бит -разрешает работу приёмника; второй - устанавливает режим работы. Имхо, Вы установили режим работы 2. Скорость работы UART в режиме 2 задаётся только тактовой частотой МК и не регулируется. Так и было задумано? Зачем тогда настройка таймера 2? PS. C настройками UART - всё верно: устанавливается режим 1. Это - я за давностью использования МК51 запамятовал...
|
|
|
|
|
Apr 23 2010, 10:49
|
Местный
  
Группа: Свой
Сообщений: 323
Регистрация: 25-08-09
Пользователь №: 52 032

|
Цитата Помниться (а, может быть я - не прав), что в окошке Keil "Serial channel" изменяется как раз второй (для передачи) регистр Окно "Serial channel" я открыл только для того что бы следить за изменением флагов прерываний передатчика и приемника последовательного порта и за ходом выполнения программы. Регистр SBUF при исполнении программы никак не изменяется (там постоянно висят нули) даже когда я захожу на вкладку последовательного порта и ввожу число, оно в нем не появляется. Цитата Если Вы отлаживая свою программу изменяли значение в этом окне, то в регистре SBUF, куда должны помещатся принятые данные (SBUF приёмника) - изменений не происходит. А копируете Вы в Р1 как раз SBUF приёмника. Чтобы изменить SBUF приёмника, нужно что-нибуть набрать в окне Keil "Serial Window". В этом окне я ничего не менял. В принципе то программа работает. Вводимое мной число (от 0 до 9) в вкладке последовательного порта, четко отображается с помощью первых 4 разрядов порта Р1. Вот только при этом загадочно "горят" 4 и 5 биты.
|
|
|
|
|
Apr 29 2010, 11:52
|
Местный
  
Группа: Свой
Сообщений: 323
Регистрация: 25-08-09
Пользователь №: 52 032

|
Подскажите почему программа выдает ошибку error A9: SYNTAX ERROR. Ругается на все строки, кроме первой. Программа для микроконтроллера AT89S8252. Часть кода: Код BYTE_ERR_IN EQU 02AH ERR_56M REG BYTE_ERR_IN.0 ERR_G1_4 REG BYTE_ERR_IN.1 ERR_SNPR56M REG BYTE_ERR_IN.2 SNPR_GHM REG BYTE_ERR_IN.3 ERR_SNPRK56M REG BYTE_ERR_IN.4 ERR_SNPRB56M REG BYTE_ERR_IN.5 ERR_OG REG BYTE_ERR_IN.6 ERR_NLCHM REG BYTE_ERR_IN.7
|
|
|
|
|
Jun 7 2010, 11:07
|
Местный
  
Группа: Свой
Сообщений: 323
Регистрация: 25-08-09
Пользователь №: 52 032

|
Подскажите, как код передает данные во внешнюю память: Код ERR_EXT_ADDR_OUT EQU 001H ...............
BYTE_ERR_OUT EQU 02CH KVITANCIA8 REG BYTE_ERR_OUT.1 LED_IND REG BYTE_ERR_OUT.2 WR_SETKA REG BYTE_ERR_OUT.6 WR_DDS REG BYTE_ERR_OUT.7
............... MOV R0,#ERR_EXT_ADDR_OUT MOV A,BYTE_ERR_OUT MOVX @R0,A Программа написана для AT89S8252. Сам код в принципе понятен, неясно как и где определяется что выдавать данные нужно через порт P0 к которому подключена 8 разрядная шина для обмена с внешней памятю. Прикрепил полный код. Извините что-то файл не прикрепился.
Сообщение отредактировал rezident - Jun 7 2010, 17:30
|
|
|
|
|
Jun 7 2010, 20:39
|

неотягощённый злом
     
Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643

|
Цитата(Aleksandr_KPI @ Jun 7 2010, 15:07)  Подскажите, как код передает данные во внешнюю память: Код MOV R0,#ERR_EXT_ADDR_OUT MOV A,BYTE_ERR_OUT MOVX @R0,A MOVX через косвенную адресацию поместит содержимое аккумулятора в ячейку памяти по адресу, хранящемуся в регистре R0. Поскольку этот регистр восьмибитный то и диапазон адресов невелик 0-255. При использовании MOVX интерфейс внешней памяти контроллера будет самостоятельно вырабатывать управляющие сигналы WR RD ALE в соответствии с даташитом на контроллер. Для понимания этого процесса советую почитать доку на Ваш контроллер и что-нибудь об параллельном интерфейсе 8085.
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Jun 8 2010, 10:55
|
Местный
  
Группа: Свой
Сообщений: 323
Регистрация: 25-08-09
Пользователь №: 52 032

|
Цитата MOVX через косвенную адресацию поместит содержимое аккумулятора в ячейку памяти по адресу, хранящемуся в регистре R0. Это я понимаю. Почему передача данных ведется через порт P0, а не скажем через порт P1 или P2?
|
|
|
|
|
Jun 10 2010, 13:38
|
Местный
  
Группа: Свой
Сообщений: 323
Регистрация: 25-08-09
Пользователь №: 52 032

|
Цитата Потому, что разработчики МК51 так когда-то спроектировали работу МК с внешней памятью: адрес - на портах Р0 и Р2, данные - на Р0 У меня в данном примере данные и адрес передаются по одному порту P0. А как быть в другом случае, например мне нужно написать программу для передачи данных из МК в ПЛИС и наоборот. Имеется два порта Р6 и Р7 микроконтроллера C8051F020. По седьмому порту передаются данные по шестому адрес. Для передачи данных в ПЛИС тоже используется команда MOVX или можно просто передавать данные побайтно в порты? Я не совсем понял выражение : Цитата адрес - на портах Р0 и Р2 . Как использовать команду MOVX если адрес и данные на разных портах?
|
|
|
|
|
Jun 11 2010, 09:57
|

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

|
Цитата(Aleksandr_KPI @ Jun 10 2010, 17:38)  Как использовать команду MOVX если адрес и данные на разных портах? Вы используете C8051F020. Это какой-то клон 8051 (к сожалению, с C8051F020 я не знаком). В классическом 8051 по команде MOVX МК аппаратно формирует некую, описанную в DS, последовательность сигналов адреса (на Р0, Р2), данных (на Р0), сигналов ALE, RD, WR. Скорее всего (уточните в DS) и применённый Вами МК так (и только так!) выполняет команду MOVX. Что делать, если нужно использовать другие порты? В этом случае сигналы прийдется формировать программным способом (с помощью команд, отличных от MOVX, выводить на нужные порты необходимые сигналы в нужной последовательности и с соблюдением необходимых временных интервалов).
|
|
|
|
|
Jun 14 2010, 12:09
|
Местный
  
Группа: Свой
Сообщений: 323
Регистрация: 25-08-09
Пользователь №: 52 032

|
1. Подскажите почему код выполняет одинаковую временную задержку на частотах микроконтроллера 11 и 22 МГц. Моделирую в Keil uVision. Код DELL_1MS: MOV TMP_CNT,#250 DJNZ TMP_CNT,$ MOV TMP_CNT,#250 DJNZ TMP_CNT,$ RET ORG 8000 JMP START_PROG 2. Эта часть кода, когда нибуть выполняется? Перед ней ведь стоит команда RET. Код ORG 8000 JMP START_PROG
Сообщение отредактировал Aleksandr_KPI - Jun 14 2010, 12:10
|
|
|
|
|
Jun 17 2010, 09:30
|
Местный
  
Группа: Свой
Сообщений: 323
Регистрация: 25-08-09
Пользователь №: 52 032

|
Спасибо все нашел, только в случае с keil uVision нужно еще перед дерективой $INCLUDE прописать $nomod51, которая отключит регистры объявленные по умолчанию. Если этого не сделать будет конфликт с вновь объявляемыми. 1.Подскажите, в чем разница между режимами Open-Drain и Push-Pull. Читал http://www.proz.com/kudoz/english_to_russi...ll.html#1000368, мало что понятно, а больше не нашел. Я так понял это два варианта настройки портов МК в выходном режиме. 2. Прочитал такую вещь Цитата Обычные команды чтения порта (например, MOV A,P2) реализуют ввод информации только с внешних выводов порта. В соответствующие регистры-фиксаторы при этом предварительно должны быть записаны "1", чем обеспечивается настройка линий порта на ввод. Где находится регистры-фиксаторы порта и как к ним обратится. Нужно смотреть в сторону регистра специальных функций или я не прав?
Сообщение отредактировал Aleksandr_KPI - Jun 17 2010, 09:31
|
|
|
|
|
Jun 17 2010, 11:22
|

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

|
Цитата(Aleksandr_KPI @ Jun 17 2010, 13:30)  нужно еще перед дерективой $INCLUDE прописать $nomod51 Или в опциях проекта (Options -> A51) убрать галку "Define 8051 SFR Names" Ваши вопросы, как я понял, касаются ввода-вывода в/из параллельные порты МК51? "На пальцах" это, примерно, так: Вывод. Выводимое значение помещается в регистр. Ноль в соответствующем разряде открывает ключ, соединяющий "ногу" МК с "землёй": на ноге - низкий уровень. Единица - запирает ключ ("отрывает" от земли), но нога соединена (внутри МК, конечно) через резистор с большим сопротивлением (pullup, подтягивающий резистор) к источнику питания, который в отсутствии "притягивания" извне ноги к земле и большого сопротивления внешней нагрузки на ноге, создаёт на ноге высокий уровень. Ввод. Информация "снимается" непосредственно с ноги МК. Нолик читается если мы вывели на ногу низкий уровень (выдали 0; открыли ключ, соединяющий ногу с землёй) или низкий уровень "навалился" на ногу с выхода другой м/с, соединенном с ногой МК. В противном случае - читается единица (т.е. ноль как-бы "приоритетнее"). Поэтому в МК51 для чтения с портов (Р0, Р1 и т.д.) нужно выдать в порт единицы (или не выводить ничего - после сброса там и так единицы).
|
|
|
|
|
Jun 17 2010, 11:50
|
Местный
  
Группа: Свой
Сообщений: 323
Регистрация: 25-08-09
Пользователь №: 52 032

|
Цитата Или в опциях проекта (Options -> A51) убрать галку "Define 8051 SFR Names" Тоже верно  . В принципе что касается ввода-вывода понятно, а как быть с Open-Drain и Push-Pull. В даташите на контролер написано Цитата The output mode of port pin can be configured as either Open-Drain or Push-Pull; Существует регистр к примеру P1MDOUT для порта Р1, который настраивает его в режим Open-Drain или Push-Pull, а в чем разница между ними?
|
|
|
|
|
Jun 18 2010, 11:01
|
Местный
  
Группа: Свой
Сообщений: 323
Регистрация: 25-08-09
Пользователь №: 52 032

|
Цитата В Push-Pull: два ключа - один соединяет ногу с землей, другой - с питанием; открыт всегда один из них в зависимости от выданного значения. Не совсем понял разницу, зачем вводить два ключа,что это дает?
|
|
|
|
|
Jul 23 2010, 10:43
|
Местный
  
Группа: Свой
Сообщений: 323
Регистрация: 25-08-09
Пользователь №: 52 032

|
Разбираю работу примера программы из пакета Silicon Laboratories IDE. Наткнулся на такой отрывок кода: Код ; Set P1.6 (LED) as digital output in push-pull mode. orl P1MDIN, #40h orl P1MDOUT,#40h Команда orl P1MDOUT,#40h настраивает порт в режим выхода, а зачем его настраивают на вход: команда orl P1MDIN, #40h. Весь код: Код $NOMOD51 $include (c8051f020.inc) ; Include register definition file.
GREEN_LED equ P1.6 ; Port I/O pin connected to sound generator.
cseg AT 0 ljmp Main ; Locate a jump to the start of code at ; the reset vector.
Blink segment CODE
rseg Blink ; Switch to this code segment. using 0 ; Specify register bank for the following ; program code.
Main: ; Disable the WDT. (IRQs not enabled at this point.) ; If interrupts were enabled, we would need to explicitly disable ; them so that the 2nd move to WDTCN occurs no more than four clock ; cycles after the first move to WDTCN.
mov WDTCN, #0DEh mov WDTCN, #0ADh
; Enable the Port I/O Crossbar mov XBR2, #40h
; Set P1.6 (LED) as digital output in push-pull mode. orl P1MDIN, #40h orl P1MDOUT,#40h
; Initialize LED to OFF clr GREEN_LED
; Simple delay loop. Loop2: mov R7, #03h Loop1: mov R6, #00h Loop0: mov R5, #00h djnz R5, $ djnz R6, Loop0 djnz R7, Loop1 cpl GREEN_LED ; Toggle LED. jmp Loop2 END
|
|
|
|
|
Jul 26 2010, 09:41
|
Местный
  
Группа: Свой
Сообщений: 323
Регистрация: 25-08-09
Пользователь №: 52 032

|
Иными словами 6 вывод порта 1 настраивается в режим выхода Push-Pull, а второй нижний ключ подтягивается к единице через резистор Pull-up? На основе этой программы написал свою. Код $include (c8051f020.inc)
Port_P3 EQU 0B0H PROGRAM BIT Port_P3.0 DONE BIT Port_P3.1 BIPP BIT Port_P3.2 TMP_CNT equ 030H BYTE_CNT equ 031H
cseg AT 0 ljmp Main ; Locate a jump to the start of code at ; the reset vector.
Blink segment CODE rseg Blink ; Switch to this code segment. using 0 ; Specify register bank for the following ; program code. Main:
mov WDTCN, #0DEh mov WDTCN, #0ADh
; Enable the Port I/O Crossbar mov XBR2, #40h
orl P3MDIN, #07h orl P3MDOUT,#05h
CLR BIPP INIT_XILINX: JB DONE,DONE_OK CLR PROGRAM CALL DELL_10MS SETB PROGRAM CALL DELL_100MS CALL DELL_100MS CALL DELL_100MS CALL DELL_100MS JB DONE,DONE_OK MOV BYTE_CNT,#100 IXL_LOOP: CALL DELL_100MS JB DONE,DONE_OK DJNZ BYTE_CNT,IXL_LOOP JMP INIT_XILINX DONE_OK: CALL DELL_100MS RET
DELL_100MS: CALL DELL_10MS CALL DELL_10MS CALL DELL_10MS CALL DELL_10MS CALL DELL_10MS CALL DELL_10MS CALL DELL_10MS CALL DELL_10MS CALL DELL_10MS DELL_10MS: CALL DELL_1MS CALL DELL_1MS CALL DELL_1MS CALL DELL_1MS CALL DELL_1MS CALL DELL_1MS CALL DELL_1MS CALL DELL_1MS CALL DELL_1MS DELL_1MS: MOV TMP_CNT,#250 DJNZ TMP_CNT,$ MOV TMP_CNT,#250 DJNZ TMP_CNT,$ RET END Задача программы: проверять состояние порта P3.1 и управлять сигналом разрешения начала программирования ПЛИС (порт P3.0). Правильно ли я настроил порты? Хочу прошить микроконтроллер и не охота его случайно спалить.
|
|
|
|
|
Jul 26 2010, 12:01
|
Группа: Новичок
Сообщений: 2
Регистрация: 9-10-09
Пользователь №: 52 837

|
Цитата(Aleksandr_KPI @ Jul 23 2010, 13:43)  Команда orl P1MDOUT,#40h настраивает порт в режим выхода, а зачем его настраивают на вход: команда orl P1MDIN, #40h. У этих контроллеров биты порта могут работать как в аналоговом режиме, так и в цифровом. Push-Pull работает только в цифровом. Поэтому, сначала устанавливают режим работы - цифровой, а затем включают Пуш-Пул. См. даташит. Цитата(Aleksandr_KPI @ Jul 26 2010, 12:41)  Иными словами 6 вывод порта 1 настраивается в режим выхода Push-Pull, а второй нижний ключ подтягивается к единице через резистор Pull-up?
На основе этой программы написал свою... Программа должна глючить. Первое, что бросилось в глаза - в метке DONE_OK, после CALL DELL_100MS, стоит RET. Выполнив эту команду, контроллер уйдет в "свободное плавание". На время отладки тут должен быть JMP $ или еще что. И еще. "Минус" программы - нет выхода из цикла, если ПЛИС так и не будет загружена (например, какая-либо аппаратная неисправность). Было бы неплохо сделать оповещение оператора в случае НЕЗАГРУЗКИ ПЛИС (даже самому потом проще будет в глюках разбираться).
Сообщение отредактировал Mastercutor - Jul 26 2010, 11:46
|
|
|
|
|
Jul 26 2010, 14:29
|

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

|
Цитата(Aleksandr_KPI @ Jul 26 2010, 13:41)  Иными словами 6 вывод порта 1 настраивается в режим выхода Push-Pull, а второй нижний ключ подтягивается к единице через резистор Pull-up? Цитата(Mastercutor @ Jul 26 2010, 16:01)  У этих контроллеров биты порта могут работать как в аналоговом режиме, так и в цифровом. Push-Pull работает только в цифровом. Поэтому, сначала устанавливают режим работы - цифровой, а затем включают Пуш-Пул. См. даташит. Смотрим DS: Регистр P1MDIN при записи в его разряды единицы переводит в режим "Цифровой ввод" соответствующую ногу порта Р1. На вывод этот регистр не влияет (за исключением подключения Pull-up - если не выбран "Цифровой ввод": Pull-up остаётся отключеным). В режиме "Цифровой ввод" к ноге может быть подключен Pull-up, но - не обязательно, есть ещё ряд условий для его подключения, например, XBR2.7. В режиме Push-Pull подключение Pull-up производится только если открыт верхний ключ (если открыт нижний ключ - Pull-up - отключен - см. рис.17.1).
|
|
|
|
|
Jul 27 2010, 08:11
|
Группа: Новичок
Сообщений: 2
Регистрация: 9-10-09
Пользователь №: 52 837

|
Цитата(Палыч @ Jul 26 2010, 17:29)  Смотрим DS: Регистр P1MDIN при записи в его разряды единицы переводит в режим "Цифровой ввод" соответствующую ногу порта Р1. На вывод этот регистр не влияет (за исключением подключения Pull-up - если не выбран "Цифровой ввод": Pull-up остаётся отключеным). В режиме "Цифровой ввод" к ноге может быть подключен Pull-up, но - не обязательно, есть ещё ряд условий для его подключения, например, XBR2.7. В режиме Push-Pull подключение Pull-up производится только если открыт верхний ключ (если открыт нижний ключ - Pull-up - отключен - см. рис.17.1). Все верно. P1MDIN определяет режим ввода порта P1 и кроме того управлет подтяжкой. Перевод бита этого регистра в "1" (цифровой вход) необходим для чтения состояния выхода. Если бит будет находится в "0" (аналоговый вход), то при чтении состояния выхода всегда будет возвращаться "0". XBR2.7 - глобальное разрешение/запрещение подтяжек (Pull-up).
Сообщение отредактировал Mastercutor - Jul 27 2010, 08:13
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|