sbalymov

UART recive string

8 сообщений в этой теме

sbalymov    0

Привет, какой день бьюсь не как не могу принять и назад оправить строку по uart, по прерыванию, может уже есть готовые решения, подскажите.

Так мне нужно по превынию RX принять строку длинной 9 символов, потом разобью на 3 и сделаю их int ( и в дальнейшем запишу в EEPROM),

на ардуино получилось быстро, но вот тут мозгов не хватает

Как сделал на arduino:

void loop() {
  if (Serial.available() > 0){        // Смотрим если в буфере данные
    str = "";                         //Очищаем строку
     str = Serial.readStringUntil('/n');  //Читаем данные  
     s_red = str.substring(0,3);    //берем первый байт
     s_green = str.substring(3,6);  //берем 2 байт
     s_blue = str.substring(6,9);   //берем  3 байт
     b_red = s_red.toInt();    // преобразуем в str в Int
     b_green = s_green.toInt();  
     b_blue = s_blue.toInt();    
     Serial.println(b_red);     
     Serial.println(b_green);  
     Serial.println(b_blue);  
     analogWrite(red, b_red);
     analogWrite(green, b_green);
     analogWrite(blue, b_blue);
     delay(400);
   }
}

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
elki    102
23 минуты назад, sbalymov сказал:

 

Как сделал на arduino:

 

Теперь покажите, как сделали без ардуины, в какой среде делаете и какой камень.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
sbalymov    0

Atmega88 atmel studio.

Как принят сроку по прерыванию не могу понять.



 ISR(USART_RX_vect) //привем по прерыванию
 {  
 data  = UDR0;

}




void UART_Send_Str(char str[])   //отправка строки
{
	unsigned char i = 0;

	while (str[i]!='\0')
	{
		USART_transmit(str[i]);
		i++;
	}

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
elki    102

Не силен в АВР, но принцип должен быть как я вижу такой. Надо сделать массив размером со строку которую хотите принять, и в прерывании делать что то типа 

interrupt(){
uint8_t count = 0;
    data[count] = UDR;
    count++;
}

Где interrupt() это обработчик прерывания.

Гуру придут поправят, долго сидеть в прерываниях не хорошо. Ошибочка, переменную coount и определение массива  надо вынести за функцию, иначе она будет каждый раз обнуляться при заходе в прерывание. После обработки массива переменную следует обнулять.

Изменено пользователем elki

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
sbalymov    0
6 минут назад, elki сказал:

Не силен в АВР, но принцип должен быть как я вижу такой. Надо сделать массив размером со строку которую хотите принять, и в прерывании делать что то типа 

interrupt(){
uint8_t count = 0;
    data[count] = UDR;
    count++;
}

Где interrupt() это обработчик прерывания.

Гуру придут поправят, долго сидеть в прерываниях не хорошо.

я делал так))) но не получилось.

ISR(USART_RX_vect)
{  
  uint8_t i = 0;
  input[i] = UDR0;
  i++;
  if (i > 2) EEPROM_write_string(0, input);
}





int main(void){
	USART_Init(103);// speed 9600
	sei();

	while (1) {
 
 
 

	}
}

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
_abk_    99

Вот так это делает Wizard CVAVR

Скрытый текст

 

#include <mega88.h>

// Declare your global variables here

#define DATA_REGISTER_EMPTY (1<<UDRE0)
#define RX_COMPLETE (1<<RXC0)
#define FRAMING_ERROR (1<<FE0)
#define PARITY_ERROR (1<<UPE0)
#define DATA_OVERRUN (1<<DOR0)

// USART Receiver buffer
#define RX_BUFFER_SIZE0 9
char rx_buffer0[RX_BUFFER_SIZE0];

#if RX_BUFFER_SIZE0 <= 256
unsigned char rx_wr_index0=0,rx_rd_index0=0;
#else
unsigned int rx_wr_index0=0,rx_rd_index0=0;
#endif

#if RX_BUFFER_SIZE0 < 256
unsigned char rx_counter0=0;
#else
unsigned int rx_counter0=0;
#endif

// This flag is set on USART Receiver buffer overflow
bit rx_buffer_overflow0;

// USART Receiver interrupt service routine
interrupt [USART_RXC] void usart_rx_isr(void)
{
char status,data;
status=UCSR0A;
data=UDR0;
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
   {
   rx_buffer0[rx_wr_index0++]=data;
#if RX_BUFFER_SIZE0 == 256
   // special case for receiver buffer size=256
   if (++rx_counter0 == 0) rx_buffer_overflow0=1;
#else
   if (rx_wr_index0 == RX_BUFFER_SIZE0) rx_wr_index0=0;
   if (++rx_counter0 == RX_BUFFER_SIZE0)
      {
      rx_counter0=0;
      rx_buffer_overflow0=1;
      }
#endif
   }
}

#ifndef _DEBUG_TERMINAL_IO_
// Get a character from the USART Receiver buffer
#define _ALTERNATE_GETCHAR_
#pragma used+
char getchar(void)
{
char data;
while (rx_counter0==0);
data=rx_buffer0[rx_rd_index0++];
#if RX_BUFFER_SIZE0 != 256
if (rx_rd_index0 == RX_BUFFER_SIZE0) rx_rd_index0=0;
#endif
#asm("cli")
--rx_counter0;
#asm("sei")
return data;
}
#pragma used-
#endif

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

// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: Off
// USART0 Mode: Asynchronous
// USART Baud Rate: 19200
UCSR0A=(0<<RXC0) | (0<<TXC0) | (0<<UDRE0) | (0<<FE0) | (0<<DOR0) | (0<<UPE0) | (0<<U2X0) | (0<<MPCM0);
UCSR0B=(1<<RXCIE0) | (0<<TXCIE0) | (0<<UDRIE0) | (1<<RXEN0) | (0<<TXEN0) | (0<<UCSZ02) | (0<<RXB80) | (0<<TXB80);
UCSR0C=(0<<UMSEL01) | (0<<UMSEL00) | (0<<UPM01) | (0<<UPM00) | (0<<USBS0) | (1<<UCSZ01) | (1<<UCSZ00) | (0<<UCPOL0);
UBRR0H=0x00;
UBRR0L=0x26;

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
ruhi    33

ДАк у вас тут i=0; ВСЕГДА!!!

вот так хотя бы надо:

В 09.02.2019 в 17:10, sbalymov сказал:

volatile int8_t i = 0; 
ISR(USART_RX_vect) 
{ 
input[i] = UDR0; 
i++; 
if (i > 2)
{
	EEPROM_write_string(0, input); 
	i = 0;
}
}

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
sbalymov    0

@ruhiя это все уже переделал, у меня сейчас проблема с заливкой

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте аккаунт или войдите в него для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!

Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас