Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: STM32F1xx, UART на 10МБит - осуществимо?
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
AHTOXA
Всем привет.
STM32F1xx, 72МГц, UART3 (тактируется от 36 МГц). Пытаюсь достичь высоких скоростей. И что-то не получается.
Отправляю блоки ~512 байт, через DMA.
Инициализация:
Код
    RCC->APB1ENR |= RCC_APB1ENR_USART3EN;
    USART3->BRR = 36000000 / BAUDRATE;
    USART3->CR1 =  USART_CR1_TE;      // transmit enable
    USART3->CR2 = 0;
    USART3->CR3 = USART_CR3_DMAT;   // no flow control, enable TX DMA
    USART3->CR1 |= USART_CR1_UE;      // enable USART

    // UART interrupt
    NVIC_SetPriority(USART3_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 2, 2));
    NVIC_EnableIRQ(USART3_IRQn);

    // DMA
    RCC->AHBENR |= RCC_AHBENR_DMA1EN;
    DMA1_Channel2->CPAR = (uint32_t)&USARTx->DR;
    DMA1_Channel2->CCR = 0
            | DMA_CCR1_MINC             // Memory increment mode
            | DMA_CCR1_DIR               // Read from memory
            | DMA_CCR1_PL_0             // Channel Priority level
        ;

Отправка блока:
Код
void sendBuf(const void* buf, size_t size)
{
    // clear all interrupts on DMA TX channel
    DMA1_Channel2->IFCR = DMA_ISR_GIF2;
    // set memory address and size
    DMA1_Channel2->CMAR = (uint32_t)buf;
    DMA1_Channel2->CNDTR = size;

    // Clear USART transmission complete flag:
    USART3->SR &= ~USART_SR_TC;
    // enable DMA channel
    DMA1_Channel2->CCR |= DMA_CCR1_EN;;
    // enable UART TC interrupt
    USART3->CR1 |= USART_CR1_TCIE;

    // wait for transfer complete
    txDmaDone_.wait();
    // disable DMA channel
    DMA1_Channel2->CCR &= ~DMA_CCR1_EN;;
}

Ну и прерывание от UART:
Код
void USART3_IRQHandler()
{
    uint16_t status = USART3->SR;
    if (status & USART_SR_TC)
    {
        // clear interrupt
        USART3->SR &= ~USART_SR_TC;
        // disable it
        USART3->CR1 &= ~USART_CR1_TCIE;
        // and flag transmission done
        txDmaDone_.signal_isr();
    }
}

Вот. Всё весьма незамысловато. И до скоростей порядка 2МБит это замечательно работает. А вот после - начинается нечто странное. Чем больше скорость, тем больше время отправки блока. На скорости 3.6МБит отправка блока длится несколько (около 4х) секунд. При дальнейшем увеличении скорости отправка вообще перестаёт завершаться. biggrin.gif

Такое впечатление, что обмен по DMA становится слишком интенсивным, и полностью забивает шину.
Поэтому у меня вопрос: это я натолкнулся на ограничения железа? Или я что-то делаю не так?
Кто-нибудь имел дело с такими скоростями UART, и насколько успешно?
Flexz
Дык у F1 у UART1 потолок 4.5Мбит, у 2 и 3 - 2.25МБит
36000000/16 (при единичке в BRR) и будет 2.25, откуда 10?
PS 10МБит достижимо для F4 только
KRS
Я конечно давно не использовал STM32.
Но практически везде максимальную скорость можно при кинуть по формуле Freq/16. Т.е. при 36 MHZ выше 2.25 мбита не получить.
Да и в даташите указано что уарт максимум на 4.5 мбита, как раз при 72 mhz и получается (но это на старые STM32, с новыми я не работал)

А эта запись:

Код
USART3->BRR = 36000000 / BAUDRATE;

вообще странна!
потому что в этом регистре же не только целая часть делителя но и дробная!

примерная формула должна быть такая
(36000000*16) / (BAUDRATE*16)
scifi
Цитата(KRS @ Oct 24 2012, 13:48) *
примерная формула должна быть такая
(36000000*16) / (BAUDRATE*16)

