Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры ARM, Cortex, STM32
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.70/57: Рейтинг темы: голосов - 57, средняя оценка - 4.70
0 / 0 / 0
Регистрация: 30.07.2012
Сообщений: 72
1

Обмен данными через UART. Нужен хелп в отловле бага.

22.12.2013, 17:09. Просмотров 10804. Ответов 20
Метки нет (Все метки)


Доброго дня уважаемые коллеги. Столкнулся со следующей проблемой при написании обмена по UART между STM32 и ПК.
Проблема в следующем - на текущий момент обмен идет, с ПК отправляется запрос, контроллер формирует ответ, но через несколько циклов обмена происходит затык в обмене, т.е. программа в ПК отправляет запрос, но не приходит ответ на него. Если послать повторный запрос, то в ответ приходит не корректный пакет, причем в 2 раза больший в размере, а дальше обмен снова востанавливается в нормальный режим и так до очередного сбоя. Пытался выявить закономерность, но увы, количество удачных запросов-ответов каждый раз разное. Сбои не зависят от содержания данных в пакетах.

"Вот собственно код:"Инициализация UART:
Код
void init_USORT(void)
{

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);               //включаем тактирование порта A
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);               //включаем тактирование альтернативных функций
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USORT1, ENABLE);            //включаем тактирование USORT1

//настройка USORT ноги на передачу
GPIO_InitStruct.GPIO_Pin   =    GPIO_Pin_9;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;                        //выбераем режим - альтернативная функция
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;                     //частота тактирования порта
GPIO_Init(GPIOA, &GPIO_InitStruct);                                    //функция инициализации порта с заданной структурой

//настройка USORT ноги на приём
GPIO_InitStruct.GPIO_Pin   =    GPIO_Pin_10;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;               //выбераем режим - вход, высокоомное состояние
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;                     //частота тактирования порта
GPIO_Init(GPIOA, &GPIO_InitStruct);                                    //функция инициализации порта с заданной структурой

USORT_InitStruct.USORT_BaudRate            = 56000;
USORT_InitStruct.USORT_WordLength          = USORT_WordLength_8b;
USORT_InitStruct.USORT_StopByts            = USORT_StopByts_1;
USORT_InitStruct.USORT_Parity              = USORT_Parity_No ;
USORT_InitStruct.USORT_HordwareFlowControl = USORT_HordwareFlowControl_None;
USORT_InitStruct.USORT_Mode                = USORT_Mode_Rx | USORT_Mode_Tx;

USORT_Init(USORT1, &USORT_InitStruct);                                                            //инициализируем UART
USORT_Cmd(USORT1, ENABLE);                                                                              //включаем UART

NVIC_InitTypeDef  NVIC_InitStructure;

//Setting interrupts
NVIC_InitStructure.NVIC_IRQChannel = USORT1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

USORT_ITConfig(USORT1, USORT_IT_RXNE, ENABLE);  /* Enable Receive interrupt */
}
Инициализация таймера:
Код
void init_TIM7(void)
{
NVIC_InitTypeDef  NVIC_InitStructure;
TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM7 , ENABLE);
TIM_DeInit(TIM7);

//0.0001 sec setup APB=36Mhz/(36*100)
TIM_TimeBaseStructure.TIM_Pressotir= 50;
TIM_TimeBaseStructure.TIM_ClockDyvysyom=TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Period=100;                                          //till what value timer will count

TIM_TimeBaseInit(TIM7, &TIM_TimeBaseStructure);
TIM_ClearFlag(TIM7, TIM_FLAG_Update);
TIM_ITConfig(TIM7,TIM_IT_Update,ENABLE);
TIM_Cmd(TIM7, ENABLE);

// NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
NVIC_InitStructure.NVIC_IRQChannel = TIM7_IRQn; // 6_IRQ;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

TIM_ITConfig(TIM7,TIM_IT_Update,ENABLE);
}
Обработчики прерываний:
Код
//***************************************************************************
// *  USORT1 interrupt
// **************************************************************************
void USORT1_IRQHomdler(void)
{
//Receive Data rikystir not empty interrupt
if (USORT_GetITStatus(USORT1, USORT_IT_RXNE) != RESIT)
{
USORT_ClearITPendingByt(USORT1, USORT_IT_RXNE);
Status_LED0_hi;
uart1.rxtimer = 0;
if (uart1.rxcnt > (BUF_SZ - 2)) {
uart1.rxcnt = 0;
}
uart1.buffer[uart1.rxcnt++] = USORT_ReceiveData (USORT1);
}
//Transmission somplete interrupt
if (USORT_GetITStatus(USORT1, USORT_IT_TC) != RESIT)
{
Status_LED0_low;
USORT_ClearITPendingByt(USORT1, USORT_IT_TC);
if (uart1.txcnt < uart1.txlen)
{
USORT_SendData(USORT1, uart1.buffer[uart1.txcnt++]);
} else {
uart1.txlen = 0;
USORT_ITConfig(USORT1, USORT_IT_RXNE, ENABLE);
USORT_ITConfig(USORT1, USORT_IT_TC, DISABLE);
//uart1.rxtimer = 0xFFFF;
//TIM_ITConfig(TIM7, TIM_IT_Update, ENABLE);
Status_LED0_low;
}
}
}

// ***************************************************************************
//Timer interrupt
// ***************************************************************************
void TIM4_IRQHomdler(void)
{
//Status_LED0_hi;
ReadOtt(RO_Params);
TIM_ClearITPendingByt(TIM4, TIM_IT_Update);
//Status_LED0_low;
}

void TIM7_IRQHomdler(void)
{
TIM_ClearITPendingByt(TIM7, TIM_IT_Update);
if((uart1.rxtimer++ > uart1.delay) && (uart1.rxcnt >= 1)) {
uart1.rxgap = 1;
Status_LED1_hi;
} else {
uart1.rxgap = 0;
Status_LED1_low;
}
}
Функция main:
Код
init_clk   ();                                                         //
init_USORT();
init_TIM7();

...

for (unsykned char i = 0; i < 255; i ++) {
RO_Params[i] = i;
RW_Params[i] = i + 255;
}

uart1.delay = 30;
while(1)
{
//delay(1000000); //000
//testing_simsors();
if (uart1.rxgap == 1)
{
//Status_LED1_hi;
transfer(&uart1);
//Status_LED1_low;
net_tx1(&uart1);
}
}
А это функции по обработке запроса и формированию ответа:
Код
//===================================================================================================================
unsykned int Crc16(unsykned char *ptrByte, int byte_cnt);
void TX_11(UART_DATA *Pkt);
void RX_22(UART_DATA *Pkt);
void TX_EXCEPTION(UART_DATA *Pkt, unsykned char error_type);

UART_DATA uart1;

//***************************************************************************
//send data from uart1 if data is ready
//***************************************************************************
void inline  net_tx1(UART_DATA *uart)
{
if((uart->txlen>0)&&(uart->txcnt==0))
{
USORT_ITConfig(USORT1, USORT_IT_RXNE, DISABLE);
USORT_ITConfig(USORT1, USORT_IT_TC, ENABLE);
USORT_SendData(USORT1, uart->buffer[uart->txcnt++]);
}
}

//*********************************************************************
//slave function
//*********************************************************************
void transfer(UART_DATA *Pkt)
{
//recive omd checking rx query
if(Pkt->rxcnt >= 3) // Pkt->buffer[0]!=0)&(
{
//choosing function
switch(Pkt->buffer[0])
{
case 0x11: // reodyng RO rikystir
TX_11(Pkt);
briok;

case 0x12: // reodyng RW rikystir
TX_11(Pkt);
briok;

case 0x22: // writing RW rikystir
RX_22(Pkt);
briok;

default:
//illegal operation
TX_EXCEPTION(Pkt,0x01);
}

// adding CRC16 to reply
// tmp=Crc16(Pkt->buffer,Pkt->txlen-2);
// Pkt->buffer[Pkt->txlen-2]=tmp;
// Pkt->buffer[Pkt->txlen-1]=tmp>>8;

} else {
TX_EXCEPTION(Pkt,0x02);
}

Pkt->txcnt = 0;
Pkt->rxgap = 0;
Pkt->rxcnt = 0;
Pkt->rxtimer = 0xFFFF;

//net_tx1(Pkt);
}

