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

Cинхронизация МК с компьютером по UARTу


Kostyanskiy

Рекомендуемые сообщения

Здравствуйте, мне надо как-то синхронизировать работу МК с компьютером, идея такая:

Отсилаю кодовое слово по UART на МК, и МК уже посилает в ответ данные на соответствующее кодовое слово

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

Я пробивал и через Terminal v1.9, но ситуация такая же...

Вот код МК:

while (!(PIND & (1<<SET_APM_UART_MODE))) //нажата кнопка, пин на минусе
    {
        if (strcmp((const char*)sReceivedChar, "CH_STS") == 0) // Парсинг кодового слова
        {
            UART_Transmit("OK"); //Ответ
        }
    }

И принимающая часть:

ISR(USART_RX_vect)
{   
         sReceivedChar[rx_count++] = UDR0;
         if (rx_count > sizeof(sReceivedChar)) rx_count = 0;
}

---В програме отсилка кодового слова была только один раз, а данные пришли дважды, что не так?---

image.png.8304800e2b6343b6a2f642f4611696fe.png

 

 

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

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

Замкните RX TX и отправьте данные в терминале, посмотреть что терминал отправляет. Попробуйте снять галку +CR так вместе с данными отправляются еще служебные символы.

Изменено пользователем elki
Ссылка на комментарий
Поделиться на другие сайты

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

2 минуты назад, elki сказал:

Замкните RX TX и отправьте данные в терминале, посмотреть что терминал отправляет. Попробуйте снять галку +CR так вместе с данными отправляются еще служебные символы.

Снял галочку и данные данные пошли непрерывным потоком, переподключил устройство, выдало все как на кратинке выше. Все пришло в тупик...

 

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

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

On 7/16/2022 at 10:39 PM, Kostyanskiy said:

Снял галочку и данные данные пошли непрерывным потоком,

Приемный буфер надо чистить, после того, как послали ответ.

Да и так могут быть проблемы, если посылать будите строку старт в самом конце буфера.

Часть строки будет в конце, часть в начале буфера.

Поменяйте алгоритм, начало посылки просто один символ.(которого точно не будет в посылке)

Читаете символ, если это не символ начала, игнорируете его.

Если поступил символ начала, читаете заданное колличевсто символов после него или все до символа конца.(которого точно не будет в посылке)

нп. символ старта >

       символ конца <

Изменено пользователем codenamehawk
Ссылка на комментарий
Поделиться на другие сайты

@codenamehawk Я уже решил проблему, да, я так и поступил, спасибо, отслеживаю по 0x0D или "/r" в конце, этого хватает 

ISR(USART_RX_vect) //Прерывания после приема
{   
    if ((UCSR0A & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN)) == 0)
    {
       char UDR = UDR0;
       
       if (UDR != 0x0D)
       {
           sReceivedChar[rx_count] = UDR;
           if (rx_count < sizeof(sReceivedChar) - 1) ++rx_count;
       }
       else
       {
           sReceivedChar[rx_count] = 0;
           rx_count = 0;
           FlagRecievData = 1;
       }
    }
}

Теперь немного другая проблема - связь с ПК.

Проблема с приемо-передачей по UART.
Работаяю я в Visual Studio CLI/C++


После открытия порта включаю девайс подключенный к этому порту через USB-COM адаптер на CH-340. При запуске програми на ПК, она шлет в порт просьбу отослать вот этот код: например - "OK" и если получает его, то можно работать дальше.

Проблема в том, если выполнять этот код без остановок при отладке: то ПК либо не получает код от девайса, то девайс не получает код, то ПК не получает ответ на код.

while (!(strcmp(dataReceive, "OK") == 0))
{
       COM_PORT_WRITE("CH_STS\r");                 
       COM_PORT_READ(dataReceive);
}

ПК отсылает "CH_STS", устройство должно ответить "OK"

Внутри этих функций вот:

void COM_PORT_WRITE(char* dataTransmit)
{
    memcpy(data, dataTransmit, sizeof(data));
    WriteFile(COM_PORT, data, dwSize, &dwBytesWritten, NULL);
}
 
void COM_PORT_READ(char *dataReceived)
{
    ReadFile(COM_PORT, &sReceivedChar, sizeof(sReceivedChar), &iSize, 0);       
    if (iSize > 0)
    {
        memcpy(dataReceived, sReceivedChar, sizeof(sReceivedChar));
    }       
}


