Перейти к содержанию
    

st8l051 Uart детектирование FE.

Здравствуйте.

Не могу разобраться почему у меня не детектируется FE статус (битовая маска 2) в байте статуса регистра SR. С STM32 на уартах проблем нет - с ST8 непонятка. Кто-нибудь может обьяснить причину, почему при приеме данных в регистре статуса не устанавливается FE бит, тогда когда со стороны передатчика я гарантировано передаю 0 байт на пониженной в 2 раза скорости относительно приемной.

 

Изменено пользователем Картошка

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


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

По документации есть инфа: по передачи BREAK (10 или 11 бит) в зависимости от режима с количеством стоповых бит, о том ,что передача BREAK, вызывающего установку FE статуса при приеме - ограничена по времени макс. 11 бит. По приему - толкового ничего нет, только упоминание о EIE при установке срабатывания прерываний по ошибкам (FE,NF и еще что-то). Но мне передаче BREAK на ST8 не нужна, только прием данных с детектированием FE. На AVR и STM32 с FE проблем - нет, а тут загадку не могу разгадать ;(.

Изменено пользователем Картошка

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


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

В 31.10.2018 в 15:03, Integro сказал:

В Errata sheet на данный камень смотрели?
 

Да смотрел. Там ничего по FE нет, на жаль.

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


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

9 hours ago, Картошка said:

Да смотрел. Там ничего по FE нет, на жаль.

Извините, а вам действительно нужно знать, что именно нехорошего произошло на шине?

Я обычно с этим не парюсь, а всегда перед чтением регистра данных читаю регистр статуса. Все биты ошибок при этом автоматически сбрасываются.

А определение целостности данных производится на следующем уровне обработки. Там и CRC и таймауты и т.п.

И работает такой алгоритм идеально на всех STM и не только.

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


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

14 hours ago, Картошка said:

Да смотрел. Там ничего по FE нет, на жаль.

Странно, там ведь все просто, должно работать :) Тогда, код в студию!
 

 

5 hours ago, amiller said:

Извините, а вам действительно нужно знать, что именно нехорошего произошло на шине?

Обычно, это нужно при работе RS4xx либо с LIN но при отсутствии такого мезанизма эту проблему можно софтово решить

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


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

Вот код инициализации.

void Init ()
{
ClearRecv ();
CLK_PeripheralClockConfig (CLK_Peripheral_USART1, ENABLE);
//USART_DeInit (USART1);
GPIO_ExternalPullUpConfig (GPIOC, GPIO_Pin_5, ENABLE);
GPIO_ExternalPullUpConfig (GPIOC, GPIO_Pin_6, ENABLE);
USART_Init (USART1, C_TOUCHUART_SPEED, USART_WordLength_8b, USART_StopBits_1, USART_Parity_No, (USART_Mode_TypeDef)(USART_Mode_Tx | USART_Mode_Rx));
USART_ITConfig (USART1, USART_IT_RXNE, ENABLE);
//USART_ITConfig (USART1, USART_IT_FE, ENABLE);
USART_Cmd (USART1, ENABLE);
}

 

Вот прерывания.

INTERRUPT_HANDLER (USART1_TX_TIM5_UPD_OVF_TRG_BRK_IRQHandler, 27)
{
  if (!tx_size) 
    {
    USART_ITConfig (USART1, USART_IT_TXE, DISABLE);
    F_Transmiting = false;
    }
  else
  {
  USART_SendData8 (USART1, lpTxData[0]);
  lpTxData++;
  tx_size--;
  }
}


INTERRUPT_HANDLER (USART1_RX_TIM5_CC_IRQHandler, 28)
{
volatile unsigned char srreg = USART1->SR;
volatile unsigned char data = USART1->DR;

if (!F_RxDataPresents)
  {
  if ((srreg & 2))  // C_UART_FE_BIT
    {
    // получена синхронизация
    ClearRecv (); 
    lpRxData[0] = data;  
    lpRxData++;
    rx_size++;
    }
  else
    {
    switch (RxSwState)
      {
      case 0:   // принять размер и контрольную сумму данных
        {
        if (rx_size < sizeof(TSTUDATA))
          {
          lpRxData[0] = data;  
          lpRxData++;
          rx_size++;
          if (rx_size == sizeof(TSTUDATA))
            {
            if (RxInfo.CountByte <= sizeof(BufInput))   // проверить адекватный размер
              {
              rx_size = 0;
              lpRxData = BufInput;
              RxSwState++;
              }
            }
          }
        break;
        }
      case 1:   // принять данные
        {
        if (rx_size < RxInfo.CountByte)
          {
          lpRxData[0] = data;
          lpRxData++;
          rx_size++; 
          if (rx_size == RxInfo.CountByte)
            {
            F_RxDataPresents = true;
            RxSwState = 0;
            SwTask = TUARTFE::EUTS_NEED_CHECK_CRC;           // проверка контрольной суммы
            }
          }
        break;
        }
      default:
        {
        ClearRecv ();
        break;
        }
      }
    }
  }
}

#ifdef __cplusplus
}
#endif

