реклама на сайте
подробности

 
 
> Autobaud, Автоматическое определение скорости Usart.
Ruslan Konovalov
сообщение Oct 13 2008, 13:11
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 54
Регистрация: 25-07-07
Пользователь №: 29 364



Всем добрый день.
Вот решил выложить свои мучения по данной теме.
Может кому нибудь пригодится. В инете так и толком ничего не нашел.

Алгоритм следующий:
Ногу PD0 и PD2 нужно замкнуть.
1) Устанавливаем внешнее прерывание (INT0) на захват спадающего фронта.
2) Прерывание произошло, устанавливаем внешнее прерывание (INT0) на захват восходящего фронта,
устанавливаем счетчик Timer1 на отсчет времени.
3)Прерывание произошло, останавливаем таймер, запрещаем внешнее прерывание.
4)Подсчитываем битрайт, и задерживаемся(delay_us()) до конца данного байта.
5)Настраиваем скорость усарта и принимаем данные.

Испытания проводил на Mega8, 16Mhz, на скоростях от 9600-210000.
Главные условия, чтобы младший бит первого байта посылки был равен 1.
Прием начинается со 2-го байта. Грубо говоря 1-й байт нужен для синхронизации.
Также реулизована возможность засыпания процессора. Если это не нужно, просто закомментируйте
#define SLEEP.

В принципе пока все устраивает, просто хотел узнать Ваше мнение.

Вопрос:
Теоретически после того как определили битрайт(это в конце старт-бита) нужно
сделать delay_us() равный: 1bit time*8(до начала стоп бита), а уже потом
устанавливать битрайт. Но вреальности принимается ерунда.
Но если написать следущее:
Код
  for(n=0; n < (char)baudrate-1; n++) delay_us(1);//Ничего не делаем до начала следующего байта
  for(n=0; n < (char)baudrate-1; n++) delay_us(1);

То все работает.
Эта задержка примерно равна 2-м битам.
Мне так кажется что пока я дохожу до этого момента, проходит время равное 6-ти битам.


Вот сам код:
Код
#include <ioavr.h>
#include <inavr.h>
#include "USART.h"


//********************************************************************************
**********
#define SLEEP

unsigned static char state;
unsigned int baudrate;


#pragma vector = INT0_vect
__interrupt void OnCapt()
{
  if(0==state)//Перехват падения фронта
   {
     state = 1;
     MCUCR |= (1<<ISC01) | (1<<ISC00); //Установка прерывания по восходящему фронту      
     TCNT1H=0;//Обнуляем таймер                
     TCNT1L=0;
     TCCR1B|=(0<<CS12) |(0<<CS11) | (1<<CS10);//Запускем таймер 1 без делителя  
   }
  else if(state==1)//Перехват подъема фронта
   {    
     state = 2;        
     baudrate = TCNT1L;
     baudrate |= (int)TCNT1H<<8;
     TCCR1B&=~((0<<CS12) |(0<<CS11) | (1<<CS10));//Запрещяем таймер      
     MCUCR &= ~((1<<ISC01) | (1<<ISC00));//Запрещяем захват по фронту
     GICR &= ~(1<<INT0);//Запрещаем прерывание по захвату      
   }
}

unsigned int Usart_autobaud(void)
{
  unsigned char n;
  
  state=0;
  MCUCR |= (1<<ISC01) | (0<<ISC00);  //Установка прерывания по спадающему фронту
  GICR |= (1<<INT0); //Разрешение прерывания    

#ifdef SLEEP
  MCUCR |= (1<<SE); //Разрешаем режим сна до первого внешнего прерывания
  asm("sleep");
  MCUCR &= ~(1<<SE); //Запрещаем режим сна до первого внешнего прерывания
#endif  
  
  while(state != 2); //Ждем окончание старт бита(восходящий фронт)
  
   //Определяем битрайт  
  baudrate = (baudrate>>3)-1; //baudrate=(baudrate/8)-1    
  for(n=0; n < (char)baudrate-1; n++) delay_us(1);//Ничего не делаем до начала следующего байта
  for(n=0; n < (char)baudrate-1; n++) delay_us(1);
  return baudrate;        
}
//********************************************************************************
**********



