Передача строки по UART

Обсуждаем контроллеры компании Atmel.
Ответить
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18769
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

Аlex писал(а):Вы ходите по форуму только в поисках фраз (слов, предложений), за которые можно зацепиться и, поспорив, попытаться показать себя грамотнее тех, кто их озвучил
разве не в этом смысл форума? разве дающий советы изначально не позиционирует сам себя, как более знающий?
я встреваю только в том случае, когда вижу попытку сделать хуже, чем было. топикстартер спросил совета, и я молчал, пока не увидел ВРЕДНЫЙ совет. в чем вредность - я обосновал. вы считаете, что из толерантности к чужому мнению, которое вредит другим, я должен промолчать? ок, теперь буду молчать, когда люди демонстрируют полную безграмотность: "АБ" - это два магических числа... да еще и с сарказмом демонстрируют...

а потом вы же сами будете отсылать новичка учить матчасть, когда он будет спрашивать "почему в Си в строке на 1 символ больше, чем в кавычках" - да? это лучше? причем отсылать будете куда как в более резкой форме, чем я.

ладно, теперь можете потереть тему, как модератор. :( всё равно моё мнение не интересно тем, кто считает неприемлемым обращать внимание на собственные ляпы...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Реклама
Открыл глаза
Сообщения: 54
Зарегистрирован: Пн янв 11, 2016 20:35:49

Сообщение LEX38RUS »

В чем может быт л шибка?
Записал я данные принятые по UART в буфер далее по окончанию приёма активирую переменную и проверяю в цикле условие
If (start == 1)
If (strcmp(rx_buffer, buffer) == 0)
PORTC = 0b00000001

Где:
start переменная активируется после окончания приёма данных.
rx_buffer принятые данные
buffer переменная типа char заполненая символами ON тоесть char buffer[] = "ON"
В итоге два этих буфера должы быть одинаковы но на деле ни чего не работает.

Добавлено after 13 minutes 10 seconds:
Пробовал и таким способом

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

define RX_BUFFER   128    //длина нашего буфера, читай макс. длина строки

volatile unsigned char work=0;
volatile unsigned char rx_buffer[RX_BUFFER];
int rx_index;
ISR(USART_RXC_vect)
   {
   unsigned char status,data;
   status=UCSRA;
   data=UDR;
   if ((status&((1<<FE)|(1<<PE)|(1<<DOR)))==0)
      {
      if (data==10) // CR
      {
         work=1;
      }
      else rx_buffer[rx_index]=data;

      if (++rx_index == RX_BUFFER) rx_index=0;
      
      }
   
   }
в майне:
   if (work) 
      {
      work=0;   
                  //тут пробовал так же проверять бесполезно.
                }
Переменная work не принимает значение 1, через терминал посылал данные с окончанием символом CR
Реклама
Модератор
Аватара пользователя
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

но на деле ни чего не работает
Кот покажите весь полностью. Тяжело угадать, почему у Вас может не работать.

Добавлено after 14 minutes 17 seconds:
LEX38RUS писал(а):Пробовал и таким способом
А вот это что такое ? :

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

if ((status&((1<<FE)|(1<<PE)|(1<<DOR)))==0)
Друг Кота
Аватара пользователя
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Сообщение oleg110592 »

LEX38RUS писал(а):через терминал посылал данные с окончанием символом CR

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

if (data==10) // CR
В ASCII и Юникоде возврат каретки вроде определён как 13 (или шестнадцатеричное 0D), могу и ошибаться. Лучше обозначить магическим числом '\r' :)) имхо.
Реклама
Эиком - электронные компоненты и радиодетали
Открыл глаза
Сообщения: 54
Зарегистрирован: Пн янв 11, 2016 20:35:49

Сообщение LEX38RUS »

делал и как 13 бесполезно
Реклама
Друг Кота
Аватара пользователя
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Сообщение oleg110592 »

взял исходник из первоисточника, наверное, покорежил так:
Спойлер

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

#include <avr/io.h>
#define F_CPU 8000000UL //8MHz
#include <util/delay.h>
#include <avr/interrupt.h>

uint8_t receive = 0;
uint8_t rx_data = 0;
volatile uint8_t rx_flag = 0;

void UARTInit(void) {
    UBRRH = 0;
    UBRRL = 51; //baud rate 9600
    UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXCIE);
    UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); //8 bit, 1 stop bit
}

void UARTSend(uint8_t data) {
    while(!(UCSRA & (1<<UDRE)));
    UDR = data;
}

unsigned char UARTGet() {
    while(!rx_flag);
    rx_flag = 0;
    return rx_data;
}

int main(void) {
    sei();
    UARTInit();
    while(1) {
        receive = UARTGet();
        //receive++;
        //UARTSend(receive);
		UARTSend('O');
		UARTSend('K');
		UARTSend('\r');
    }
}