Забавная формула, учитывая, что 16 в числителе и знаменателе сокращаются :-)
Это уже обсуждалось.
AHTOXA
Цитата(Flexz @ Oct 24 2012, 15:44) *
Дык у F1 у UART1 потолок 4.5Мбит, у 2 и 3 - 2.25МБит
36000000/16 (при единичке в BRR) и будет 2.25, откуда 10?

Да, проглядел про 4.5Мбит.
Про единичку в BRR - не понял, при скорости 3 600 000 в BRR будет 10.
KRS
Цитата(scifi @ Oct 24 2012, 14:00) *
Забавная формула, учитывая, что 16 в числителе и знаменателе сокращаются :-)
Это уже обсуждалось.

что то я туплю там действительно все сокращается.
но есть ограничения.

Цитата(AHTOXA @ Oct 24 2012, 14:04) *
Про единичку в BRR - не понял, при скорости 3 600 000 в BRR будет 10.

BRR не может быть меньше 16
там фиксед поинт. но число не может быть меньше 1.0
а 10 это 10/16
scifi
Цитата(KRS @ Oct 24 2012, 14:07) *
да один множитель лишний
(36000000*16) / BAUDRATE

Всё-таки посетите ссылку.
Кстати, в STM32F2xx есть режим OVER8 (то есть oversampling 8, а не 16), там макс. битовая скорость Fbus/8.
AHTOXA
Цитата(KRS @ Oct 24 2012, 16:07) *
BRR не может быть меньше 16
там фиксед поинт. но число не может быть меньше 1.0
а 10 это 10/16

Насчёт фиксед поинт - это бредни маркетологов ST.
KRS
Цитата(scifi @ Oct 24 2012, 14:15) *
Кстати, в STM32F2xx есть режим OVER8 (то есть oversampling 8, а не 16), там макс. битовая скорость Fbus/8.

В старых, которые 72Mhz вроде не было еще! (по крайней которые я использовал)
AHTOXA
Цитата(scifi @ Oct 24 2012, 16:15) *
Кстати, в STM32F2xx есть режим OVER8 (то есть oversampling 8, а не 16), там макс. битовая скорость Fbus/8.

О, вот это ценно, спасибо! То есть, при 120 МГц это будет уже 15 Мбит. Это меня вполне устроит.
KRS
Цитата(AHTOXA @ Oct 24 2012, 14:16) *
Насчёт фиксед поинт - это бредни маркетологов ST.

Это реальный фиксед поинт!
UART на 1 бит требуется 16 клоков.
там все сокращается из за того что 4 бита после точки! Вот формула и кривая.

Обычно делитель считается как: Частота/16/Скорость в битах
Но у STM32 дробный делитель.
Регистр = Частота/16/Скорость в битах*16
16 сокращается.

scifi
Цитата(AHTOXA @ Oct 24 2012, 14:18) *
О, вот это ценно, спасибо! То есть, при 120 МГц это будет уже 15 Мбит. Это меня вполне устроит.

К сожалению, шину, на которой сидит UART, нельзя разгонять выше 60 МГц.
Тогда уж STM32F4xx. Там 168 МГц, т.е. макс. скорость UART 10,5 Мбит/с.
AHTOXA
Цитата(KRS @ Oct 24 2012, 16:22) *
Это реальный фиксед поинт!
UART на 1 бит требуется 16 клоков.
там все сокращается из за того что 4 бита после точки! Вот формула и кривая.

Или вот вам другая версия: в BRR задаётся не частота UART, а внутренняя частота семплирования UART, равная baudrate*16. И никаких fixed-point-овsm.gif
Конечно, это звучит не так маркетологически круто, как "fractional baudrate generator":)
ЗЫ. Я в своё время даже составил табличку в экселе, с двумя колонками. В одной - формула из даташита, в другой - F_BUS/BAUDRATE. И колонки совпали полностьюsm.gif

