Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: "Мусор" на входе Atmega
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
nvk
Добрый день!

Имеется следующая программа:
CODE

#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В.
Палыч
Цитата(nvk @ Nov 24 2011, 17:50) *
На терминал выводятся числовые или буквенные символы, хотя должен быть 0.

Причин того может быть несколько
1. Неправильно инициируете USART (проверить это затруднительно, поскольку Вы не указали ни тип МК, ни тактовую частоту).
2. Неверные настройки терминала.
3. Неверная установка fuses (можно зациклить программу на МК на выводе одного и того же символа - удобно "U" - и посмотреть/померить время импульсов на выходе USART осциллографом).
4. Ошибка в схеме или в кабеле подключения к ПК.
5. .......

Чем больше Вы дадите информации, тем быстрее получите конкретный совет, позволяющий решить Вашу проблему.
nvk
1. Микроконтроллер Atmega32, тактовая частота от внешнего кварцевого резонатора частотой 14,7456 МГц. Строки приходят на терминал правильно
(например, "HELLO, WORLD!").
2-4. См. пункт 1.
Если написать:
if ((PORTB!=0x00) <некое действие>, то это действие будет выполнятся, хотя на всех пинах 0В.
Палыч
Цитата(nvk @ Nov 24 2011, 19:48) *
if ((PORTB!=0x00) <некое действие>, то это действие будет выполнятся, хотя на всех пинах 0В.

Ноги порта посажены на землю, или "болтаются в воздухе", а потенциал на них Вы замеряете вольтметром?
ucMike
Может правильнее:
Код
....
while(1)
{
inputs = PINB;
...
nvk
Цитата(Палыч @ Nov 24 2011, 23:11) *
Ноги порта посажены на землю, или "болтаются в воздухе", а потенциал на них Вы замеряете вольтметром?


Болтаются в воздухе. Вольтметром.

Цитата(ucMike @ Nov 24 2011, 23:29) *
Может правильнее:
Код
....
while(1)
{
inputs = PINB;
...


PORTB предназначен как для чтения так и для записи, а PINB только для чтения. В этом и отличие.
ucMike
Для входов PORTB определяет состояние подтягивающих резисторов. Лучше все-таки пользоваться PINB.
Палыч
Цитата(nvk @ Nov 24 2011, 20:50) *
PORTB предназначен как для чтения так и для записи, а PINB только для чтения. В этом и отличие.

О-па... Просмотрел, что читается PORTB...
Отличие у них не только в том, что один для записи/чтения, а другой только на чтение... Из порта PORTB читается то, что туда записали. Поскольку по сбросу в регистр PORTB заносятся нули, да и программе "PORTB = 0x00;", то читаться всегда должно ноль.
nvk
Цитата(Палыч @ Nov 25 2011, 01:54) *
Поскольку по сбросу в регистр PORTB заносятся нули, да и программе "PORTB = 0x00;", то читаться всегда должно ноль.


Пробовал писать так:
inputs = PINB;
Всё равно на входе не 0.
maksimp
Цитата(nvk @ Nov 24 2011, 20:50) *
Болтаются в воздухе. Вольтметром.

Плохо что болтаются. Там не 0, но когда вы подключаете вольтметр, что через его внутреннее сопротивление (хоть даже 10 МОм) напряжение снижается до 0.
Например, для проверки можете включить подтяжку на "1" с помощью PORTB=0xff; и прочтите PINB. Должно получиться 0xff. Если теперь замкнуть ногу на 0, то на ней должен прочитаться 0.

Палыч
Сообщите: какой компилятор используете.

Ошибка, скорее всего, в настройках компилятора... Сужу это по тому, что условие if(PORTB!=0x00) всегда должно быть ложным, но, по словам ТС - это не так. Возможно, какая-то беда со стеком (например, мало выделенно место под стек, и происходит его переполнение), и ещё что-то подобное.
nvk
Цитата(Палыч @ Nov 25 2011, 13:19) *
Сообщите: какой компилятор используете.

Ошибка, скорее всего, в настройках компилятора... Сужу это по тому, что условие if(PORTB!=0x00) всегда должно быть ложным, но, по словам ТС - это не так. Возможно, какая-то беда со стеком (например, мало выделенно место под стек, и происходит его переполнение), и ещё что-то подобное.


AVR Studio 4.18

Изменил программу так:
CODE

#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;
}

Выводит на терминал: "ЪК".

Наверное, нужно дорабатывать схему подключения...
nvk
Для того, чтобы проверить один старший бит, написал так:

inputs = PIND;
inputs = inputs & 0x80;
if (inputs!=0x80) {}

Работает, даже если вход подвешен в "воздухе".
Палыч
Цитата(nvk @ Nov 27 2011, 10:29) *
Работает, даже если вход подвешен в "воздухе".

"Работает" - что?
1) Приведенный Вами фрагмент с проверкой старшего бита? Как работает? Считается, что в старшем бите - ноль?
2) Ваша программа с выводом значений на терминал? Перестала выдавать буквы и теперь выдает только нули?

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

Marian
Цитата(Палыч @ Nov 25 2011, 09:19) *
Ошибка, скорее всего, в настройках компилятора... Сужу это по тому, что условие 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);    
        }


входы порта В оставьте висеть в воздухе, если в терминале что то появилось ошибка или наводка.

Теперь попробуйте заземлить любую ногу порта на корпус (желательно через резистор).

Палыч
Цитата(Marian @ Nov 27 2011, 17:16) *
Кто вам сказал, что условие if(PORTB!=0x00) всегда должно быть ложным?
Если речь о данной программе, то оно должно всегда быть истинным, так как до проверки делается PORTB = 0xFF;
Ложным она будет если в порт записать ноль PORTB = 0x00;
Не вводите другого в заблуждение.

Потрудитесь прочитать весь топик! Мою цитату Вы привели из сообщения #11 и, если Вы посмотрите версии программы ТС приведенные в предыдущих сообщениях, то увидите, что PORTB = 0x00; и только начиная с сообщения #12: PORTB = 0xFF;
usav
Давайте разделим мух и будем властвовать!
1) Подключим LED (если в этом устройстве ну больше ничего зримого нет) и
научимся им управлять.
2) Попробуем читать входную линию и выводить на светодиод. Заодно разберемся,
как "работают" PIN, PORT, if, &...
3) Поместим в буфер УАРТа что-нибудь и получим ЭТО в терминале.
4) Поставим "ЭТО" в зависимость от 2).
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.