void main( void )
{  
DDRD =  0x00;
PORTD = 0x00;
DDRB =  0x00;
PORTB = 0x00;
DDRC =  0x00;
PORTC = 0x00;

#ifdef SLEEP
  MCUCR |= (0<<SM2)|(0<<SM1)|(0<<SM0);//Режим сна Idle
#endif
  
  USART0_init();//Инициализируем уарт  
  
   __enable_interrupt();
   delay_s(1);

  while(1)
  {        
   USART0_set_speed(Usart_autobaud()); //Определяем битрайт и устанавливаем скорость
   UCSRB |= (1 << RXCIE)| (1 << RXEN); //Разрешаем прием и прерывание усарта  
   while(!USARTBuffSize);          //Ждем конца приема данных  
   UCSRB &= ~((1 << RXCIE) | (1 << RXEN)); //Запрещаем прием и прерывание усарта      
   USART_SEND_STR(UsartBuff, USARTBuffSize+1);    
   USARTBuffSize = 0;  
  }

}


И еще вопрос.
В даташите написано, что пробуждение от сна по внешнему прерыванию разрешено во всех режимах.
Но у меня прерывание происходит только в режиме сна Idle.
Что я делаю не так ?

Сообщение отредактировал Ruslan Konovalov - Oct 13 2008, 12:24
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
SasaVitebsk
сообщение Oct 13 2008, 13:45
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



У меня:
1) не задействовано дополнительных ног (это для AVR ни к чему)
2) без разницы что идёт первым символом (в смысле какой нулевой бит 0 или 1)
3) На частоте 7372800 безошибочное восстановление инфы до 115200.

У меня может ошибаться UART лишь в том случае если в символе 1 перепад (например 5 мл. =0, потом =1). Это изза того, что восстановление скорости осуществляется по первому байту.
Но принципиально, если бы такая задача стояла, то я бы мог полностью восстановить данные. То есть в таком случае ждал бы первого "вменяемого" символа.
Go to the top of the page
 
+Quote Post
Ruslan Konovalov
сообщение Oct 13 2008, 14:01
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 54
Регистрация: 25-07-07
Пользователь №: 29 364



Цитата(SasaVitebsk @ Oct 13 2008, 16:45) *
У меня:
1) не задействовано дополнительных ног (это для AVR ни к чему)
2) без разницы что идёт первым символом (в смысле какой нулевой бит 0 или 1)
3) На частоте 7372800 безошибочное восстановление инфы до 115200.

У меня может ошибаться UART лишь в том случае если в символе 1 перепад (например 5 мл. =0, потом =1). Это изза того, что восстановление скорости осуществляется по первому байту.
Но принципиально, если бы такая задача стояла, то я бы мог полностью восстановить данные. То есть в таком случае ждал бы первого "вменяемого" символа.


1) Если не секрет, давайте код в студию, вдруг кому нибудь пригодится(например мне) smile.gif
2) По вашему алгоритму не получится проснуться из режима спячки.
А для меня это желательно.

Мне кажется разница между Вашим и моим алгоритмом в том что я использую внешние прерывания а Вы
Код
while(!(PIND&(1<<PD0)));//Ждем падение фронта
...
while((PIND&(1<<PD0)));//Ждем подъем
...
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Oct 13 2008, 14:33
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(Ruslan Konovalov @ Oct 13 2008, 17:01) *
1) Если не секрет, давайте код в студию, вдруг кому нибудь пригодится(например мне) smile.gif

Это я сделать не могу
Цитата
2) По вашему алгоритму не получится проснуться из режима спячки.
А для меня это желательно.

Да. Мне это было не нужно. Для этого действительно необходимо дополнительно Int задействовать
Цитата
Мне кажется разница между Вашим и моим алгоритмом в том что я использую внешние прерывания а Вы

Нет ну это просто принцип измерения длительности импульса. Это к самому алгоритму не имеет никакого отношения.

Алгоритм ваш и мой отличается как телега от мерседеса. Поскольку ничего сверхестественного в нём нет, я его просто сел и выдумал подходя к решению данной задачи. Иными словами я его нигде не заимствовал. Просто смотрел как восстанавливает посылку модем US Robotics Courier. Задумался как это можно сделать, проанализировал и получил результат.

Я не знаю так ли делает модем от US Robotics, но я делал след. образом.
1) записывал все длительности импульсов в память.
2) на лету выделял найменьший импульс, а также найменьшую разность
3) на лету определял "текущий прогнозируемый конец байта"
4) по окончанию байта определял скорость, переводил записаное в нужные биты и преобразовывал в байт, переинициализировал UART.

Скорость сбрасывал по след признакам:
1) Конец команды
2) Таймер неактивности
3) Снятие готовности терминала
Go to the top of the page
 