scifi
Цитата(AHTOXA @ Oct 24 2012, 14:27) *
Или вот вам другая версия: в BRR задаётся не частота UART, а внутренняя частота семплирования UART, равная baudrate*16. И никаких fixed-point-овsm.gif

Интересная интерпретация, но формула BRR = Fbus / BaudRate говорит о том, что регистр всё-таки задаёт частоту битов UART. Поэтому какая-та заморочка с тактированием там должна быть, чтобы получить дробные частоты. Сигма-дельта или что-то такое.
KRS
Цитата(AHTOXA @ Oct 24 2012, 14:27) *
Или вот вам другая версия: в BRR задаётся не частота UART, а внутренняя частота семплирования UART, равная baudrate*16. И никаких fixed-point-овsm.gif

Она там и задается!
с дробной частью.
потому что если туда записать 16
то клоки на UART пойдут 1 к 1 (в Вашем примере 36 Mhz и скорость UART будет 2.25 мбит)

Flexz
Вообще-то "дробные" частоты получить очень просто: если записать в BRR 0x33, то UART на один бит отмолотит 3 целых 16 тактовых интервала, а потом еще 3 такта Fbus (всего 51). Т.е. если считать базовой частоту Fbus/16, то делитель действительно можно называть дробным (в данном случае 3.1875). А если базовой взять Fbus то никаких дробей нет, делитель просто считает от 0 до BRR, т.е. делитель - 51.
KRS
Цитата(Flexz @ Oct 24 2012, 14:53) *
А если базовой взять Fbus то никаких дробей нет, делитель просто считает от 0 до BRR, т.е. делитель - 51.

Это UART, а не SPI он не может так работать - ему надо 16 клоков на бит.
Flexz
Кто ж ему помешает-то? 16 клоков нужны только для надежного обнаружения стартового бита ака ресинхронизации, так они на месте - меньще 0x10 в BRR писать нельзя.
AHTOXA
Цитата(scifi @ Oct 24 2012, 16:26) *
К сожалению, шину, на которой сидит UART, нельзя разгонять выше 60 МГц.

То есть, максимум 7.5 МБит? Это хуже чем 15, но лучше, чем 2.25 sm.gif
Цитата(scifi @ Oct 24 2012, 16:35) *
Интересная интерпретация, но формула BRR = Fbus / BaudRate говорит о том, что регистр всё-таки задаёт частоту битов UART. Поэтому какая-та заморочка с тактированием там должна быть, чтобы получить дробные частоты. Сигма-дельта или что-то такое.

Скорее, там где-то есть неявное предварительное умножение F_BUS на 16. Дробные - сильно сомневаюсь. (Нечто похожее на дробные скорости встречал только у MSP430, и то, там это надо было задавать руками в виде битовой маски добавочных тактов по битам.)
ViKo
А ножки на 50 MHz настроили?
AHTOXA
Да, конечно. Не стал приводить для краткости.
MrAlex
Цитата
Дробные - сильно сомневаюсь. (Нечто похожее на дробные скорости встречал только у MSP430, и то, там это надо было задавать руками в виде битовой маски добавочных тактов по битам.)

По крайней мере SAM7 семейство от Атмел имеет для асинхронного режима дробный делитель.
Нажмите для просмотра прикрепленного файла
_pv
Цитата(AHTOXA @ Oct 24 2012, 20:24) *
То есть, максимум 7.5 МБит? Это хуже чем 15, но лучше, чем 2.25 sm.gif
Скорее, там где-то есть неявное предварительное умножение F_BUS на 16. Дробные - сильно сомневаюсь. (Нечто похожее на дробные скорости встречал только у MSP430, и то, там это надо было задавать руками в виде битовой маски добавочных тактов по битам.)

