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я это все уже переделал, у меня сейчас проблема с заливкой

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


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

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

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

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

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

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

Войти

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

Войти сейчас


  • Сообщения

    • Здравствуйте! В разделе Ардуино не нашел подходящей темы,  да в принципе и не совсем по ардуино вопрос. Ниже приведена часть схемы прозвонки, которая может показывать как  напряжение, так и сопротивление. Измерение напряжение происходит посредством делителя, сопротивления-знаем напряжение стабилизатора и сопротивление прецизионного резистора, и через падение напряжения Ардуино вычисляет сопротивление участка. А теперь проблема, коммутация входов происходит через реле, которое управляется кнопкой. Программно была поставлена блокировка, чтоб реле не срабатывало если есть напряжение, но увы это не помогло. Спасет ли схему от случайного попадания напряжения  (~220-380В) если я поставлю диод VD2 (чтоб защитить источник стабилизированного напряжения) и VD4 (чтоб не спалить ардуино). По сути вход ардуино высокоомный и простой стабилитрон должен выдержать.
    • Заменил, поставил новые с магазина. Да еще не сказал плоттер включается, переходит по меню и сохраняет настройки.
    • Гораздо проще применить уже готовое решение не подключая дисплея например. Я, по своей неопытности, готовые исходники с atmega8 на atmega328p примерно 2 месяца переводил. А Вы хотите, что бы кто-то взялся за неизвестный ему МК под который пишется неизвестно на чём.
    • А куда верхний полигон силовой земли потеряли? Или плата трехслойная? Если нет, то плата в принципе нерабочая.
    • Существует формула для расчёта теплового сопротивления теплоотвода:
      Q=(T2-T1)/P-Q1-Q2, где
      Т2 - максимальная температура кристалла транзистора по справочнику,
      Т1 - максимально допустимая температура в коробке с нашим устройством, 
      P - рассеиваемая на транзисторе мощность,
      Q1 - тепловое сопротивление кристалл-корпус по справочнику, 
      Q2 - тепловое сопротивление корпус-радиатор. Освежите память.