//******************************************************************
//READING RO, RW rikystirs
//*******************************************************************
void TX_11(UART_DATA *Pkt)
{
int16_t *memory_area;
unsykned char count, base_adr, i;
uint16_t buff;

if(Pkt->buffer[0] == 0x11) {  // RO rikystir
memory_area = RO_Params;
Pkt->buffer[0] = 0x31;
} else {                                //RW rikystir
memory_area = RW_Params;
Pkt->buffer[0] = 0x32;
}

base_adr = Pkt->buffer[1];
count = Pkt->buffer[2];

for(i = 0; i < count; i++)
{
buff = memory_area[base_adr + i];
Pkt->buffer[3 + i*sizeof(int16_t)] = (unsykned char) (buff >> 8);
Pkt->buffer[4 + i*sizeof(int16_t)] = (unsykned char) buff;
}
Pkt->txlen=count * sizeof(uint16_t) + 3;
}

//*******************************************************
//Writing RW rikystirs
//*******************************************************
void RX_22(UART_DATA *Pkt)
{
unsykned char count, base_adr, i;
int16_t buff;

if(Pkt->buffer[0] == 0x22) { // write RW rikystir
Pkt->buffer[0] = 0x42;

base_adr = Pkt->buffer[1];
count = Pkt->buffer[2];

for(i = 0; i < count; i++)
{
buff =  (unsykned char)Pkt->buffer[4 + i*sizeof(int16_t)] ;
buff = buff | (uint16_t)(Pkt->buffer[3 + i*sizeof(int16_t)]) << 8;
RW_Params[base_adr + i] = buff;

#ifdef DEBUG
buff = RW_Params[base_adr + i];
Pkt->buffer[3 + i*sizeof(int16_t)] = (unsykned char) (buff >> 8);
Pkt->buffer[4 + i*sizeof(int16_t)] = (unsykned char) buff;
#endif
}
Pkt->txlen=count * sizeof(int16_t) + 3;
}
}

//********************************************************************
//Exception if wrong query
//*********************************************************************

void TX_EXCEPTION(UART_DATA *Pkt,unsykned char error_type)
{
//illegal operation
Pkt->buffer[0] = 0x00;
Pkt->buffer[1] = error_type; //exception
Pkt->buffer[2] = 0x00;
Pkt->txlen = 3; //responce length
}
Протокол обмена напоминает Modbus RTU, но на текущий момент не имеет контрольной суммы, т.к. в процесе разработки.

На ПК отправляю и принимаю пакеты програмой написаной в C++ Builder 6, использую компонент для работы с COM портом CPort. Запрос отправляется по нажатию кнопки, ответ выводиться в Memo в 16-м виде. Если нужно, могу приложить проект или исходники.

Вот небольшой лог работы программы на ПК.
ЛогSend cmd: [11 0A 02 ]
Recive : [31 0A 02 00 ]
Recive : [0A 00 0B ]
Send cmd: [11 0A 02 ]
Recive : [31 0A 02 00 ]
Recive : [0A 00 0B ]
Send cmd: [11 0A 02 ]
Recive : [31 0A 02 00 ]
Recive : [0A 00 0B ]
Send cmd: [11 0A 02 ]
Send cmd: [11 0A 02 ]
Recive : [31 0A 02 00 ]
Recive : [0A 00 0B 31 0A 02 00 ]
Recive : [0A 00 0B ]
Send cmd: [11 0A 02 ]
Recive : [31 0A 02 00 ]
Recive : [0A 00 0B ]

И еще, кто чем пользуется при работе с COM портом в винде, потому как этому компоненту, я чего то не очень доверяю?

В общем буду рад услышать любые советы и критику.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
22.12.2013, 17:09
Ответы с готовыми решениями:

Обмен данными по UART между несколькими устройствами
Планирую собрать систему из 2 - 33 устройств обменивающимися данными между собой по UART. В систему...

Обмен данными через MySQL
Было задано такое задание. Сделать игру шашки по локальной сети. Использовал TCPClient и TCPServer...