максимум 4.5 на 72МГц.
нет там умножения, просто при делении на 16 разрешили выбирать скорость не как обычно после деления на 16: F/16/N, а просто как F/N, при N>16.
что позволяет более гибкую настройку частоты.
Нажмите для просмотра прикрепленного файла
если надо только передавать, а с другой стороны принимать будет кто-нибудь с УАРТом по-быстрее, то можно передатчик от SPI задействовать, только буфер нужен будет в два раза больше под 16ти разрядные данные и руками надо будет по нему пробежаться и стартовые биты в каждый байт добавить.
из него тогда и 72/2/2 = 18МБит вроде выжать можно.
AHTOXA
Цитата(_pv @ Oct 25 2012, 01:30) *
максимум 4.5 на 72МГц.

Это мы уже про F2xx.
Цитата(_pv @ Oct 25 2012, 01:30) *
нет там умножения, просто при делении на 16 разрешили выбирать скорость не как обычно после деления на 16: F/16/N, а просто как F/N, при N>16.
что позволяет более гибкую настройку частоты.

Ну как же нет? При делении F_BUS на BRR мы получаем BAUDRATE (время одного бита). Откуда тогда берётся частота семплирования 16 раз на бит?
Цитата(_pv @ Oct 25 2012, 01:30) *
если надо только передавать

Нет, к сожалению, принимать тоже нужно.
_pv
Цитата(AHTOXA @ Oct 25 2012, 02:06) *
Ну как же нет? При делении F_BUS на BRR мы получаем BAUDRATE (время одного бита). Откуда тогда берётся частота семплирования 16 раз на бит?

ну меньше чем на 16 всё равно делить нельзя.
просто пользователю дали не поделенную как обычно на 16 частоту, которую дальше можно только поделить на 2,3, ... то есть baudrate будет F/16, F/32, F/48,
а позволили просто делить и на 17, 18, 19... тоже. при этом бит всё равно где-то примерно посередине сэмплируется, ну теперь не ровно по середине, а в 8/17 например, не велика разница, зато частота гораздо гибче настраивается.
Цитата(AHTOXA @ Oct 25 2012, 02:06) *
Нет, к сожалению, принимать тоже нужно.

тогда максимум 4.5Мбит.
AHTOXA
Цитата(_pv @ Oct 25 2012, 02:35) *
ну меньше чем на 16 всё равно делить нельзя.

Ну да, вы всё очень хорошо расписали. В BRR оставили запас в 16, для того, чтобы можно было его поделить на 16 (и тем самым умножить частоту семплирования на 16 - это как раз то, о чём я и говорю sm.gif ).
Цитата(_pv @ Oct 25 2012, 02:35) *
тогда максимум 4.5Мбит.

Или 7.5 у F2xx, или 10.5 у F4xx.
Aner
QUOTE (AHTOXA @ Oct 25 2012, 00:12) *
Ну да, вы всё очень хорошо расписали. В BRR оставили запас в 16, для того, чтобы можно было его поделить на 16 (и тем самым умножить частоту семплирования на 16 - это как раз то, о чём я и говорю sm.gif ).

Или 7.5 у F2xx, или 10.5 у F4xx.

Все же ... зачем вам это нужно? ... не практично это, ... есть куча вариантов лучшиих решений по передаче данных на этих 4XX чипах.
AHTOXA
Мне надо быстро сливать большой объём данных с одного устройства на другое, кабель - метра три, жил - желательно поменьше. Вокруг будут помехи, так что USB не катит. Какие ещё у меня варианты, кроме быстрого RS-485?
Aner
Однозначно, без проблем - Ethernet 100M.
ViKo
Цитата(AHTOXA @ Oct 25 2012, 01:07) *
Мне надо быстро сливать большой объём данных с одного устройства на другое, кабель - метра три, жил - желательно поменьше. Вокруг будут помехи, так что USB не катит. Какие ещё у меня варианты, кроме быстрого RS-485?