Все внешние переменные обьявлены volatile. Ситуация когда передатчикик (он на STM32) нулевого байта на скорости в 3 раза ниже настроенной скорости, на приемной части должен быть установлен бит FE при чтении регистра статуса. Он сброшен. Нулевой байт принимается, но без фиксации в регистре SR - бита FE.

Изменено пользователем Картошка

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


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

В 01.11.2018 в 04:44, amiller сказал:

Извините, а вам действительно нужно знать, что именно нехорошего произошло на шине?

 

Из методов синхронизации байтового потока, по моему это самый лучший метод вообще, ну и для этой задачи под слабый контроллер.

FE - используется в LIN, DMX и др.

MODBUS использует IDLE режим - более чем 3.5 байтовых интервала  - это накладно ;) аж на 4 байта (я его раньше использовал). За байт стафинг я вообще не говорю, он вообще требует если не двойного приемного буфера, то по крайней мере работу без DMA проверяя каждый байт(для "высооокоуровнёвых" подходит, которым лень скорость порта на мастере переключать). 9-ти битовый режим (адресной или мастер) - это тоже не фонарь(не везде есть вроде) - жертвуешь трафиком. За HEX режимы или AT командную  кодировку - не то это, метушня на ровном месте, дутие кода и ресурсов под обработку ;) .

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


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

В 01.11.2018 в 10:23, Integro сказал:

Странно, там ведь все просто, должно работать :) Тогда, код в студию!

Вот код скинул. На параноидальные volatile внутри функции - не обращай внимания ;). 

Образно реализация протокола канального уровня :    Сначала идет нуль байт (короче он должен вызвать FE) + двубайтная структура (размер и контрольная сумма следующих за структурой данных) + данные (размер которых оговорен в струтуре) .  Все банально и есть возможность оптимизировать прием с DMA (тут не реализовано).

 

Но FE тупо не детектируется, с FE-нуль байтом я игрался, и раздувал его в 3 раза и укорачивал в оговоренный минимальный интервал это 10 или 11 бит  - ничего не получилось. Не знаю.

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


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

28 минут назад, Картошка сказал:

Вот прерывания.