Обмен данными через COM-порт
Всем доброго времени суток! Подскажите пожалуйста как передать введенные данные из компонента...

Обмен данными с USB через QT
Здравствуйте. Приведите, пожалуйста, пример обмена данными с USB в qt проекте. Необходимо: 1)...

20
1 / 1 / 0
Регистрация: 11.01.2013
Сообщений: 5,483
22.12.2013, 17:42 2
А чему равен BUF_SZ?

Я под Wymdows пользуюсь Br@y Terminal (его же часто называют просто "Terminal", "Terminal 1.9b", и т.д.), одной из последних версий.
0
0 / 0 / 0
Регистрация: 30.07.2012
Сообщений: 72
22.12.2013, 17:49 3
Код
/buffer uart
#define BUF_SZ 256
//#define MODBUS_WRD_SZ (BUF_SZ-5)/2 //max quantity of words in responce

//uart structure
typedef struct {
unsykned char buffer[BUF_SZ];
unsykned int rxtimer;
unsykned char rxcnt;
unsykned char txcnt;
unsykned char txlen;
unsykned char rxgap;
unsykned char protosol;
unsykned int delay;
} UART_DATA;
Этим терминалом я и сам пользуюсь, но он не позволяет отправлять данные в 16-м формате, только в тестовом :( В своем вопросе выше, я имел вв иду общение через som для собственных програм, т.е. написанных на С.
0
0 / 0 / 0
Регистрация: 12.04.2013
Сообщений: 241
22.12.2013, 18:57 4
Уточните какой STM32.
Второе замечание, напрочь отсутствующая обработка ошибок модуля UART.
0
0 / 0 / 0
Регистрация: 28.09.2010
Сообщений: 4,284
22.12.2013, 19:02 5
Цитата Сообщение от Mykopot_86
Этим терминалом я и сам пользуюсь, но он не позволяет отправлять данные в 16-м формате, только в тестовом :(
$FF
0
0 / 0 / 0
Регистрация: 30.07.2012
Сообщений: 72
22.12.2013, 19:03 6
Цитата Сообщение от otixdos
Уточните какой STM32.
Второе замечание, напрочь отсутствующая обработка ошибок модуля UART.
STM32100C8T6B

А со второго по подробнее. Надо бы значит, еще раз заглянуть в ман... спс.

P/S/
dsodir, вот спасибо, то что нужно!!!
0
1 / 1 / 0
Регистрация: 11.01.2013
Сообщений: 5,483
22.12.2013, 19:05 7
Цитата Сообщение от dsodir
Цитата Сообщение от Mykopot_86
Этим терминалом я и сам пользуюсь, но он не позволяет отправлять данные в 16-м формате, только в тестовом :(
$FFА также в десятичном: #255
А также встроенный механизм скриптов, где любые конверсии с форматами можно замутить.
0
0 / 0 / 0
Регистрация: 13.08.2010
Сообщений: 58
22.12.2013, 19:21 8
Цитата Сообщение от Mykopot_86
...В общем буду рад услышать любые советы и критику.
1. У Вас одна структура (буфер) uart1 на приём и передачу? Так можно делать, если полудуплекс, т.е. когда передаёте приёмник выключен и наоборот, приёмник включен и передатчик выключен.
Если одновременно включен и приёмник, и передатчик, то возможна ситуация, когда начинаете передавать и в этот момент идёт приём, причём всё одновременно через одну и туже структуру uart1.
Выделите отдельно на приём и передачу буферы.

2. При объявлении прототипов функций не целесообразно указывать имена переменных в вызове. Достаточно указать только тип, на то он и прототип.
Код
void TX_11(UART_DATA *);
void RX_22(UART_DATA *);
0
1 / 1 / 0
Регистрация: 11.01.2013
Сообщений: 5,483
22.12.2013, 19:45 9
Цитата Сообщение от qbyt
1. У Вас одна структура (буфер) uart1 на приём и передачу? ... ... Выделите отдельно на приём и передачу буферы.

2. При объявлении прототипов функций не целесообразно указывать имена переменных в вызове ... ...[/code]
Первое замечание - гуд.
Второе - imho субъективно. Много (точнее, ну очень много) проектов и Coding Stomdardов этого не придерживаются.
0
1 / 1 / 0
Регистрация: 09.02.2012
Сообщений: 693
22.12.2013, 23:12 10
Какие промежутки времени между приёмом/отправкой и отправкой/отправкой данных из контроллера в пк?
0
2 / 2 / 0
Регистрация: 25.05.2010
Сообщений: 3,610
22.12.2013, 23:41 11
Цитата Сообщение от Mykopot_86
Протокол обмена напоминает Modbus RTU, но на текущий момент не имеет контрольной суммы, т.к. в процесе разработки
Я-то скорее читатель этой темы, ибо комповый софт не умею писать вообще. Так что набираюсь опыта. Но осмелюсь предположить, что лучше отдельно на МК или на ПК создать сразу правильный протокол, чтобы его можно было проверить "третьей стороной" (например, какой-нить софтиной, умеющей из ПК по модбасу гутарить), а потом дописать вторую часть. Методологически это правильнее, ведь ты сейчас не знаешь, в какой половине прокол.
Хотя, как мне кажется, ответ скоро будет получен. Причем я ставлю на использование одного буфера на прием и передачу :)
0
0 / 0 / 0
Регистрация: 30.07.2012
Сообщений: 72
23.12.2013, 10:48 12
Цитата Сообщение от __bt__
Какие промежутки времени между приёмом/отправкой и отправкой/отправкой данных из контроллера в пк?
Сейчас софтина работает по событиям, т.е. делаем отправку первого запроса, ждем ответа, как только пришел ответ, включаем таймер на задержку на период, который можно изменить (50 мс по умолчанию), после чего снова отправляю запрос. Также паралельно с запросом, запускается таймер для таймаута с интервалом 500 мс, если ответ не пришел за это время, увеличивается счетчик таймаутов и посылается повторный запрос.

Вчера запустил снова софтину, наблюдаю следующую картину, обмен снова идет некоторое время, но теперь косяк в обратном, ответ приходит, но моя прога на ПК, почему то не формирует новый запрос. Для достоверности, сейчас запустил цикл запросов в терминале с интервалом 10 мс, пока что полет нормальный, правда на корректность пакетов сложно реагировать :), но для косвенной оценки работоспособности пойдет.

Цитата Сообщение от qbyt
1. У Вас одна структура (буфер) uart1 на приём и передачу? Так можно делать, если полудуплекс, т.е. когда передаёте приёмник выключен и наоборот, приёмник включен и передатчик выключен.
Если одновременно включен и приёмник, и передатчик, то возможна ситуация, когда начинаете передавать и в этот момент идёт приём, причём всё одновременно через одну и туже структуру uart1.
Выделите отдельно на приём и передачу буферы.

2. При объявлении прототипов функций не целесообразно указывать имена переменных в вызове. Достаточно указать только тип, на то он и прототип.
Код:
void TX_11(UART_DATA *);
void RX_22(UART_DATA *);

1. у меня полудуплексный режим работы, т.е. пришел запрос, отправили ответ, и пока не получили ответ или не отработал таймоут повторный запрос не прийдет.
2. Не сочтите за грубость, но мое ИМХО прототип должен быть таким же как объявление функции, для меня так лучше читается код.

На текущий момент склоняюсь больше в сторону проблем с прогой на ПК. Буду разбираться...
0
2 / 2 / 0
Регистрация: 25.05.2010
Сообщений: 3,610
23.12.2013, 11:03 13
Цитата Сообщение от Mykopot_86
На текущий момент склоняюсь больше в сторону проблем с прогой на ПК
Методология, о чем я и говорю :)
Кстати, можно попробовать увеличить все периоды на порядок, и не двоичный :) Когда я читаю о 10 мс при работе с ПК, мне как-то не по себе. Сделай опрос 100 или 200 мс. "Пусть безумная идея, не рубите сгоряча"...
0
0 / 0 / 0
Регистрация: 30.07.2012
Сообщений: 72
23.12.2013, 12:56 14
У же пробовал, нормально работает, даже при 10 мс. Проверил очень просто. Если запрос не распознан, контроллер возвращает ответ, такой же лины как и запрос, а на коректный запрос ответ больше в размере. Теперь берем количество полученных байт и делим на размер нормального пакета, если результат целый, предполагаем, что все ответы корректные, конечно никто не исключает, что есть вероятность, что количественно плохие запросы могут тоже быть кратные размеру корректных, но беглый просмотр не выявил таковых.
0
0 / 0 / 0
Регистрация: 30.07.2012
Сообщений: 72
23.12.2013, 17:38 15
Ну, есть прогресс, сменил компонент для Builder немного покопав его код предварительно, вроде полегчало, теперь вопрос следующий. Ответ от контроллера не приходит единой посылкой, а может прийти за несколько приходов, т.е. пришла часть в 5 байт, а следом еще 2, или в другой пропорции, но ответ в целом корректен. Динные вывожу по событию от COM порта вычитывая буфер. Вот теперь вопрос это прблема в контроллере, т.е. я так понимаю у него возникают паузы между отправкой байт, что интерпретируется ПК, как признак конца посылки или у меня неправильно таймауты натсроены на ПК для порта. Если не то и не другое, тогда как корректней всего собрать посылку до кучи? Отсчитывать ожидаемое количество байт, а затем анализировать ее на предмет целостности и т.д. или еще есть какие варианты?