Но сейчас вы экспериментируете без помех? А если не получили подтверждения о правильном приеме, передаете еще раз? Или как еще можно объяснить замедление передачи на высоких скоростях?
Что, если на время пересылки не разрешать процессору бегать по программе (обращаться к Flash программы), а оставить в цикле, проверяющем окончание передачи? Все команды будут читаться из буфера, нагрузка на шины меньше.
Там, где обсуждалось про F/N, я предлагал рассчитывать скорости с округлением результата. Не просто F/N, а (F + N/2)/N. Может, вы уже подобрались к скоростям, когда дробную часть от деления просто отбрасывать нельзя?
AHTOXA
Цитата(ViKo @ Oct 25 2012, 10:50) *
Но сейчас вы экспериментируете без помех?
Да, сейчас помех нет.
Скорость падала потому, что я заносил в BRR значение меньше 16. Я не смотрел осциллографом, но, по всей видимости, скорость стала какая-то ооооочень маленькая от этогоsm.gif
Цитата(ViKo @ Oct 25 2012, 10:50) *
Не просто F/N, а (F + N/2)/N.
Да, у меня именно (F + N/2)/N. В примере упростил для большей прозрачности.
Цитата(ViKo @ Oct 25 2012, 10:50) *
Может, вы уже подобрались к скоростям, когда дробную часть от деления просто отбрасывать нельзя?
Не только подобрался, но и перебралсяsm.gif))

Цитата(Aner @ Oct 25 2012, 04:22) *
Однозначно, без проблем - Ethernet 100M.

Да нет, проблема есть, и очень серъёзная. Я не уверен, что смогу быстро подобрать быстроразъёмные соединения и кабеля IP65 для Ethernet. (У меня ещё и агрессивная среда)
scifi
Цитата(AHTOXA @ Oct 25 2012, 09:20) *
Да нет, проблема есть, и очень серъёзная. Я не уверен, что смогу быстро подобрать быстроразъёмные соединения и кабеля IP65 для Ethernet. (У меня ещё и агрессивная среда)

Можно использовать 10BASE-T, он через любые разъёмы пройдет.
Allregia
Цитата(AHTOXA @ Oct 25 2012, 07:20) *
Цитата(Aner)
Однозначно, без проблем - Ethernet 100M.


Да нет, проблема есть, и очень серъёзная. Я не уверен, что смогу быстро подобрать быстроразъёмные соединения и кабеля IP65 для Ethernet. (У меня ещё и агрессивная среда)


RJ45 в IP65 как и USB.

Но а что если не UART а SPI ? Проводков чуть больше, зато со скоростью проблем не будет. От помех - тот же 485.
Вопрос с разьемами можно решить.
ViKo
Цитата(AHTOXA @ Oct 25 2012, 08:20) *
Скорость падала потому, что я заносил в BRR значение меньше 16. Я не смотрел осциллографом, но, по всей видимости, скорость стала какая-то ооооочень маленькая от этогоsm.gif

Когда посмотрите осциллографом, расскажите. Наверное, скорость передачи будет той, что задали. Но биты не смогут читаться, потому что нарушается механизм выборок, которых нужно 16 на бит.
AHTOXA
Цитата(Allregia @ Oct 25 2012, 12:07) *
RJ45 в IP65 как и USB.
Но а что если не UART а SPI ? Проводков чуть больше, зато со скоростью проблем не будет. От помех - тот же 485.
Вопрос с разьемами можно решить.

Я не сомневаюсь, что можно решить. Вопрос во времени. Нынешние разъёмы мы подбирали очень долго - много проб и ошибок. Очень многие разъёмы, несмотря на заявленную устойчивость к агрессивным средам, в реальности меньше чем за год распадаются на плесень и липовый мёд (ц).
Про SPI - это было первое, о чём мы подумали. Но при использовании диф. пар - получается многовато проводков, поэтому стали разведывать в сторону 485.
Цитата(ViKo @ Oct 25 2012, 12:14) *
Когда посмотрите осциллографом, расскажите. Наверное, скорость передачи будет той, что задали. Но биты не смогут читаться, потому что нарушается механизм выборок, которых нужно 16 на бит.

Хорошо, посмотрю (завтра). Но биты читались, приём - был. sm.gif
_pv
Цитата(AHTOXA @ Oct 25 2012, 15:16) *
Я не сомневаюсь, что можно решить. Вопрос во времени. Нынешние разъёмы мы подбирали очень долго - много проб и ошибок. Очень многие разъёмы, несмотря на заявленную устойчивость к агрессивным средам, в реальности меньше чем за год распадаются на плесень и липовый мёд (ц).
Про SPI - это было первое, о чём мы подумали. Но при использовании диф. пар - получается многовато проводков, поэтому стали разведывать в сторону 485.

