Проблема с UART - прием и передача (AVR)

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Закрыто
Родился
Сообщения: 10
Зарегистрирован: Чт янв 20, 2011 14:38:21

Сообщение uZZZer »

Доброго времени, суток)

Вот такой у меня еще вопрос:

Как прекратить передачу символов от контроллера к компу, после отправленных символов ?
Допустим: ввел "ANSWER", получил эхом его обратно, но только один раз, и не более.
А то получается, что сколько не нажму энтер, столько раз оно и появляется...
И отсюда еще вопрос: почему слово приходит порой не полностью ? Например "ANSWER" - "NSWER" или "SWER" ? - это происходит обычно после сброса контроллера или на второй или третий раз после энтер ?

Изображение

Код: Выделить всё

#include <avr/io.h>
#include <avr/interrupt.h>

#define F_CPU 16000000UL

#define UART_BAUD  9600 // Скорость USART порта

void USART_init(void)
{
#if F_CPU < 2000000UL && defined(U2X)
UCSRA = _BV(U2X);
UBRRL = (F_CPU / (8UL * UART_BAUD)) - 1;
#else
UBRRL = (F_CPU / (16UL * UART_BAUD)) - 1;
#endif
UCSRB = (1 << TXEN) | (1 << RXEN);
UCSRB |= (1 << RXCIE);
sei();
}



volatile char buf[200]; // Буфер
volatile int bufsize = 0; // Длина строки
volatile char ready = 0; // Получена ли строка?


ISR(USART_RXC_vect)
{
int b;
b = UDR; // Получаем эти данные
if (((b == 13) || (b == 10))
&& (bufsize > 0)) ready = 1;
if ((b != 13) && (b != 10)
&& (bufsize < sizeof(buf)-1))
buf[bufsize++] = b;

}

ISR(USART_TXC_vect)
{
//if(ready==1)
//cli();
//UDR='J';

}


int main(void)
{

USART_init();


char *p = "A ?";
while (*p){while(!(UCSRA & (1 << UDRE)));UDR = (uint16_t)*p;p++;} //тестовая строка, вместоп риветствия


while (1)
{
while (ready);
int i;


	for (i = 0; i < bufsize; i++)
	 {

	  while(!(UCSRA & (1 << UDRE)));
	  UDR = buf[i];

	  }


 bufsize = 0;
 ready = 0;
}

 
  return 0;
} 
Последний раз редактировалось uZZZer Вт апр 19, 2011 16:17:26, всего редактировалось 1 раз.
Реклама
Родился
Сообщения: 10
Зарегистрирован: Чт янв 20, 2011 14:38:21

Сообщение uZZZer »

Извиняюсь за ранее за нубский вопрос)
Реклама
Друг Кота
Аватара пользователя
Сообщения: 3872
Зарегистрирован: Пт янв 29, 2010 10:27:40
Откуда: Москва

Сообщение Engineer_Keen »

Заведите отдельную переменную. Один раз приняли "ANSWER", передали его обратно и присвоили этой переменной какое-то определенное значение, например "1". Каждый раз перед отправкой ответа проверяете переменную, если она =1, значит ничего не передаем. Делов то...
Что касается прихода слова не целиком, тут может быть все что угодно, от кривого кварца МК или не совсем верных настроек UART, до глюков ОС или самого терминала...
Родился
Сообщения: 10
Зарегистрирован: Чт янв 20, 2011 14:38:21

Сообщение uZZZer »

Спасибо огромное)


А как сравнить массив, считанный с UDR со строкой ?

Пишу вот так:
if ( (strcmp(String1, "ANSWER")) == 0 ){

..............

} - молчание...

if ( (strcmp(String1, "A")) == 0 )
{.....} - работает

т.е. массив как будто имеет один символ, на который указывает String1...
или как преобразовать массив в строку ?
Реклама
Эиком - электронные компоненты и радиодетали
Вымогатель припоя
Сообщения: 630
Зарегистрирован: Пн июн 14, 2010 13:07:29
Откуда: Жуковский

Сообщение a_skr »

uZZZer писал(а):Спасибо огромное)


А как сравнить массив, считанный с UDR со строкой ?

Пишу вот так:
if ( (strcmp(String1, "ANSWER")) == 0 ){

..............

} - молчание...

if ( (strcmp(String1, "A")) == 0 )
{.....} - работает

т.е. массив как будто имеет один символ, на который указывает String1...
или как преобразовать массив в строку ?
возможно один символ 'A' и имеет.
следующий пример работает (в протеусе):

Код: Выделить всё

#include <avr/io.h>
#include <string.h>

int main(void)
{
  char str[10]="123";
  DDRA=1;
  if(strcmp(str, "123") == 0) PORTA=1; 
  while(1);
}
Реклама
Родился
Сообщения: 10
Зарегистрирован: Чт янв 20, 2011 14:38:21

Сообщение uZZZer »

Нет, ничего не выходит(((

У меня вот такой код...

Код: Выделить всё

#include <avr/io.h>
#include <avr/interrupt.h>
#include <string.h>

#define F_CPU 16000000UL

#define UART_BAUD  9600 // Скорость USART порта

void USART_init(void)
{
#if F_CPU < 2000000UL && defined(U2X)
UCSRA = _BV(U2X);
UBRRL = (F_CPU / (8UL * UART_BAUD)) - 1;
#else
UBRRL = (F_CPU / (16UL * UART_BAUD)) - 1;
#endif
UCSRB = (1 << TXEN) | (1 << RXEN);
UCSRB |= (1 << RXCIE);
sei();
}



volatile char buf[200]; // Буфер
volatile int bufsize = 0; // Длина строки
volatile char ready = 0; // Получена ли строка?


ISR(USART_RXC_vect)
{
int b;
b = UDR; // Получаем эти данные
//if (((b == 13) || (b == 10))
//&& (bufsize >=6)) ready = 1;
if((bufsize >=5)) ready = 1;
if ((b != 13) && (b != 10)
&& (bufsize < sizeof(buf)-1))
buf[bufsize++] = b;

//char *p = "X";
//while (*p){while(!(UCSRA & (1 << UDRE)));UDR = (uint16_t)*p;p++;}


}

ISR(USART_TXC_vect)
{
//if(ready==1)
//cli();
//UDR='J';

}


int strcmpP(char *s, char *t)
{
    for ( ; *s == *t; s++, t++)
        if (*s == '\0')
            return 0;
    return (*s - *t);
}


int main(void)
{

USART_init();

char *pCmd = "TEST OK";
char cmd0[]="ANSWER";
char *pFail="FAIL";
char tmp[7];
char *a=0;

char *p = "A ?";
while (*p){while(!(UCSRA & (1 << UDRE)));UDR = (uint16_t)*p;p++;} //тестовая строка, вместоп риветствия


while (1)
{
while (!ready);
int i;

    *a =(char)*buf;
	for (i = 0; i < bufsize; i++)
	 {

	  a++;
	  *a=buf[i];
	  tmp[i]= *a;
	  //while(!(UCSRA & (1 << UDRE)));
	  //UDR = buf[i];

	  }
 //for(i=0;i<=7;i++){
if(!(memcmp((char *)tmp,cmd0,6))){
  while(*pCmd){
    while(!(UCSRA & (1 << UDRE)));

   UDR = *pCmd;
  pCmd++;}
}

 //}


/*else{
 while(*pFail){ 
while(!(UCSRA & (1 << UDRE)));

UDR = *pFail;
  pFail++;}
}*/


 bufsize = 0;
 ready = 0;
}

 
  return 0;
}
Реклама
Закрыто

Вернуться в «Микроконтроллеры и ПЛИС»