Джиттер контакта UART TX

Я разрабатываю небольшого робота, используя плату STM32L152C Discovery. В настоящее время я пытаюсь настроить плату с помощью STM32CubeMX. Я никогда не работал на таком низком уровне (мой опыт гораздо больше связан с алгоритмами), поэтому я начал делать простые вещи, такие как отправка нескольких символов на порт UART. На плате нет внешнего генератора. Поэтому я использую внутренний RC-генератор.

После этого я написал очень простое программное обеспечение, которое постоянно отправляет символ на порт UART:

void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART2_UART_Init(void);

int main(void)
{
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_USART2_UART_Init();
    unsigned char msg = '@';

    while (1)
    {
        HAL_UART_Transmit(&huart2,&msg,1,1);
    }
}

Используя осциллограф на 100 МГц, я получаю следующее:

серийный дрейф

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

Я подумал, что, возможно, это может быть проблема с RC-генератором. После установки тактовой частоты на 4,194 МГц (максимум) с помощью конфигуратора STM32 я измерил тактовую частоту, но результат оказался не таким, как я ожидал.

Вот что я получаю:

Измерение часов с помощью осциллографа

Во-первых, я заметил, что волна не такая уж "прямая", а также немного другая частота: 4,202 МГц вместо 4,194 МГц.

Я хотел бы лучше понять, почему я получаю этот вывод.

Что касается формы, поскольку осциллограф имеет частоту 100 МГц, а часы имеют частоту ~ 4 МГц, я думаю, что измерительный инструмент не является проблемой. Касательно частоты, я бы сказал, что проблема в точности самого RC-генератора. Могут ли они быть причиной проблемы, которую я получаю на UART?

Ваши часы отлично подходят для этого приложения. Вы пробовали одиночный выстрел на выходе UART? Кажется, вы получаете несколько наложенных передач.
Может вообще не быть проблемы. UART являются символьно-асинхронными. Вызывает ли петля (TX, подключенный к RX) проблемы с неправильными символами?
Я согласен, проблемы не отображаются. 10% ошибка часов по сравнению со скоростью передачи, насколько я помню, это предел для 10-битной выборки по центру, включая. start/stop Jitter — это просто задержка в режиме простоя. Проблема в настройке задержки срабатывания. по размаху.
Добавьте некоторое время простоя между символами и некоторое время задержки в вашем прицеле или активируйте последовательное декодирование, если оно доступно.
это задумано, вам нужно быть достаточно близко, чтобы другая сторона могла работать через символ, поэтому ваш джиттер и / или ошибка тактовой частоты могут быть относительно большими. Это асинхронный интерфейс, поэтому предполагается, что обе стороны не будут использовать одни и те же часы, поэтому стартовые биты и стоповые биты гарантируют ребра, которые можно использовать для поиска битовых ячеек в следующем символе.
Кстати, 8N1 символ 0x55 ("U") создает прямоугольную волну...

Ответы (2)

Итак, здесь есть несколько ответов, я начну с простого для простого объяснения (во всяком случае, для меня) до более нечетких ответов.

Во-первых, форма волны, которую вы разместили, не является «квадратной» из-за нескольких факторов, а именно паразитных электронных эффектов, которые влияют на контакт, который вы исследуете, таких как емкость, неправильное заземление вашего прицела, последовательное сопротивление на дорожке, паразитная индуктивность и тому подобное. По сути, все эти паразитные эффекты ограничивают скорость изменения состояния контакта. На практике настоящая прямоугольная волна невозможна, поскольку для этого потребовалось бы мгновенное изменение состояния схемы (если бы это было так, наши компьютеры работали бы НАМНОГО быстрее, чем они). Существует также дополнительная «ошибка» с микроконтроллерами STM32 и другими, где можно изменить мощность выходного привода. То есть можно, в прошивке, диктуйте, какой ток вы проталкиваете через контакт в остальную часть схемы, тем самым изменяя скорость, с которой он может изменять состояние. В опубликованном вами коде об этом не упоминается, поэтому, скорее всего, микропроцессор работает на частоте 20 МГц по умолчанию, что подтверждается снимком экрана вашего прицела (время нарастания ~ 50 нс).

Во-вторых, вы правы, предполагая, что несоответствие выходной частоты связано с внутренним RC-генератором. введите описание изображения здесьИз таблицы данных STM32L152C, стр. 75, вы можете видеть, что внутренний RC показывает точность в наихудшем случае от -4% до +3% во всем диапазоне рабочих температур и +/- 1% при комнатной температуре. Таким образом, (4,202 - 4,194) / 4,194 * 100 = разница 0,19%, что находится в пределах спецификации.

Наконец, дрожание, скорее всего, связано с библиотеками HAL piss-porr (я знаю, что это не очень хорошее объяснение, но я столкнулся с таким количеством проблем с этим b/s, так как они перестали поддерживать библиотеку SPL, которую мы пишем наш собственный HAL для различных STM32). Если вы посмотрите на код HAL, чаще всего они передают гигантские и раздутые структуры данных, которые представляют собой автоматически сконфигурированный код HAL при каждом вызове функции. То, что обычно можно сделать, отправив 4 байта в соответствующий регистр (несколько, если не 1 цикл процессора), компилируется во многие, МНОГИЕ строки сборки. Объедините это с несколькими ISR, запускающими его здесь и там, будет некоторый джиттер. Основным узким местом здесь является то, сколько времени требуется процессору, чтобы получить следующие несколько инструкций из флэш-памяти. на самом деле это дурацкий процесс, когда процессор делает что-то с конвейерной выборкой инструкций. Вы можете прочитать Руководство для процессораздесь Раздел 3. Я бы попробовал загрузить вашу программу на плату разработчика для выполнения из ОЗУ и посмотреть, исчезнет ли проблема, если нет, то я идиот и полностью упускаю что-то простое. Но я бы порекомендовал отказаться от библиотек HAL, если вы можете, к сожалению, ST не выпустила свой SPL для частей серии L1 и L4, поэтому вам, возможно, придется немного покопаться.

Наконец... :) Это вообще проблема? Может ли ваш компьютер правильно принимать символы или вы можете декодировать их с помощью своего прицела?

Вы видите, где находится точка срабатывания трассировки прицела? Он находится в середине трассы. Джиттер предшествует триггеру и возникает между одним символом и следующим. Это не повлияет на прием символа, так как асинхронная связь не предполагает синхронизацию между символами.

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

Запущены ли какие-либо программы службы прерывания по таймеру? Например, в функции "SystemClock_Config()" - включает ли она периодический таймер.

Если это так, то существует ISR, который периодически крадет время у функции main() и вызывает изменение задержки между символами.