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

STM32F103 USAR3 обмен по ModBus

18 минут назад, jcxz сказал:

А где-ж ещё её вставлять?

Ну, по-хорошему надо не только вставить, но и со считанным что-то делать.

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


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

2 hours ago, jcxz said:

А где-ж ещё её вставлять? Вроде в начале - это как бы само собой разумеется.

"Не точный" - это мягко сказано. У меня на плате с али (STM32F103R8T6) частота HSI по дефолту == ~6.326 МГц.

Прикол в том, что вставив команду чтения SR я, фактически, обеспечил считываяние его дважды: процедура

bufio_IRQHandler(&FIFO);

в результате вызывает что-то такое (см ниже), где и происходит " смысловое" считывание SR и анализ его битов. То есть, каким-то образом двойное считывание обеспечивает правильную работу, словно происходит синхронизация одного тактового домена с другим.

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//
//  Reading DR
//
static uint16_t Read_RX(void)
{
    uint16_t 
    st = READ_BIT(STDIO_DEVICE->SR, USART_RX_FLAGS),
    dr = USART_GET_DR(STDIO_DEVICE);

    if (st) // any RX related flag
    {
        if (READ_BIT(st, USART_FLAG_FE) && dr == 0) // BREAK - prepare for DMX 
        { 
            bufio_PurgeRX(stdioFIFO());
        }
    }
    return dr;
}

 

А уверены, что на плате стоит натуральный F103, а не китайский G... как его там? Вообще-то с RC я до сих пор проблем не имел, UARTы работают достаточно стабильно.

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


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

16 минут назад, KnightIgor сказал:

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

Двойное считывание в Вашем случае лишь прикрывает последствия бага, спрятанного где-то еще. С UART-ами там все четко:wink:

Мой обработчик (скелет) для приема/передачи

UARTISR()
{
  u32 sr = PUART->SR;
  u32 cr = PUART->CR1;
  if(cr & sr & USART_SR_RXNE)
  {
    u8 b = PUART->DR;
    ...
  }
  
  if(cr & sr & USART_SR_TXE)
  {
    u8 b;
    ...
    PUART->DR = b;
    ...
    if(EndTx)
      DisTxIrqUART();
  }
}

 

Никаких двойных считываний и все работает как положено.

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


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

9 minutes ago, Arlleex said:

Мой обработчик (скелет) для приема/передачи

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

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


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

27 минут назад, haker_fox сказал:

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

ИМХО, это не имеет большого смысла, особенно учитывая периодичность возникновения прерываний.

Но стоит отметить, что я, бывает, циклически тоже обрабатываю - но это больше в случае, когда на периферии висит аппаратный FIFO.

КМК, когда прерывания от периферии забивают бОльшую часть времени CPU, стоит подумать о разгрузке, например, тем же DMA.

 

Да и в целом: ну зациклим мы проверку

while(cr & sr & USART_SR_RXNE)
{
  ...
}

якобы в надежде, что при большой плотности данных есть шанс снизить риск потери байта.

Однако, когда мы зайдем в такой же цикл опроса TXE (ниже по коду) - в этот момент может сновать возникнуть RXNE.

И мы уже не обработаем его в текущем ISR. Мы выйдем из него и зайдем снова.

И где тогда выгода, если даже при циклической обработке можно терять байты?:wink:

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

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


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

58 минут назад, KnightIgor сказал:

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

44 минуты назад, Arlleex сказал:

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

Согласен с Arlleex.

58 минут назад, KnightIgor сказал:

А уверены, что на плате стоит натуральный F103, а не китайский G... как его там? Вообще-то с RC я до сих пор проблем не имел, UARTы работают достаточно стабильно.

Не уверен. Скорее даже подозреваю. Поэтому писал сюда: https://electronix.ru/forum/index.php?app=forums&module=forums&controller=topic&id=157135&do=findComment&comment=1700231

Но периферия (UART, таймер, SPI и пр.) работают там нормально, проблемы только с предвыборкой и HSI.

UART.SR у меня считывается только единожды как видно:

extern "C" void concat(isrUART, nUART_serv)()
{
  uint c, i0, i1, i2;
  HwRegsUART volatile *io = &concat(UART, nUART_serv);
  if ((i0 = io->SR) & (1 << UART_SR_NE | 1 << UART_SR_FE)) c = io->DR;
  else if (i0 & 1 << UART_SR_RXNE) {
    c = io->DR;
    if (i0 & (1 << UART_SR_PE | 1 << UART_SR_ORE)) return;
    i0 = rxw;
    if ((i1 = i0 + 1) >= sizeof(bufService.rx)) i1 = 0;
    if (i1 == (i2 = rxr)) return;
    bufService.rx[i0] = c;
    rxw = i1;
    if (i0 == i2) OsFlagSet(&rxNoEmpty);
  }
}

 

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


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

59 minutes ago, Arlleex said:

И где тогда выгода, если даже при циклической обработке можно терять байты

Да, погорячился я немного. Почему-то на ум пришёл синхронный интерфейс типа SPI, где сколько передали, столько и приняли.

1 hour ago, Arlleex said:

Но стоит отметить, что я, бывает, циклически тоже обрабатываю - но это больше в случае, когда на периферии висит аппаратный FIFO.

Аналогично!

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


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

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

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

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

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

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

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

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

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

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