В терминале COM порта все работает отлично, как мне сингронизироваться?

image.png.c403e226166b4e4980bcfcaaf7d3995c.png

Изменено пользователем Kostyanskiy
Ссылка на комментарий
Поделиться на другие сайты

16 hours ago, Kostyanskiy said:

Я уже решил проблему, да, я так и поступил, спасибо, отслеживаю по 0x0D или "/r" в конце, этого хватает 

Хотя бы для отладки, стоит, перед очисткой буфера, собрать информацию:

как часто появляются ошибки приема

а успел ли мк обрабатать принятую информацию

Изменено пользователем codenamehawk
Ссылка на комментарий
Поделиться на другие сайты

В 21.07.2022 в 22:17, Огонёк сказал:

Получился указатель на указатель.

А оно что так, что так не работает...

 

Я сейчас тестирую программу на ПК из USB-COM адаптером на CH-340, и пока ничего не выходит, нашел одну статейку, как перевести COM порт в асинхронный режим "overlapped", сделал все как в статте, на WINAPI, и чего-то не фурычит.

Вот статья https://studfile.net/preview/1506844/

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

DWORD WINAPI ReadThread(LPVOID)
{
	overlapped.hEvent = CreateEvent(NULL, true, true, NULL); //создать сигнальный объект-событие для асинхронных операций
	SetCommMask(COM_PORT, EV_RXCHAR); //установить маску на срабатывание по событию приёма байта в порт
	while (1) //пока поток не будет прерван, выполняем цикл
	{
		WaitCommEvent(COM_PORT, &mask, &overlapped); //ожидать события приёма байта (это и есть перекрываемая операция)
		signal = WaitForSingleObject(overlapped.hEvent, INFINITE); //приостановить поток до прихода байта
		if (signal == WAIT_OBJECT_0) //если событие прихода байта произошло
		{
			if (GetOverlappedResult(COM_PORT, &overlapped, &temp, true)) //проверяем, успешно ли завершилась перекрываемая операция WaitCommEvent
				if ((mask & EV_RXCHAR) != 0) //если произошло именно событие прихода байта
				{
					ClearCommError(COM_PORT, &temp, &comstat); //нужно заполнить структуру COMSTAT
					btr = comstat.cbInQue; //и получить из неё количество принятых байтов
					if (btr) //если действительно есть байты для чтения
					{
						ReadFile(COM_PORT, DataReceived, BUFF_SIZE, &iSize, &overlapped); //прочитать байты из порта в буфер программы					
					}
				}
		}
	}
	CloseHandle(overlapped.hEvent); //перед выходом из потока закрыть объект-событие
}	
	
void COM_PORT_READ(char* data)
{
	memcpy(data, DataReceived, BUFF_SIZE);
}

В отладке, у меня все стопорится на этой точке ReadFile(COM_PORT, DataReceived, BUFF_SIZE, &iSize, &overlapped); и btr принимает вообще рандомные значения 

Изменено пользователем Kostyanskiy
Ссылка на комментарий
Поделиться на другие сайты

23 минуты назад, Kostyanskiy сказал:

А оно что так, что так не работает...

Ну да, так и есть. Что указатель на переменную, что указатель на указатель - какая разница! Кому какое дело, что за данные мы передаём в функцию. Что там, что тут - непонятная шаманская бормотуха, верно?

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

39 минут назад, Kostyanskiy сказал:

А оно что так, что так не работает...

Жесть. Как можно писать код и не понимать, что ты пишешь ? На что можно надеяться ?

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

14 часов назад, Огонёк сказал:

Что там, что тут - непонятная шаманская бормотуха, верно?

13 часов назад, Alex сказал:

Жесть. Как можно писать код и не понимать, что ты пишешь ? На что можно надеяться ?

Этот код правился и дорабатывался безчисленное количество раз, и так как проект старый, помнить где какие ошибки я не могу, и я не сразу обратил внимание на ваше @Огонёк замечание. Я не помню всего что делал довольно давно, и не могу сказать зачем делал указатель на указатель.

 

P.S: Наверное тогда я принимал только один байт, и у меня буфер sReceivedChar не был масивом

Изменено пользователем Kostyanskiy
Ссылка на комментарий
Поделиться на другие сайты

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

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

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

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

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

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

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

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...