может тогда просто взять езернет PHY 10мбитный. в режиме SNI будет выглядеть почти как просто SPI со стороны контроллера.
RTL8201 или DP83848.
ну или поставить любую самую мелкую cpld и на ней енкодер/декодер манчестера сделать для SPI от контроллера и потом его поверх 485 по одной паре.
Major
Цитата
может тогда просто взять езернет PHY 10мбитный. в режиме SNI будет выглядеть почти как просто SPI со стороны контроллера.
RTL8201 или DP83848.
ну или поставить любую самую мелкую cpld и на ней енкодер/декодер манчестера сделать для SPI от контроллера и потом его поверх 485 по одной паре.

Возникла похожая задача. Хочу протянуть через коаксиал питание и данные. Данных 115200 кбит/с.
Датчиков до 256 шт., каждому свой кабель 5-20 м. В идеале подошел бы TTCAN или Ethernet с протоколом синхронизации времени.
Если есть мелкое решение (корпус-жор) для UART, то будет хорошо. Вроде посмотрел все модемы, и декодеры манчестера. Все старое в PLCC. CPLD лепить сбоку не особо хочется, вдруг пропустил все в одном флаконе. Может есть готовые решения?
Пока думаю 10BASE-T half duplex через трансформатор загонять в коаксиал (все согласую сам). С езернетом смущает свитч на 256 портов и потребление phy. UART (RS-485) как-то получше смотрится, его можно сделать на МК и заводить через 100BASE.

_pv
Цитата(Major @ Jun 30 2014, 10:21) *
Возникла похожая задача. Хочу протянуть через коаксиал питание и данные. Данных 115200 кбит/с.

Не экономьте на проводах, положите лучше стандартную витую пару 5й категории, тем более она дешевле sm.gif
Для 20м и 115200 простого uarta поверх 485 вполне хватит.
Чтобы не городить 256 приёмопередатчиков со стороны хоста или свичи/хабы, можно вспомнить про незаслуженно забытый token ring.
Хотя 256 uartов в fpga тоже не большая проблема, там в младших семействах ноги скорее закончатся чем логика.
Ну или если так хочется ethernet, то тогда etherCAT, хотя получится недешево.
Major
У меня проблема комплексная, и цена кабеля вторична.
Преимущества коаксиала:
1. Любой диаметр (на 20м потери все равно какие, питание для датчиков 200мВт).
2. Простота заделки (герметизация переходов и уплотнения на резинках), кабель сам по себе плотный (если не вспенен)
2.1 (или 1.1) можно использовать полужесткие коаксиалы в сложных местах (масло+вода на переходе).
3. Простота подключения к клемам, сложно ошибиться.
Делать простой RS-485 не особо, так как нужные конденсаторы большого номинала для отвязки. Поэтому хочется манчестер, FSK или что-то подобное. Для манчестера можно CPLD сбоку, но получается что корпус FBGA с шагом 0.8 или меньше. Вот и ищу простое решение.
Можно сделать АМ на прием и передачу, но тоже габаритно. Bluetooth есть малые по габаритам и потреблению, но 2,4 ГГц сложнее загонять в коаксиал.


Aner
QUOTE (Major @ Jun 30 2014, 06:21) *
Возникла похожая задача. ..., вдруг пропустил все в одном флаконе. Может есть готовые решения?
...

... SX1276 технология Lora, манчестер аппаратный, внутри есть.
Major
Цитата
SX1276 технология Lora, манчестер аппаратный, внутри есть

Похоже подойдет. Скорость, потребление, корпус, все как надо.
Благодарю за подсказку.
Aner
http://www.aliexpress.com/item/Sfm-1-l-sx1...1698746935.html
Этот кит подешевле чем оригинальный.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.