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

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 так вместе с данными отправляются еще служебные символы.

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

 

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

Особенности хранения литиевых аккумуляторов и батареек

Потеря емкости аккумулятора напрямую зависит от условий хранения и эксплуатации. При неправильном хранении даже самый лучший литиевый источник тока с превосходными характеристиками может не оправдать ожиданий. Технология, основанная на рекомендациях таких известных производителей литиевых источников тока, как компании FANSO и EVE Energy, поможет организовать правильный процесс хранения батареек и аккумуляторов. Подробнее>>

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@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 пользователей онлайн

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

    • Хорошо, что информация в статье говорит о многослойной катушке намотанной лентой из изолированных жил, расположенных в одной плоскости? Мне бы больше помогла не статья, а представление магнитного поля этой ленты. Да, будет эффект близости, когда ток съедет еще и к низу проволок полумесяцем. Наверное, в центральных жилах будет меньшая плотность тока, т.к. они будут пронизываться магнитным полем остальных проволок в большей степени, чем крайние проволоки. Но стоит подумать о потокосцеплении, или как там правильно называется, взаимоиндукции что ли? То есть, надо ли рассматривать магнитное поле каждой отдельной проволоки, или всей ленты сразу, то есть, будет ли поле обтекать эту ленту вокруг перпендикулярного сечения? Вообще, если исходить из принципа суперпозиции магнитного поля, то надо рассматривать поле каждой проволочки отдельно.  
    • Походу рекомендованную статью вы проигнорировали...
    • А я считал навивку сердечника выходника из пермаллоевой проволоки (что то типа самодельного r-core) странным занятием сумрачного гения  Разориться на феррите можно в процессе угадывания концентрации)
    • Проект фотоаппарата мгновенной печати на ESP32 Cam. Фото ESP32 печатается из браузера на WI-FI принтер Ссылка на статью: //cxem.net/arduino/arduino281.php Автор статьи: //cxem.net/profile/56/
    • Не нравится лампа постоянно подключённая в 21w, подключите её через реле поворота. А зачем нам тут городить огород да ещё и с реле поворота? Через реле - 5 контактов где есть нормально замкнутые контакты. В паузе - тухнет красный светодиод, реле тоже отключается, замыкая резистор на разряд. Пошёл импульс заряда - засветился красный светодиод - реле сработало, разомкнуло цепь на резистор. Но я хотел бы по красивее, на транзисторах вместо реле. Нужно просто найти способ включить транзистор в период паузы. Либо на этом компараторе искать сигнал, либо второй поставить.  
    • Я уже выяснил что не уменьшится, а значительно увеличится. Вот если эту ленту разрезать вдоль на много отрезков. Другими словами, можно взять много эмалированных проводком параллельно, они будут представлять что-то типа сепарированной ленты. Но я прикинул трудозатраты и плюнул на это дело. Если подумать, добротность может упасть только за счет снижения Z, или за счет увеличения R. Если уменьшится нагрев, то добротность тоже возрастет, конечно при условии, что емкость при этом останется на прежнем уровне. Часто слышу про межвитковую емкость. Сунут ее де не попадя. Надо понимать, что, если на катушке падает незначительное напряжение и длина ходя бы полуволны больше длины провода из которого состоит катушка, то можно забыть про межвитковую емкость. Катушка будет представлять из себя уединенную емкость цилиндра. Помноженную на коэффициент равный обратному отношению площади прямоугольника к площади полусинусоиды, вписанной в этот прямоугольник. Это константа, по-моему равная π/2.
    • Свернуть в ТОР, чтобы меньше излучала и ослабилось влияние на саму катушку, особенно если вы хотите поместить ее в стальной экран. Мотать медной лентой – не лучшая идея, нагрев может и уменьшится, но добротность будет хуже и вырастут габариты. Попробуйте все тот же жгут, стараясь его сделать более плоского профиля. Отдельный вопрос – повышение магнитной проницаемости. Кроме пропиленного кольца, которое непросто найти необходимого размера и материала, можно поэкспериментировать с самодельным композитом. Растолочь ВЧ феррит и смешать с измельченным стеклом с добавлением клея. Из этой массы сформовать бублик для будущего ТОРа. Главное угадать с концентрацией феррита, чтоб не переборщить. 
×
×
  • Создать...