ISR(USART_RXC_vect) {
    rx_data = UDR;
	if (rx_data=='\r') // CR
	{
		rx_flag = 1;
	}	
}
в протеусе работает:
Изображение
Реклама
Открыл глаза
Сообщения: 54
Зарегистрирован: Пн янв 11, 2016 20:35:49

Сообщение LEX38RUS »

Вот еще пример кода:
Спойлер

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

#define F_CPU 8000000
 
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdio.h>

#define DATA_REGISTER_EMPTY (1<<UDRE)
#define RX_COMPLETE (1<<RXC)
#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<UPE)
#define DATA_OVERRUN (1<<DOR)

#define RX_BUFFER_SIZE 16
char rx_buffer[RX_BUFFER_SIZE];
char buffer[] = "*ON$";

unsigned char rx_wr_index,rx_rd_index,rx_counter;

char rx_buffer_overflow;
char read_enable = 0;
volatile char _out = 0;
 
ISR(USART_RXC_vect )
{
	char status,data;
	status=UCSRA;
	data=UDR;
	if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
	{
		if (data =='*')
		{
			rx_wr_index=0;
			read_enable = 1;
 
		}
 
		if((data == '$')&&(read_enable == 1))
		{
				read_enable = 0;
				_out = 1;				
		}
 
		if (read_enable == 1)
		{
			rx_buffer[rx_wr_index++]=data;
			if (rx_wr_index == RX_BUFFER_SIZE) rx_wr_index=0;
 
			if (++rx_counter == RX_BUFFER_SIZE)
			{
				rx_counter=0;
				rx_buffer_overflow=1;
			}
 
		}
 
	}
}
 
int main(){
 
        DDRC= 0b00000001;

	// USART initialization
	// Communication Parameters: 8 Data, 1 Stop, No Parity
	// USART Receiver: On
	// USART Transmitter: On
	// USART Mode: Asynchronous
	// USART Baud Rate: 9600
	UCSRA=0x00;
	UCSRB=0x98;
	UCSRC=0x86;
	UBRRH=0x00;
	UBRRL=0x33;
 
	sei();

 
	while (1)
	{
 
    	if (_out == 1)
		{	
                      If (strcmp(rx_buffer, buffer) == 0)
                          {
                             PORTC = 0b00000001;
                           }

			_out = 0;
			rx_wr_index= 0;
			rx_counter = 0;			
		}
	}
}
Если опять пытаюсь сравнить буфер

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

If (strcmp(rx_buffer, buffer) == 0)
PORTC = 0b00000001
то та же ни чего не работает.
Вообще не могу вкурить как его сравнить этот буфер принятый.

Здесь алгоритм такой, когда принимаем символ $ то активируем переменную _out = 1, и заканчиваем прием read_enable = 0
Далее уже в цикле сравниваем записанные данные в буфер.
Но ни чего не выходит.
Друг Кота
Аватара пользователя
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Сообщение oleg110592 »

корявенько так накарябал, может дядюшка Мокус поправит, сравнение работает
Спойлер

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

#include <avr/io.h>
#define F_CPU 8000000UL //8MHz
#include <util/delay.h>
#include <avr/interrupt.h>
#include <string.h>

#define RX_BUFFER_SIZE 5
uint8_t received;
char rx_data [5];
volatile uint8_t rx_flag = 0;
volatile uint8_t indexchar = 0;
char buffer[] = "*ON$";
 
void UARTInit(void) {
    UBRRH = 0;
    UBRRL = 51; //baud rate 9600
    UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXCIE);
    UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); //8 bit, 1 stop bit
}

void UARTSend(uint8_t data) {
    while(!(UCSRA & (1<<UDRE)));
    UDR = data;
}

unsigned char UARTGet() {
    while(!rx_flag);
    rx_flag = 0;
    indexchar = 0;
    rx_data[4] = '\0';
    return 1;
}

int main(void) {
    DDRC = 0b00000001;
    sei();
    UARTInit();
    while(1) {
        received = UARTGet();
        if (strcmp(buffer, rx_data) == 0)
        {
            PORTC = 0b00000001;
        }
    }
}

ISR(USART_RXC_vect) {
    rx_data[indexchar] = UDR;
	if (rx_data[0] !='*')
	{
		indexchar = 0;
		return;
	}
    if ((rx_data[0]=='*') && (rx_data[indexchar]=='$'))
    {
        rx_flag = 1;
		return;
    }
    if(++indexchar >= RX_BUFFER_SIZE)
    {
        indexchar = 0;
    }
}
Открыл глаза
Сообщения: 54
Зарегистрирован: Пн янв 11, 2016 20:35:49

Сообщение LEX38RUS »

Благодарю. Будем изучать в чем ошибки у меня. Это я слизывал код с инета.
Открыл глаза
Сообщения: 54
Зарегистрирован: Пн янв 11, 2016 20:35:49