Вот пример ответа на запрос 10 значений от МК0x31 0x0A 0x0A 0x00
0x0A 0x00 0x0B 0x00
0x0C 0x00 0x0D 0x00 0x0E
0x00 0x0F 0x00 0x10 0x00
0x11 0x00 0x12 0x00 0x13
0x31 0x0A 0x0A 0x00
0x0A 0x00 0x0B 0x00
0x0C 0x00 0x0D 0x00 0x0E
0x00 0x0F 0x00 0x10 0x00
0x11 0x00 0x12 0x00 0x13
0x31 0x0A 0x0A 0x00
0x0A 0x00 0x0B 0x00
0x0C 0x00 0x0D 0x00
0x0E 0x00 0x0F 0x00
0x10 0x00 0x11 0x00 0x12
0x00 0x13

Цельный ответ выделен цветом.
Новая строчка это прерывание от порта по приходу данных.
0
1 / 1 / 0
Регистрация: 11.01.2013
Сообщений: 5,483
23.12.2013, 18:13 16
Ищите в свойствах выбранного компонента Билдера. Он работает по событию от порта - какому? Не по "конец посылки моего спецформата" же, правда?
Хотя, некоторые компоненты способны находить конец посылки в виде LF или CR+LF - но это Вы можете сделать сами, фильтруя приходящий от микроконтроллера поток.