INTERRUPT_HANDLER (USART1_RX_TIM5_CC_IRQHandler, 28)
{
volatile unsigned char srreg = USART1->SR;
volatile unsigned char data = USART1->DR;

if (!F_RxDataPresents)
  {
  if ((srreg & 16))  // C_UART_FE_BIT
    {
    // получена синхронизация
    ClearRecv (); 
...

Все внешние переменные обьявлены volatile. Ситуация когда передатчикик (он на STM32) нулевого байта на скорости в 3 раза ниже настроенной скорости, на приемной части должен быть установлен бит FE при чтении регистра статуса. Он сброшен. Нулевой байт принимается, но без фиксации в регистре SR - бита FE.

С таким "кодом" любые чудеса возможны. Хотя-бы почитайте как работает UART и примеры работы с ним посмотрите. Из этого "кода" видно что Вы не понимаете как работает UART.

Читать из DR нужно только после анализа содержимого SR и обнаружения там флага "наличие RX-данных". Но никак не так безусловно как у Вас. Подумайте почему.

И зачем там эти volatile? И что находится в ClearRecv()? Подозреваю что там ещё один баг.

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


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

В 11.11.2018 в 00:07, jcxz сказал:

С таким "кодом" любые чудеса возможны. Хотя-бы почитайте как работает UART и примеры работы с ним посмотрите. Из этого "кода" видно что Вы не понимаете как работает UART.

Читать из DR нужно только после анализа содержимого SR и обнаружения там флага "наличие RX-данных". Но никак не так безусловно как у Вас. Подумайте почему.

И зачем там эти volatile? И что находится в ClearRecv()? Подозреваю что там ещё один баг.

Это не stm32 с общим вектором прерываний. И то что вы те читаете документацию и не пишите нормальную обработку данных - это видно. Как видите это прерывание только по приему. А правила сброса ошибок - без грабель похоже не усвоили и пытаетесь опять изобрести велосипед. Это в хале индусы на стм32 так делают как вы говорите. 

 

В 11.11.2018 в 00:07, jcxz сказал:

И зачем там эти volatile? И что находится в ClearRecv()? Подозреваю что там ещё один баг.

Подозревайте дальше , вот весь код. Никакого отношения к хардваре тут нет.

 

static void ClearRecv ()
{
F_RxDataPresents = false;
lpRxData = (char*)&RxInfo;
rx_size = 0;
RxSwState = 0;
SwTask = TUARTFE::EUTS_NONE;
}

 

Изменено пользователем Картошка

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


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

22 минуты назад, Картошка сказал:

За байт стафинг я вообще не говорю, он вообще требует если не двойного приемного буфера, то по крайней мере работу без DMA проверяя каждый байт

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

В Вашем "коде" кадровой синхронизации нет как таковой. Что будет если фоновый процесс не успеет обработать предыдущий кадр и придёт новый? Что будет если возникнет помеха на линии? Также подозреваю что ещё целая куча багов в реализации.

А все эти стандартные методы лучше уже хотя бы отсутствием граблей на которые Вы уже наступили  - они не зависят от аппаратной реализации UART в МК. Детектируется там FE или нет - будут работать всё равно. Изучите хотя-бы байт-стаффинг - реализованный прямыми руками он будет много оптимальнее и быстрее чем этот ваш код

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


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

В 11.11.2018 в 00:23, jcxz сказал:

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

В Вашем "коде" кадровой синхронизации нет как таковой. Что будет если фоновый процесс не успеет обработать предыдущий кадр и придёт новый? Что будет если возникнет помеха на линии? Также подозреваю что ещё целая куча багов в реализации.

А все эти стандартные методы лучше уже хотя бы отсутствием граблей на которые Вы уже наступили  - они не зависят от аппаратной реализации UART в МК. Детектируется там FE или нет - будут работать всё равно. Изучите хотя-бы байт-стаффинг - реализованный прямыми руками он будет много оптимальнее и быстрее чем этот ваш код

Мужчина - можно по существу.  О каком блин еще фоновом процессе вы несете речь ? Тут методика обмена MASTER-SLAVE с синхронным квитированием по протоколу практически в каждой транзакции, без буферизации асинхронных какашек. Тут обсуждается ни моя или ваша ква-квалификации - а реальная проблема. С написанием программ на микроконтроллерах знаком еще 1997 года - это на заметку особенным. И до сих пор этим занимаюсь проффесионально.

В 11.11.2018 в 00:23, jcxz сказал:

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

Если по текущей проблеме FE на stm8 - у вас нет информации, нечего уводить в сторону...

Изменено пользователем Картошка

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


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

В 11.11.2018 в 00:23, jcxz сказал:

Что будет если фоновый процесс не успеет обработать предыдущий кадр и придёт новый?

Если не писали код по LIN (BREAK) или DMX  или подобным где используется FE синхронизация - то вам просто и кода не понять. Любой FE - это и есть синхронизация - посмотрите пожалуйста и не подсовывайте мне пережитки студенчества типа байт-стафинга (который у меня тоже есть и написан мною). Тут не стоит проблема передавать данные с PC UART в устройство, тут обмениваются два микроконтроллера и в каком формате передаю данные решаю сам.

Изменено пользователем Картошка

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


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

48 минут назад, Картошка сказал:

Это не stm32 с общим вектором прерываний. И то что вы те читаете документацию и не пишите нормальную обработку данных - это видно.

Не надо гадать о том, о чём Вы понятия не имеете. Вот пример ISR UART.RX из одного моего проекта на STM8, может он хоть чему-то Вас научит?

               SECTION  `.near.noinit`:DATA:REORDER:NOROOT(0)
bufRx          DS8      UART_RBUF_SIZE

               SECTION  `.tiny.bss`:DATA:REORDER:NOROOT(0)
uartSizRx      DS8      1
rposRx         DS8      1
wposRx         DS8      1

               SECTION  `.near_func.text`:CODE:REORDER:NOROOT(0)
               CODE
               ISR      IRQ_UART_RX
RxISR:         CLRW     X
               LD       A, L:UART_SR
               LD       XL, A
               BCP      A, #B5
               JREQ     pri_01
               LD       A, L:UART_DR
               EXG      A, XL
               BCP      A, #B1 | B2 | B3
               JRNE     pri_01
               LD       A, S:uartSizRx
               CP       A, #UART_RBUF_SIZE
               JRNC     pri_01
               INC      S:uartSizRx
               LD       A, S:wposRx
               INC      A
               AND      A, #UART_RBUF_SIZE - 1
               LD       S:wposRx, A
               EXG      A, XL
               LD       (L:bufRx, X), A
               BSET     S:work, #WF_UART
pri_01:        IRET

 

Цитата

Как видите это прерывание только по приему. А правила сброса ошибок - без грабель похоже не усвоили и пытаетесь опять изобрести велосипед. Это в хале индусы на стм32 так делают как вы говорите. 

"Только по приёму"? ;)   Значит не читаете док - это Вы. Так как оно не "только по приёму", но и по разным ошибкам приёма. И с чего вы вообще решили, что флаг FE и флаг наличия данных RXNE должны выставляться одновременно, а не скажем "сперва RXNE", а потом FE? Или наоборот? И что по такому вашему колхозу на BREAK-е, будет только одно прерывание, а не 2 подряд? Где такое вычитали в доке?

"Не работает" - у вас, а не у меня. У меня с UART STM8 вообще проблем не возникло - сразу UART заработал как было задумано. Но при этом почему-то Вы учите меня как его готовить. Как-то странно, не находите?  :biggrin:

Прежде чем начинать хамить на замечания, хотя-бы на минуту включите голову и подумайте - что будет если между 

volatile unsigned char srreg = USART1->SR;

и следующей строчкой вашего "кода" в UART.RX придёт новый байт?

40 минут назад, Картошка сказал:

С написанием программ на микроконтроллерах знаком еще 1997 года - это на заметку особенным. И до сих пор этим занимаюсь проффесионально.

Ну если всё так запущено, и за столько лет можете наплодить только такое.... тогда больше вопросов нет. Продолжайте в том же духе, флаг в руки.

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


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

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...