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

потеря данных при передаче через UART

Добрый день! Помогите пожалуйста разобраться в следующем:

 

С микроконтроллера на внешнее устройство через UART с частотой около 2 Гц уходят наборы управляющих команд. Общий объем данных в одном наборе около 1500 байт.

При передаче происходит потеря данных, например: из этих 1500 байт может сначала послать сколько-то байт данных, потом сколько нибудь пропустит и дослать оставшиеся ;

либо может передать часть данных,и начать передавать набор с начала.

сначала отключил все прерывания(изначально отправлялось по таймеру), убрал все вызовы функций опроса датчиков,клавиатуры.

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

Заранее благодарю.

код прилагаю:

 

#include "stm32f10x.h"
#include <stdio.h>
#include <string.h>
char KUKU[]="GR SF 1\r\nGR T 20 0 x1\r\nGR SC WHITE\r\nGR L 408 270 408 200 0\r\nGR L 408 290 408 310 0\r\n\
GR L 408 310 408 360 1\r\nGR L 398 280 378 280 0\r\nGR L 378 280 328 280 1\r\nGR L 418 280 438 280 0\r\nGR L 438 280 488 280 1\r\n\
GR SC WHITE\r\nGR R 670 1 760 46 1\r\nGR B 660 11 670 36\r\nGR B 680 5 760 42\r\nGR SF 1\r\nGR T 20 550 -60°C\r\nGR SF 1\r\n\
GR T 300 550 Азимут: -1°\r\nGR SC WHITE\r\nGR L 20 416 31 433 0\r\nGR L 31 433 42 444 0\r\nGR L 42 444 53 452 0\r\n\
GR L 53 452 64 458 0\r\nGR L 64 458 75 463 0\r\nGR L 75 463 86 466 0\r\nGR L 86 466 97 469 0\r\nGR L 97 469 108 472 0\r\n\
GR L 108 472 119 474 0\r\nGR L 119 474 130 476 0\r\nGR L 130 476 141 478 0\r\nGR L 141 478 152 479 0\r\nGR L 152 479 163 480 0\r\n\
GR L 163 480 174 481 0\r\nGR L 174 481 185 483 0\r\nGR L 185 483 196 485 0\r\nGR L 196 485 207 486 0\r\nGR L 207 486 218 487 0\r\n\
GR L 218 487 229 488 0\r\nGR L 229 488 240 489 0\r\nGR L 240 489 251 489 0\r\nGR L 251 489 262 490 0\r\nGR L 262 490 273 491 0\r\n\
GR L 273 491 284 491 0\r\nGR L 284 491 295 492 0\r\nGR L 20 500 295 500 0\r\nGR SF 0\r\nGR L 20 500 20 505 0\r\nGR T 20 507 1\r\n\
GR L 64 500 64 505 0\r\nGR T 64 507 2\r\nGR L 108 500 108 505 0\r\nGR T 108 507 3\r\nGR L 152 500 152 505 0\r\nGR T 152 507 4\r\n\
GR L 185 500 185 505 0\r\nGR T 185 507 5\r\nGR L 207 500 207 505 0\r\nGR T 207 507 6\r\nGR L 229 500 229 505 0\r\nGR T 229 507 7\r\n\
GR L 251 500 251 505 0\r\nGR T 251 507 8\r\nGR L 273 500 273 505 0\r\nGR T 273 507 9\r\nGR L 295 500 295 505 0\r\nGR T 295 507 10\r\n\
GR SC WHITE\r\nGR C 700 500 50 0\r\nGR L 700 500 699 450\r\nGR SF 1\r\nGR T 691 450 c\r\nGR T 691 525 ю\r\nGR T 730 486 в\r\nGR T 655 486 з\r\nGR D\r\n"; 


void UART1_Send(char *ch);
void Init_all(void);
void TfmInit(void);
void cmd_delay(void);

int main(void)
{
volatile uint32_t i;

 __enable_irq();
//инициализация процессора
Init_all();
//Инициализация модуля
TfmInit();

 while (1)
 {
 for(i=0;i<0x28676C;i++);//тупим
 UART1_Send(KUKU);
 cmd_delay();

 }
}