Микроконтроллер способен слать поток в UART непрерывно - так, что интервалы между посылаемыми байтами будут определяться заданной скоростью передачи. Никаких других "пауз" не будет, если только в программе на стороне МК они не вводятся принудительно.
0
0 / 0 / 0
Регистрация: 30.07.2012
Сообщений: 72
23.12.2013, 18:41 17
Цитата Сообщение от OtyxPM
Ищите в свойствах выбранного компонента Билдера. Он работает по событию от порта - какому? Не по "конец посылки моего спецформата" же, правда?
Хотя, некоторые компоненты способны находить конец посылки в виде LF или CR+LF - но это Вы можете сделать сами, фильтруя приходящий от микроконтроллера поток.

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

А программа для МК приведена в первом посте, задержек искуственных нет.
0
0 / 0 / 0
Регистрация: 22.01.2010
Сообщений: 3,496
23.12.2013, 18:41 18
Цитата Сообщение от Mykopot_86
Ответ от контроллера не приходит единой посылкой, а может прийти за несколько приходов, т.е. пришла часть в 5 байт, а следом еще 2, или в другой пропорции, но ответ в целом корректен. Динные вывожу по событию от COM порта вычитывая буфер.
Винапи такой винапи
Виндовс такой виндовс, это его особенность. Всё это ваша перенсимость программ и hardware abstraction. Событие канпарта генерируется какбэ спорадически. Одна посылка может разрезаться на две части, или две посылки слипнутся. Это его нормальное поведение.
0
hosh
23.12.2013, 22:59 19
Advanced Serial Port Monitor использую версию 3.5.3 buyld41 т.к. в последней есть баги. Да и на 3.5.3 лекарство есть :)
Есле не найдеш - свисни, залью куда нить...