Сообщение LEX38RUS »

Код с поста выше:

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

#include <avr/io.h>
#define F_CPU 8000000UL //8MHz
#include <util/delay.h>
#include <avr/interrupt.h>
#include <string.h>

#define RX_BUFFER_SIZE 6
uint8_t received;
char rx_data [6];
volatile uint8_t rx_flag = 0;
volatile uint8_t indexchar = 0;

void UARTInit(void) {
	UBRRH = 0;
	UBRRL = 51; //baud rate 9600
	UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXCIE);
	UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); //8 bit, 1 stop bit
}

void UARTSend(uint8_t data) {
	while(!(UCSRA & (1<<UDRE)));
	UDR = data;
}

unsigned char UARTGet() {
	while(!rx_flag);
	rx_flag = 0;
	indexchar = 0;
	rx_data[4] = '\0';
	return 1;
}

int main(void) {
	DDRC = 0b00000001;
	sei();
	UARTInit();
	while(1) {
		received = UARTGet();
		if (strcmp("*ON!", rx_data) == 0)
		{
			PORTC = 0b00000001;
		}
		else
		if (strcmp("*OF!", rx_data) == 0)
		{
			PORTC = 0b00000000;
		}

	}
}

ISR(USART_RXC_vect) {
	rx_data[indexchar] = UDR;
	if (rx_data[0] !='*')
	{
		indexchar = 0;
		return;
	}
	if ((rx_data[0]=='*') && (rx_data[indexchar]=='!'))
	{
		rx_flag = 1;
		return;
	}
	if(++indexchar >= RX_BUFFER_SIZE)
	{
		indexchar = 0;
	}
}
В протеусе все работает, но если залить прошивку в кристалл то включить светодиод удается а вот выключить уже нет. В чем может быть причина?
Друг Кота
Аватара пользователя
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Сообщение oleg110592 »

криминала в тексте не вижу, может фузы, кварц 8мГц присутствует?
Открыл глаза
Сообщения: 54
Зарегистрирован: Пн янв 11, 2016 20:35:49

Сообщение LEX38RUS »

Кварц внутренний на 8 стоит с фьюзами все ровно

Добавлено after 1 minute 46 seconds:
Вот скрин фьюзов
Вложения
Снимок.PNG
(20.54 КБ) 307 скачиваний
Друг Кота
Аватара пользователя
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Сообщение oleg110592 »

хм на скриншоте JTAG - это не atmega8? Птичка это включен или выключен?
Открыл глаза
Сообщения: 54
Зарегистрирован: Пн янв 11, 2016 20:35:49

Сообщение LEX38RUS »

Атмега 16. Забыл указать. Да включён.
Друг Кота
Аватара пользователя
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Сообщение oleg110592 »

так выключить, SPIEN не задеть!
Открыл глаза
Сообщения: 54
Зарегистрирован: Пн янв 11, 2016 20:35:49

Сообщение LEX38RUS »

А что изменится при отключение jtag?
Друг Кота
Аватара пользователя
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Сообщение oleg110592 »

глянул док. - вроде для PORTC0 отключение житага не даст ничего - может пробовать перейти на скорость UARTа ниже (1200), никогда меги с использованием UART без кварца не включал.
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

oleg110592 писал(а):никогда меги с использованием UART без кварца не включал.
Включал несколько раз на 9600 мегу8 со внутренним RC генератором, а OSCCAL не менял . Проблем не было.

Добавлено after 6 minutes 35 seconds:
LEX38RUS писал(а):но если залить прошивку в кристалл то включить светодиод удается а вот выключить уже нет.
Я данный топик только бегло поглядывал. Хороший метод для тестирования UART, это возвращать на комп, что принял. В любой терминальной программе сразу будет видно.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Открыл глаза
Сообщения: 54
Зарегистрирован: Пн янв 11, 2016 20:35:49

Сообщение LEX38RUS »

Попробую внешний поставить на 12. Но думаю ни чего не изменится. Отпишусь о результатах. Скорость кстати понижал.
Включение то нормально отробатывает.

Добавлено after 5 minutes 11 seconds:
И добавлю чтоб назад отсылал то что принял. Это я так понимаю, что то вроде эхо?
Друг Кота
Аватара пользователя
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Сообщение oleg110592 »

Спойлер

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

        if (strcmp("*ON!", rx_data) == 0)
        {
            PORTC = 0b00000001;
            UARTSend('O');
            UARTSend('N');
            UARTSend('\r');
        }
        else if (strcmp("*OF!", rx_data) == 0)
        {
            PORTC = 0b00000000;
            UARTSend('O');
            UARTSend('F');
            UARTSend('\r');
        }
проверил протеус, мега16 - все четко
Ответить

Вернуться в «AVR»