+Quote Post
rezident
сообщение Oct 13 2008, 15:16
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(SasaVitebsk @ Oct 13 2008, 20:33) *
Я не знаю так ли делает модем от US Robotics, но я делал след. образом.
1) записывал все длительности импульсов в память.
2) на лету выделял найменьший импульс, а также найменьшую разность
3) на лету определял "текущий прогнозируемый конец байта"
4) по окончанию байта определял скорость, переводил записаное в нужные биты и преобразовывал в байт, переинициализировал UART.
В модеме autobaud detect реализовать проще, т.к. там заранее известно, что команда с префикса AT начинается. А вот как предлагается реализовывать это же самое на MSP430. Automatic Baud Rate Detection on the MSP430
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- Ruslan Konovalov   Autobaud   Oct 13 2008, 13:11
- - GDI   ЦитатаТеоретически после того как определили битра...   Oct 13 2008, 13:17
|- - Ruslan Konovalov   Цитата(GDI @ Oct 13 2008, 16:17) А зачем ...   Oct 13 2008, 13:23
- - GDI   А не надо устранять, просто сбросьте ошибку, а про...   Oct 13 2008, 13:35
|- - Ruslan Konovalov   Цитата(GDI @ Oct 13 2008, 16:35) А не над...   Oct 13 2008, 13:44
|- - SasaVitebsk   Цитата(rezident @ Oct 13 2008, 18:16) В м...   Oct 13 2008, 17:02
- - Палыч   Цитата(Ruslan Konovalov @ Oct 13 2008, 16...   Oct 13 2008, 15:37
|- - Ruslan Konovalov   Цитата(Палыч @ Oct 13 2008, 18:37) Э-э-э-...   Oct 13 2008, 15:44
|- - Палыч   Цитата(Ruslan Konovalov @ Oct 13 2008, 18...   Oct 13 2008, 15:49
|- - Ruslan Konovalov   Цитата(Палыч @ Oct 13 2008, 18:49) Ассемб...   Oct 13 2008, 15:52
- - sf9   Господа электронщики, как определять скорость USAR...   Oct 15 2008, 11:24
|- - Maik-vs   Цитата(sf9 @ Oct 15 2008, 15:24) Господа ...   Oct 15 2008, 14:16
|- - SasaVitebsk   Цитата(sf9 @ Oct 15 2008, 14:24) Sasa из ...   Oct 15 2008, 16:55
||- - Maik-vs   Цитата(SasaVitebsk @ Oct 15 2008, 20:55) ...   Oct 16 2008, 07:15
|- - singlskv   Цитата(sf9 @ Oct 15 2008, 15:24) ВОПРОС: ...   Oct 15 2008, 17:36
|- - singlskv   Цитата(singlskv @ Oct 15 2008, 21:36) ......   Oct 15 2008, 19:03
- - ARV   в принципе, для абсолютно неизвестного потока данн...   Oct 15 2008, 15:06
- - SasaVitebsk   Для непрерывного потока, когда устройство налету в...   Oct 15 2008, 20:13
|- - singlskv   Цитата(SasaVitebsk @ Oct 16 2008, 00:13) ...   Oct 15 2008, 20:26
|- - SasaVitebsk   Цитата(singlskv @ Oct 15 2008, 23:26) Для...   Oct 15 2008, 21:50
|- - singlskv   Цитата(SasaVitebsk @ Oct 16 2008, 01:50) ...   Oct 16 2008, 13:38
- - sf9   Я тоже считаю,что для определения скорости на лету...   Oct 16 2008, 06:32
- - ae_   Цитата(singlskv @ Oct 16 2008, 22:38) Я и...   Oct 17 2008, 13:50
|- - singlskv   Цитата(ae_ @ Oct 17 2008, 17:50) Т.е. нел...   Oct 17 2008, 15:16
|- - galjoen   Делал автобауд для USART и для CAN (AT90CAN128). П...   Oct 17 2008, 16:03
- - Джеймс   Скачайте с gaisler.com библиотеку grlib-gpl Там ка...   Oct 17 2008, 17:59
- - SasaVitebsk   Тоже сталкнулся с такой байдой. Точно получить неу...   Oct 17 2008, 18:37


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 22nd June 2025 - 04:09
Рейтинг@Mail.ru


Страница сгенерированна за 0.01439 секунд с 7
ELECTRONIX ©2004-2016