void TfmInit(void)
{
volatile uint32_t i;
for(i=0;i<0x1ffffff;i++);//пауза-ждем инициализации внешнего устройства
UART1_Send ("GR D\r\n");// 
cmd_delay();
       UART1_Send ("GR CS\r\n");// 
cmd_delay();
       UART1_Send ("GR D\r\n");// 
cmd_delay();
UART1_Send("D SET REG 19 0\r\n");// 
cmd_delay();
UART1_Send("D SET REG 17 0\r\n");// 
cmd_delay();
UART1_Send("D SET REG 20 0\r\n");// 
cmd_delay();
UART1_Send("D SET REG 18 0\r\n");// 
cmd_delay();
UART1_Send("D SET REG 4 215\r\n");// 
cmd_delay();

}

void UART1_Send(char *ch)
{
unsigned int len,i;
char *p = ch;


 while (*p)
 {
   while( (USART1->SR & USART_SR_TXE) == 0);

   USART1->DR =  *p; p++;

 }
while((USART1->SR & USART_SR_TC) == 0);
USART1->SR &=  ~USART_SR_TC;
}

void cmd_delay(void)
{
volatile int delay;
delay=0x7ff;
while(delay!=0)delay--;

}

void Init_all(void)
{

GPIO_InitTypeDef   GPIO_InitStructure;
USART_InitTypeDef  USART_InitStructure;

///////////////////////////////////////////////////////////////////////////////////////////
//	INIT PERIPHERAL  CLOCK 										 
///////////////////////////////////////////////////////////////////////////////////////////
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
       RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
       RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);



///////////////////////////////////////////////////////////////////////////////////////////	
// 	PORTA 9:10 RxTx USART1											 
///////////////////////////////////////////////////////////////////////////////////////////
 /* Configure USART1 Rx as input floating */
//  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
//  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
//  GPIO_Init(GPIOA, &GPIO_InitStructure);


 /* Configure USART1 Tx as alternate function push-pull */
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
 GPIO_Init(GPIOA, &GPIO_InitStructure);
///////////////////////////////////////////////////////////////////////////////////////////	
//	      - BaudRate = 57600 baud  									
//        - Word Length = 8 Bits										
//        - One Stop Bit												
//        - no parity												
//        - Hardware flow control disabled (RTS and CTS signals)				
//        - Receive and transmit enabled									
//    															
///////////////////////////////////////////////////////////////////////////////////////////
 USART_InitStructure.USART_BaudRate = 57600;
 USART_InitStructure.USART_WordLength = USART_WordLength_8b;
 USART_InitStructure.USART_StopBits = USART_StopBits_1;
 USART_InitStructure.USART_Parity = USART_Parity_No;
 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
 USART_InitStructure.USART_Mode =  USART_Mode_Tx;

 /* Configure USART1 */
 USART_Init(USART1, &USART_InitStructure);

 USART_Cmd(USART1, ENABLE);

}

Изменено пользователем Andrey_C

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


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

Попробуйте для начала скорость UART уменьшить, например до 9600 и поставить 2 стоп бита

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


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

Сейчас попробую, а можете объяснить взаимосвязь?

 

Попробовал-результат такой же.

 

Уточню ещё некоторые детали:

Изначально делал в кейле, тоже самое перенес в иар-результата нет. Заливал код в STM32f103VET6 - тоже самое(настройки проекта соответственно менял).

Пробовал отправку через ДМА-результат тот же.

 

Выход смотрю через ft232rl программой Terminal Br@y++ v1.9- там есть лог в файл.

Изменено пользователем Andrey_C

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


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

Терминал может некоторые символы проглатывать. Считать их как "не отображаемые". Кроме того, надо отключить управление потоком. Какие у вас там настройки никто не знает.

Короче убедитесь, что терминал гарантированно всё записывает.

Лучше конечно какая нибудь более объективная прога.

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


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

Спасибо за ответ! Управление потоком естественно выключено. Кроме программы Terminal снимал лог с порта программой Putty результат такой же.

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


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

UART1_Send ("GR D\r\n");//

 

void UART1_Send(char *ch)
{
unsigned int len,i;
char *p = ch;
  while (*p)
  {
    while( (USART1->SR & USART_SR_TXE) == 0);
    USART1->DR =  *p; p++;
  }
while((USART1->SR & USART_SR_TC) == 0);
USART1->SR &=  ~USART_SR_TC;
}

Когда здесь *p будет равно 0? Когда в памяти вдруг 0 встретится?

Надо наверное вставить \0? Нет?

 

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


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

Когда здесь *p будет равно 0? Когда в памяти вдруг 0 встретится?

Надо наверное вставить \0? Нет?

О господи :cranky:

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


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

