Модераторы: PILOT, ManiaK, Mazzi
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> UART Atmega8535 как обрабатывать длинные строки, т.е. как получить строку во время работы 
V
    Опции темы
max_k
Дата 27.4.2009, 12:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 14.11.2006

Репутация: нет
Всего: нет



Приветствую Уважаемые,
есть такая задачка:
Atmega8535 управляет шаговыми моторами всего их 6 штук. 
Данные о том куда и каким мотором крутить передаются от компа на Atmega через UART
Ввиду того что обмен занимает некоторое время, то если моторы встают на время приема новой порции команд, я решил разбить буфер обмена пополам и пока проц обрабатывает первую половину команд, принимать в это время вторую половину, но не тут то было smile 

вот кусок кода (для примера я его сократил до основного минимуиа)
Код

#include <mega8535.h>
#include <stdio.h>  
#include <delay.h>
#include <stdlib.h>
#include <string.h>


#define RXB8 1
#define TXB8 0
#define UPE 2
#define OVR 3
#define FE 4
#define UDRE 5
#define RXC 7

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

char bank;
char flg_set_speed;
char tm_real_del_shag;
// USART Receiver buffer
#define RX_BUFFER_SIZE 251
char rx_buffer[RX_BUFFER_SIZE];

#if RX_BUFFER_SIZE<256
unsigned char rx_wr_index,rx_rd_index,rx_counter;
#else
unsigned int rx_wr_index,rx_rd_index,rx_counter;
#endif

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


void ob_recive_str()
{
 int i;
 char data;
  if (rx_counter>=125+bank)
  { 
  puts(rx_buffer);
    
  for (i=0;i<=124;i++)
  {
    data=rx_buffer[i+bank];  
      switch (data) 
      {
        case 'Z':
            PORTA.1=1;
            delay_ms(200);                
        break;
        case 'Q':
            PORTA.1=0;                
        break;
        case 'A':
            PORTA.4=1; PORTA.5=0;PORTA.6=1;PORTA.7=0;               
        break;
        case 'B':
            PORTA.4=0; PORTA.5=1;PORTA.6=0;PORTA.7=1;                
        break;
        case '^':
            flg_set_speed=255;                
        break;
        case 'W':
                putsf("OUT of Binary Mode");
        break;
       
        default:    if (flg_set_speed==255)
                      {
                         flg_set_speed=0;
                         tm_real_del_shag=data-100;
                      }

        break;              
       };//case
       delay_ms(tm_real_del_shag);
   } // for i
   if (bank==0)
      {
         bank=125;
      }
      else
      {
         bank=0;
      }
      
   putsf("-");
   } //if rx_counter
}  


// USART Receiver interrupt service routine
interrupt [USART_RXC] void usart_rx_isr(void)
{
char status,data;
status=UCSRA;
data=UDR;
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
   {
   rx_buffer[rx_wr_index]=data;
       if (data==64)  //Если приняли символ "@" то начало передачи
       {
         rx_counter=0;   // Обнуляем счетчик буферра 
         rx_wr_index=0;
       }
         
   if (++rx_wr_index == RX_BUFFER_SIZE) rx_wr_index=0;
   if (++rx_counter == RX_BUFFER_SIZE)
      {
      rx_counter=0;
      rx_buffer_overflow=1;
      };
     ob_recive_str();
      
   };
}

#ifndef _DEBUG_TERMINAL_IO_
// Get a character from the USART Receiver buffer
#define _ALTERNATE_GETCHAR_
#pragma used+
char getchar(void)
{
char data;
while (rx_counter==0);
data=rx_buffer[rx_rd_index];
if (++rx_rd_index == RX_BUFFER_SIZE) rx_rd_index=0;
#asm("cli")
--rx_counter;
#asm("sei")
return data;
}
#pragma used-
#endif

// Standard Input/Output functions
#include <stdio.h>

// Declare your global variables here

void main(void)
{
// Declare your local variables here

// Input/Output Ports initialization
// Port A initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out 
// State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0 
PORTA=0x00;
DDRA=0xFF;

// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTB=0x00;
DDRB=0x00;

// Port C initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTC=0x00;
DDRC=0x00;

// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTD=0x00;
DDRD=0x00;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=FFh
// OC0 output: Disconnected
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
MCUCR=0x00;
MCUCSR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;

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

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;
bank=0;
// Global enable interrupts
#asm("sei")

while (1)
      {
      // Place your code here

      };
}




Так вот пока мы читаем первые 125 байт все ок,
далее когда Atmega начинает обрабатывать эти байта а управляющая программа начинает слать вторую половину, то у Atmegи возникает ошибка UART: Overrun. Data register (UDR) must be read before this point

Ошибка возникает естественно на задержке, но если задержку убрать, то и в любом другом месте.
Пробывал делать задержку использую таймер0, результат тот-же.
Как быть? В чем ошибка?  smile 
PM MAIL   Вверх
Mazzi
Дата 27.4.2009, 12:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Правильный
**


Профиль
Группа: Комодератор
Сообщений: 825
Регистрация: 3.4.2003

Репутация: 9
Всего: 21



Простое решение 1:
1) сделай буфер кольцевым
2) после приёма последнего байта посылки выставляй флажёк
3) в основном цикле при получении флажка извлекай из буфера данные и обрабатывай

Простое решение 2:
1) сделай буфер кольцевым
2) после приёма очередного байта выставляй флажёк
3) в основном цикле при получении флажка извлекай из буфера этот байт и обрабатывай

Удачи

Добавлено через 24 секунды
Задержки выкинь вообще



--------------------
Мне нужны помощники.
PM MAIL WWW   Вверх
max_k
Дата 27.4.2009, 21:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 14.11.2006

Репутация: нет
Всего: нет



Большое спасибо!
Действительно проблема в том что, вызывается прерывание по приему байта, и я именно из него вызывал процедуру обработки буфера и тем самым прерывание не заканчивалось пока вся строка не обработается и тут приходил очередной байт и вызывал прерывание повторно, вот и возникала ошибка.
А задержки выкинуть нельзя т.к. программа управляет шаговыми моторами, а они не могут крутиться с такими скоростями.
Еще раз спасибо.
Проблема решена. 
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Микроконтроллеры (MCU) и микропроцессоры (MPU)"
PILOT ManiaK
UniBomb Mazzi

На данный раздел помимо Правил форума распространяются текже следующие правила:


  • Прежде чем создать тему воспользуйтесь поиском или посмотрите в faq. Возможно на форуме уже есть ответ на ваш или близкий к вашему вопрос.
  • В заголовке темы в квадратных скобках обозначьте используемое семейство микроконтроллера: [avr],[pic],[arm].
  • При создании темы с вопросом указывайте участок кода с ошибкой, версию компилятора, схемы подключения, fuse биты и прочие данные, которые помогут найти правильный ответ. Для форматирования текста программ используйте кнопку код.
  • Новое сообщение должно иметь прямое отношение к тематике этого раздела. Для флуда, просьб выполнить задание, поиска партнёров или исполнителей существуют свои разделы.
  • Если вы заметили несовместимое с правилами сообщение, то можете уведомить об этом модератора раздела нажав кнопку Репорт у соответствующего сообщения.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, PILOT, ManiaK, UniBomb, Mazzi.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Микроконтроллеры (MCU) и микропроцессоры (MPU) | Следующая тема »


 




[ Время генерации скрипта: 0.0966 ]   [ Использовано запросов: 20 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.