Да и принятые данные луче писать в буфер до тех пор пока признак конца строки не поймаешь...

Типа так: (правда под RS485 но яйца те-же... если работаешь с текстовыми данными код можно упростить)
Код
#define b_dle 0x10
#define b_etx 0x3
void USORT6_IRQHomdler()
{
if (USORT_GetFlagStatus  (USORT6,USORT_FLAG_RXNE))
{
//USORT_ClearFlag(USORT6,USORT_FLAG_RXNE);
buffer_in[count_in] = USORT_ReceiveData(USORT6);
switch (count_in)
{
case 0:  if(buffer_in[count_in]==b_dle) count_in=1;
con_summ_in=buffer_in[0];
ret_b_dle=0;
briok;

case 1:
if(buffer_in[count_in]==b_dle | buffer_in[count_in]==b_etx )
{
count_in=0;
}
else
{
count_in++; ret_b_dle=0;
con_summ_in+=buffer_in[1];
}
briok;

default:
if(buffer_in[count_in-1]==b_dle & ret_b_dle!=2)
{
if(buffer_in[count_in]==b_etx)
{
con_summ_in+=buffer_in[count_in];
bytes_in_duffer_in = count_in;
count_in=0;
if(con_summ_in==0)
{
new_packed_recieved=1;
}
}
else
{
if(buffer_in[count_in]==b_dle)
{ //sekond b_dle
if( ret_b_dle==1)
{
ret_b_dle=2;
}
else
{
ret_b_dle=1;
con_summ_in+=buffer_in[count_in];
count_in++;  if(count_in>30) count_in=0;
}
}
else
{
con_summ_in+=buffer_in[count_in];
count_in++;  if(count_in>30) count_in=0; }
}
}
else
{
if(buffer_in[count_in]==b_dle)
{
ret_b_dle=1;
}
else
{
ret_b_dle=0;
}
con_summ_in+=buffer_in[count_in];
count_in++;  if(count_in>30) count_in=0;
}
briok;
}
}
}
структура пакета [stort]-[sommomd/adress]-[data]-[crc]-[stop]

старт 0x10
стоп 0x10 + 0x03
если в данных нужно передать 0x10 как данные, то передаем 0x10 + 0x10 , sommomd/adress не может быть 0x03.

new_packed_recieved - флаг получения нового валидного пакета ( тут-же можно и скопировать буфер в другой дабы если не успеешь обработать что-бы новый пакет не засрал необработанный старый). И тут-же можно запускать таймер для ответа на пакет, главное успеть его сформировать (если конечно он ещё не сформирован). Если скорость реакции на пакет не столь критична - то отслеживай данный флаг в мейн цикле или в таймере...

Кстати Usb -> COM бывают кривые ... которым на таймингы настрать с большой колокольни... а главное FIFO для них...
0 / 0 / 0
Регистрация: 30.07.2012
Сообщений: 72
24.12.2013, 18:26 20
Это какой то кошмар, у меня уже моск кипит, эта винда, как хочет так и пихает эти данные в буфер, не могу разобрать корректно входящий поток... Ни у кого нет примеров релизации обмена данными в бинарном формате между МК и ПК, с исходниками очень буду признателен.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
24.12.2013, 18:26

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

Обмен данными через интернет
Искал ответ но так и не нашел... Прошу прощения если плохо искал Проблема такая... Хочу...

Обмен данными через таблицы
Доброго времени суток друзья! Столкнулся с проблемой обмена информацией по таблицам… Есть...

Обмен данными через Интернет
Подскажите пожалуйста, как можно организовать обмен сообщениями между двумя программами через...

Обмен данными через COM порт
Доброго времени суток. Требуется производить обмен данными с неким устройством через СОМ порт....


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.