Когда здесь *p будет равно 0? Когда в памяти вдруг 0 встретится?

Надо наверное вставить \0? Нет?

Неа, когда пишут строковый литерал в кавчках \0 подставляет компилятор в конц автоматом.

http://en.cppreference.com/w/c/language/string_literal

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


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

0 подставляет компилятор в конц автоматом.

Во блин! scifi верно диагноз определил :)

 

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


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

При передаче происходит потеря данных, например: из этих 1500 байт может сначала послать сколько-то байт данных, потом сколько нибудь пропустит и дослать оставшиеся ;

либо может передать часть данных,и начать передавать набор с начала.

Может дело в МК? Сброса не происходит внезапного? Проверьте пропай ножек МК. Тактирование от чего ведётся - внешний кварц? Мб там что-то не то. Попробуйте затактировать от внутреннего генератора, как изменится поведение?

Если это точно весь код, и при этом у вас может начать сначала передавать данные внезапно (вы ведь не врёте, правда? B) ), то тут явно дело в железе.

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


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

Сейчас попробую, а можете объяснить взаимосвязь?

Потеря синхронизации. в UART допустимо до 2% разбежки...

 

UART еще можно проверить замкнув RX на TX и получать эхо в контроллере...

 

 

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


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

Если это точно весь код, и при этом у вас может начать сначала передавать данные внезапно (вы ведь не врёте, правда? B) ), то тут явно дело в железе.

Для исключения проблем в железе предназначены отладочные платы. Разработка ПО обычно начинается с работы на отладочной плате, это позволяет подстраховаться от проблем по-крайней мере со стороны железа на начальном этапе.

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


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

А у Вы вообще с UART ранее работали на таком железе? Может у вас это CMSIS кривой....

Я бы у меня встретилась подобна непонятная ошибка я бы пошел последовательно

1. Проверить железку на FT232RL - замкнув RX c TX b посмотрев эхо

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

3. Соединить с компом и проверить идут ли простые посылки

...

если в пункте 2 уже не работает - выкинуть нафиг CMSIS

 

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


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

Попробуйте другую FT232 (или какой-то другой адаптер, вариантов много).

Можно попробовать передавать в себя же, замкнув rx-tx. Для начала можно просто принятые байты считать.

 

Если есть осциллограф, стоит посмотреть на линию usart'а, измерить длину бита; проследить что она не меняется, когда приём вдруг ломается.

Правда, это маловероятно - только если кварц сбивается, и процессор продолжает работать от встроенного RC-генератора. У меня так получается, только если ткнуть в ноги кварца пинцетом.

 

PS USART1->SR &= ~USART_SR_TC; делать не нужно. Во-первых, он и так скинется при повторном заходе в эту функцию. А во-вторых, правильно делать USART1->SR = ~USART_SR_TC;

 

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


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

Для исключения проблем в железе предназначены отладочные платы. Разработка ПО обычно начинается с работы на отладочной плате, это позволяет подстраховаться от проблем по-крайней мере со стороны железа на начальном этапе.

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

 

Кроме своей платы использовал и отладочную плату с другим процессором (тоже стм32,только памяти побольше).

 

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

 

А у Вы вообще с UART ранее работали на таком железе? Может у вас это CMSIS кривой....

Я бы у меня встретилась подобна непонятная ошибка я бы пошел последовательно

1. Проверить железку на FT232RL - замкнув RX c TX b посмотрев эхо

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

3. Соединить с компом и проверить идут ли простые посылки

...

если в пункте 2 уже не работает - выкинуть нафиг CMSIS

На стмках c UARTом уже работал, все вроде бы успешно было. CMSIS сначала был стмовский-когда в кейле писал. Сейчас- который в стандартной поставке ИАРА (6.20 версия)

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

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

3- простые посылки идут нормально.

 

FT232 уже заменил - пофигу.

по поводу сброса флага-спасибо, недосмотрел даташит сначала-сбрасывается оригинально- поправил :smile3046:

Если честно,то ситуация П%%%%%Ц непонятная для меня, вроде бы почти все проверено, и в другом железе в т.ч. , программно-все около дела; через ДМА,прерывания,тупо циклом-результат стабильно х...й.

 

может сплошным потоком 1500 байт СТМовский УАРТ не держит за раз?!

 

Вобщем,попробую эхо на контроллере-отпишусь,как и что.....спасибо большое за участие!

 

 

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


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

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

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

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

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

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

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

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

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

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