|
|
  |
теряются символы UART STM32F030, "плавающая" проблема |
|
|
|
Jul 27 2014, 14:21
|
Участник

Группа: Участник
Сообщений: 21
Регистрация: 18-01-12
Пользователь №: 69 728

|
Привет!
Использую UART как консоль - вывожу одной строкой нужные мне данные с интервалом в секунду. Проблема в том, что ИНОГДА теряются символы. Выглядит это примерно так:
1556 mV | rise= | l | panel= | panel=4 | ltsw= 0 14 | pan curren0 | bat= 10 | bat= 1A | D= 10nt= -161 nt= -161 chg curre-165 mA | -165 mA | urrent= = 0 | = 0 | 556 mV | rise64 | ltsw=64 | ltsw=2 pan curre pan curre= 28 |00 | bat= 00 | bat= mA | D= 112195 mV | chg curr current= current=8 mA | pev6 mV | ri6 mV | ri | ref= 155se= 0 | 307 | lts307 | lts w= 0 | panel= 144 mA | D=4 mA | D=rrent= -2V | chg cuV | chg cu= 12195 mev currentev current67 mA | p556 mV | r556 mV | r | ref= 1ise= 0 | | light=anel= 2anel= 2sw= 0 | p-24 mA | D-24 mA | Drrent= = 100 | bat= 12200 -165 mA | -165 mA | urrent= mA | ref=mA | ref=nt= -167 | | 556 mV | rise= 0 | light= 302 | ltsw= 0 |current= current= 14 | pan bat= 1220 bat= 1220 D= 100 | -165 mA current=5 mA | ref5 mA | refent= -16= 1556 mV | rise= 0 | | ltsw= 0 | ltsw= 0 308 n currentn current 28 | pa= -24 mA | D= 100 hg currenhg curren195 mV | crrent= -rrent= -mA | pev cumV | rise=mV | rise=ef= 1556 0 | | light= 28 28 | 28 | 0 | panel=mA | D= 10mA | D= 10t= -33 chg curre chg curre2189 mV |current= current= mA | pev -168 mA | ref= 1556 mV | rise= 0 | light= 2 l= 28 l= 28 = 0 | pane| pan current= -3 12189 mV 12189 mV 100 | bat=66 mA | perent= -1 | ref= 15 | ref= 15 -164 mA56 mV | rise= 0 | light= 2 l= 28 = 0 | pane| pan current= -24 12195 mV 12195 mV100 | bat= | chg current= -168 mA | pev current= -166 mA | ref= 1556 mV | rise= 0 | | lig 14 | pan 14 | pan ltsw= 0 | panel= | D= 100 | D= 100 -26 mA hg currenthg current95 mV | c= -168 mA | pev cuef= 1556 mef= 1556 m68 mA | rV | rise= 0 | | light= 269 | ltsw= 0 | panel= 28 | pan current= -32 mA | D= 100 | bat= 12189 mV | chg current= -162 mA | pev current= -168 mA | ref= 1556 mV | rise= 0 | | light= 268 | ltsw= 0 | panel= 0 | pan current= -28 mA | D= 100 | bat= 12184 mV | chg current= -165 mA | pev current= -162 mA | ref= 1556 mV | rise= 0 | | light= 269 | ltsw= 0 | panel= 28 | pan current= -30 mA | D= 100 | bat= 12184 mV | chg current= -165 mA | pev current= -165 mA | ref= 1556 mV | rise= 0 | | light= 311 | ltsw= 0 | panel= 0 | pan current= -25 mA | D= 100 | bat= 12195 mV | chg current= -166 mA | pev current= -165 mA | ref= 1556 mV | rise= 0 | | light= 310 | ltsw= 0 | panel= 14 | pan current= -25 mA | D= 100 | bat= 12184 mV | chg current= -157 mA | pev current= -166 mA | ref= 1556 mV | rise= 0 | | light= 308 | ltsw= 0 | panel= 28 | pan current= -30 mA | D= 100 | bat= 12189 mV | chg current= -162 mA | pev current= -157 mA | ref= 1556 mV | rise= 0 |
Сначала видно бардак поскольку часть символов выпала, в последних 6ти строках все ок. Причем я специально скопировал тот момент когда проблема пропала, при том что девайс никто не трогал и внешние условия не менялись. Вывод осуществляется одной строкой в цикле:
printf("| light=%5d | ltsw=%2d | panel=%6d | pan current=%6d mA | D=%4d | bat=%6d mV | chg current=%6d mA | pev current=%6d mA | ref=%5d mV | rise=%2d |\n", light, ltsw, panel, paneli, d, bat, bati, bati_prev, ref, rise);
Инициализация порта с сайта кейла:
#include <stm32f0xx.h>
/*---------------------------------------------------------------------------- Initialize UART pins, Baud-rate *----------------------------------------------------------------------------*/ void init_serial (void) { int i;
/* Configure UART2 for 9600 baud */ RCC->AHBENR |= RCC_AHBENR_GPIOAEN; /* Enable GPIOA clock */ GPIOA->MODER |= GPIO_MODER_MODER9_1; // PA9 as alternative GP Output (USART1_TX) GPIOA->MODER |= GPIO_MODER_MODER10_1; // PA10 as AF GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR9; //high speed (current?) output GPIOA->AFR[1] |= 0x110; // PA9, PA10 Alternative function 1 (USART1) enable RCC->APB2ENR |= RCC_APB2ENR_USART1EN;/* Enable USART1 clock */ USART1->BRR = 0x0341; /* Configure 9600 baud, */ for (i = 0; i < 0x1000; i++) __NOP();/* avoid unwanted output */ USART1->CR1 |= (USART_CR1_UE | USART_CR1_RE | USART_CR1_TE); // Enable USART, Receive and Transmit }
/*---------------------------------------------------------------------------- Write character to Serial Port *----------------------------------------------------------------------------*/ int sendchar (int c) {
while(!(USART1->ISR & USART_ISR_TXE)); USART1->TDR = (c & 0x1FF); return ©; }
/*---------------------------------------------------------------------------- Read character from Serial Port (blocking read) *----------------------------------------------------------------------------*/ int getkey (void) {
while (!(USART1->ISR & USART_ISR_RXNE)); return (USART1->RDR); }
Сначала грешил на пролификовский адаптер, подкючил к машине с аппаратным компортом - таже фигня. Причем проблема проявляется на 2х разных контроллерах (STM32F030F4P6 b STM32F030C8T6) в разных устройствах с разной фирмварью но одинаковым кодом инициализации порта и и вывода (все приведено выше). Во втором устройстве параметров вдвое меньше в printf, соответственно отображаемая строка короче но проблема абсолютно та же. Компы тоже разные. Пробовал с ноутом работающим от батареи и устройством питающимся от другой батареи - эффект аналогичный.
Обычно вывод нормализуется через час-два работы устройства (заметил случайно раза 3, уже не совпадение) но не всегда и сколько-нибудь заметного нагрева нигде нет. Форма сигнала ТХ выглядит нормально как на ноге контроллера так и на ноге ком порта (после преобразователя уровня) и одинакова при корректном выводе и "побитом".
Код инициализации вроде бы понятен но непонятно зачем 0x1FF в строке USART1->TDR = (c & 0x1FF); Пробовал USART1->TDR = c; разницы никакой не обнаружил. Объясните пожалуйста зачем это нужно.
Ну и главный вопрос - в чем может быть проблема с выводом.
Сообщение отредактировал greenhorn - Jul 27 2014, 14:23
|
|
|
|
|
Jul 27 2014, 17:49
|
Участник

Группа: Участник
Сообщений: 21
Регистрация: 18-01-12
Пользователь №: 69 728

|
Цитата(adnega @ Jul 27 2014, 20:30)  printf работает только в одном потоке? Из других потоков печатать не пытаетесь? В одном. Более того кроме этого единственного принтфа с UART ничего больше не работает. Опрашиваю в цикле ацп, входные PIO, вывожу результатя на печать. Больше в программе ничего нет. Прерываний и энергосберегающих режимов нет. Работаю от внутреннего RC, грешил на частоту, вывел на MCO и померял частотомером - 7.991 MHz Цитата(kan35 @ Jul 27 2014, 18:35)  & 0x1FF нужно для того, чтобы гарантировать, что в уарт не записывается число длиннее 9 бит Вот спасибо - всю голову сломал а до такого банального не додумался. Цитата(kan35 @ Jul 27 2014, 18:35)  Терять может если есть переход контроллера в режим STOP, хотя наверное у вас этого нет. Может быть проблема в терминальной программе, попробуйте логировать в файл. Цитата(kan35 @ Jul 27 2014, 18:35)  Как написал выше - никаких стопов все очень тупо. А вот Bray's terminal это единственное что было неизменно во всех экспериментах, завтра буду пробовать, спасибо. Цитата(kan35 @ Jul 27 2014, 18:35)  Многие параметры взяты "по умолчанию", регистры не настраивались, но вроде 8N1 должно быть нормально. Тем не менее, я все таки рекомендую пользоваться Standart Peripherial Library или CibeMX, а то проверять каждый бит настройки довольно утомительно. Тут у меня огромная проблема с отсутствием (или немогу найти, или просто не понимаю) лоичной и последовательной документации по CMSIS и Standart Peripherial Library. По первому вообще больше по хидерам разбираюсь. Способ наверное традициооно программерский но как по мне -неправильный. В общем пока у меня с этим не сростается....
|
|
|
|
|
Jul 27 2014, 18:34
|
Участник

Группа: Участник
Сообщений: 73
Регистрация: 26-10-05
Пользователь №: 10 125

|
Попробуйте вместо TXE, TC дожидаться и сбрасывать его незабыть, тогда будет более птонятнее.
|
|
|
|
|
Jul 27 2014, 19:11
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Все прекрасно работает по TXE как и описано в документации. От перехода к проверке TC тут ничего не изменится (и не должно). Попробуйте пересчитать частоту вашего тактового генератора и "магическое число", которое вы пишете в BRR, обратно в скорость. Есть подозрение, что реальная скорость находится на грани допустимого. Если вы вдумчиво почитаете документацию на регистр BRR, то поймете, что можно просто написать Код USART1->BRR = UART1_CLOCK_FREQ / BAUDRATE; и пусть компилятор сам считает, какое конкретно число надо занести в регистр при вашей частоте и скорости. P.S. и используйте, пожалуйста, кнопку  на форме ввода сообщения для публикации исходников.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jul 27 2014, 22:27
|
Местный
  
Группа: Участник
Сообщений: 234
Регистрация: 7-11-13
Пользователь №: 79 085

|
не стал вникать в код из первого сообщения, но так понял, что контроллер шлёт данные, а программа на компе иногда не видит некоторых символов. Если контроллер работает только на передачу и со стороны компьютера никаких запросов нет, то для начала нужно определиться с неисправным звеном - МК или ПК. Самый простой способ - распаралеллить данные с МК на два компьютера с запущенной принимающей программой и сравнивать. Если пропуски будут совпадать на обоих компах, то проблема в МК, если вразнобой, то косяк на стороне ПК. Если выяснится, что дело в контроллере, то нужно будет оставить только функцию отправки данных, отключить все лишние прерывания и в бесконечном цикле гнать заранее известные данные на ПК. Если опять будут встречаться пропуски, то дело может быть в частоте кварца и если эти пропуски раз в час-два, то тут уместно будет применить контрольную сумму, если есть возможность изменить программу на компьютере. Для проверки плавания частоты можно всю плату погеть феном, одновременно наблюдая за отправляемыми данными. Цитата(greenhorn @ Jul 27 2014, 21:49)  Тут у меня огромная проблема с отсутствием (или немогу найти, или просто не понимаю) лоичной и последовательной документации по CMSIS и Standart Peripherial Library. По первому вообще больше по хидерам разбираюсь. Способ наверное традициооно программерский но как по мне -неправильный. В общем пока у меня с этим не сростается.... упорядоченое описание на русском языке функций CMSIS есть в приложении к этой книге http://www.twirpx.com/file/1136980/ В продаже она есть в терраэлектронике.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|