nvk 0 24 ноября, 2011 Опубликовано 24 ноября, 2011 (изменено) · Жалоба Добрый день! Имеется следующая программа: #include <avr/io.h> #include <util/delay.h> #include <string.h> #include <stdlib.h> void USART_Transmit(char *data) { int i,s; s = strlen(data); for(i=0;i<s;i++) { /* Wait for empty transmit buffer */ while (!( UCSRA & (1<<UDRE))); /* Put data into buffer, sends the data */ UDR = data[i]; } } int main(void) { int inputs; char str[10]; char *ptr; //Все выводы порта В - входы DDRB = 0x00; PORTB = 0x00; //Настройка параметров связи UBRRH = 0x0; UBRRL = 0x7; //скорость 115,2 Кбит UCSRC = 0x86; UCSRA = 0x0; UCSRB = 0x19; //8 бит данных while(1) { inputs = PORTB; ptr = itoa(inputs, str, 10); USART_Transmit(str); } return 0; } На терминал выводятся числовые или буквенные символы, хотя должен быть 0. Измерял мультиметром напряжение на каждом отводе - либо 0,02В либо -0,6В. Изменено 24 ноября, 2011 пользователем IgorKossak [codebox] Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Палыч 6 24 ноября, 2011 Опубликовано 24 ноября, 2011 · Жалоба На терминал выводятся числовые или буквенные символы, хотя должен быть 0. Причин того может быть несколько 1. Неправильно инициируете USART (проверить это затруднительно, поскольку Вы не указали ни тип МК, ни тактовую частоту). 2. Неверные настройки терминала. 3. Неверная установка fuses (можно зациклить программу на МК на выводе одного и того же символа - удобно "U" - и посмотреть/померить время импульсов на выходе USART осциллографом). 4. Ошибка в схеме или в кабеле подключения к ПК. 5. ....... Чем больше Вы дадите информации, тем быстрее получите конкретный совет, позволяющий решить Вашу проблему. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
nvk 0 24 ноября, 2011 Опубликовано 24 ноября, 2011 (изменено) · Жалоба 1. Микроконтроллер Atmega32, тактовая частота от внешнего кварцевого резонатора частотой 14,7456 МГц. Строки приходят на терминал правильно (например, "HELLO, WORLD!"). 2-4. См. пункт 1. Если написать: if ((PORTB!=0x00) <некое действие>, то это действие будет выполнятся, хотя на всех пинах 0В. Изменено 24 ноября, 2011 пользователем IgorKossak Бездумное цитирование Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Палыч 6 24 ноября, 2011 Опубликовано 24 ноября, 2011 · Жалоба if ((PORTB!=0x00) <некое действие>, то это действие будет выполнятся, хотя на всех пинах 0В. Ноги порта посажены на землю, или "болтаются в воздухе", а потенциал на них Вы замеряете вольтметром? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ucMike 0 24 ноября, 2011 Опубликовано 24 ноября, 2011 · Жалоба Может правильнее: .... while(1) { inputs = PINB; ... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
nvk 0 24 ноября, 2011 Опубликовано 24 ноября, 2011 · Жалоба Ноги порта посажены на землю, или "болтаются в воздухе", а потенциал на них Вы замеряете вольтметром? Болтаются в воздухе. Вольтметром. Может правильнее: .... while(1) { inputs = PINB; ... PORTB предназначен как для чтения так и для записи, а PINB только для чтения. В этом и отличие. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ucMike 0 24 ноября, 2011 Опубликовано 24 ноября, 2011 (изменено) · Жалоба Для входов PORTB определяет состояние подтягивающих резисторов. Лучше все-таки пользоваться PINB. Изменено 24 ноября, 2011 пользователем ucMike Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Палыч 6 24 ноября, 2011 Опубликовано 24 ноября, 2011 · Жалоба PORTB предназначен как для чтения так и для записи, а PINB только для чтения. В этом и отличие. О-па... Просмотрел, что читается PORTB... Отличие у них не только в том, что один для записи/чтения, а другой только на чтение... Из порта PORTB читается то, что туда записали. Поскольку по сбросу в регистр PORTB заносятся нули, да и программе "PORTB = 0x00;", то читаться всегда должно ноль. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
nvk 0 25 ноября, 2011 Опубликовано 25 ноября, 2011 · Жалоба Поскольку по сбросу в регистр PORTB заносятся нули, да и программе "PORTB = 0x00;", то читаться всегда должно ноль. Пробовал писать так: inputs = PINB; Всё равно на входе не 0. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
maksimp 0 25 ноября, 2011 Опубликовано 25 ноября, 2011 · Жалоба Болтаются в воздухе. Вольтметром. Плохо что болтаются. Там не 0, но когда вы подключаете вольтметр, что через его внутреннее сопротивление (хоть даже 10 МОм) напряжение снижается до 0. Например, для проверки можете включить подтяжку на "1" с помощью PORTB=0xff; и прочтите PINB. Должно получиться 0xff. Если теперь замкнуть ногу на 0, то на ней должен прочитаться 0. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Палыч 6 25 ноября, 2011 Опубликовано 25 ноября, 2011 · Жалоба Сообщите: какой компилятор используете. Ошибка, скорее всего, в настройках компилятора... Сужу это по тому, что условие if(PORTB!=0x00) всегда должно быть ложным, но, по словам ТС - это не так. Возможно, какая-то беда со стеком (например, мало выделенно место под стек, и происходит его переполнение), и ещё что-то подобное. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
nvk 0 25 ноября, 2011 Опубликовано 25 ноября, 2011 (изменено) · Жалоба Сообщите: какой компилятор используете. Ошибка, скорее всего, в настройках компилятора... Сужу это по тому, что условие if(PORTB!=0x00) всегда должно быть ложным, но, по словам ТС - это не так. Возможно, какая-то беда со стеком (например, мало выделенно место под стек, и происходит его переполнение), и ещё что-то подобное. AVR Studio 4.18 Изменил программу так: #include <avr/io.h> #include <util/delay.h> #include <string.h> #include <stdlib.h> void USART_Transmit(char *data) { int i,s; s = strlen(data); for(i=0;i<s;i++) { /* Wait for empty transmit buffer */ while (!( UCSRA & (1<<UDRE))); /* Put data into buffer, sends the data */ UDR = data[i]; } } int main(void) { int inputs; char str[10]; char *ptr; //Все выводы порта В - входы DDRB = 0x00; PORTB = 0xFF; //Настройка параметров связи UBRRH = 0x0; UBRRL = 0x7; //скорость 115,2 Кбит UCSRC = 0x86; UCSRA = 0x0; UCSRB = 0x19; //8 бит данных while(1) { inputs = PINB; ptr = itoa(inputs, str, 10); USART_Transmit(str); } return 0; } Выводит на терминал: "ЪК". Наверное, нужно дорабатывать схему подключения... Изменено 25 ноября, 2011 пользователем IgorKossak [codebox] Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
nvk 0 27 ноября, 2011 Опубликовано 27 ноября, 2011 · Жалоба Для того, чтобы проверить один старший бит, написал так: inputs = PIND; inputs = inputs & 0x80; if (inputs!=0x80) {} Работает, даже если вход подвешен в "воздухе". Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Палыч 6 27 ноября, 2011 Опубликовано 27 ноября, 2011 · Жалоба Работает, даже если вход подвешен в "воздухе". "Работает" - что? 1) Приведенный Вами фрагмент с проверкой старшего бита? Как работает? Считается, что в старшем бите - ноль? 2) Ваша программа с выводом значений на терминал? Перестала выдавать буквы и теперь выдает только нули? Посторайтесь внятно излогать свои мысли: одно дело - общаться с сидящим рядом коллегой (он и по интонации и по жестам додумает то, что Вы не досказали), другое дело - объяснить происходящее человеку в письме... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
codenamehawk 0 27 ноября, 2011 Опубликовано 27 ноября, 2011 (изменено) · Жалоба Ошибка, скорее всего, в настройках компилятора... Сужу это по тому, что условие if(PORTB!=0x00) всегда должно быть ложным, но, по словам ТС - это не так. Кто вам сказал, что условие if(PORTB!=0x00) всегда должно быть ложным? Если речь о данной программе, то оно должно всегда быть истинным, так как до проверки делается PORTB = 0xFF; Ложным она будет если в порт записать ноль PORTB = 0x00; Не вводите другого в заблуждение. Автору, правильно читать с порта DDRB = 0x00; inputs = PINB; Но, так как у вас включены подтягивающие резисторы PORTB = 0xFF; то с порта прочитается ноль(или все нули, если говорить о битах), только если входы порта В вы подадите лог. ноль, а для этого каждую ногу порта В, через резистор нп. 1 ком подключите на корпус. Так как в некоторых процах выводы порта используются и для других целей то важно значение битов конфигурации проца. Попробуйте так : inputs=PINB; if (inputs != 0xFF) { itoa(inputs, str, 10); strcat(str,"\n\r"); USART_Transmit(str); } входы порта В оставьте висеть в воздухе, если в терминале что то появилось ошибка или наводка. Теперь попробуйте заземлить любую ногу порта на корпус (желательно через резистор). Изменено 27 ноября, 2011 пользователем Marian Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться