Поскольку, почему-то, просят воздерживаться от использования ярких, образных, деперсонифицированных, но адекватных выражений, описывающих происходящее в этой теме, то предлагаю ТС для осмысления взглянуть на концепцию организации ввода-вывода через последовательные интерфейсы, которой я пользуюсь уже не один год. Кое-что было подсмотрено у Адвантека, врать не буду. На этой базе работают UART, USB, Ethernet под FreeRTOS, MiniOS7, ROM-DOS, Windows. Спойлер
//---------- // В STM32 последовательный порт может работать как в терминальном // режиме, обрабатывая каждый принятый и отправленный символ, так и в // блочном режиме по Модбас-подобным протоколам, используя ДМА и обмен // блоками данных. Поэтому определяем как методы для посимвольного // ввода-вывода, так и методы для блочного. В наследника наполним их // смыслом, применительно к способу использования конкретного порта.
//---------- // Копирует принятые байты из буфера приёмника физического порта // в буфер buff размером buffSize принятые байты. Возвращает число // скопированных байтов. // В случае ошибки возвращает отрицательное число. virtual int16 receive ( void* buff, int16 buffSize, MODE mode = NON_BLOCK ) = 0;
//---------- // Записывает в буфер передатчика физического порта из буфера // buff пользователя buffSize байт. Метод не проверяет наличие // в буфере передатчика не отправленных с прошлого вызова send байтов! // Метод не дожидается окончания отправки всех байтов из buff, // а возвращает управление в точку вызова сразу же, как только // последний байт из числа buffSize будет записан в буфер передатчика! virtual int16 send ( void* buff, int16 buffSize, MODE mode = NON_BLOCK ) = 0;
//---------- // Метод реализует отправку сообщения из буфера и приём ответа // в этот же буфер. Во время работы метода будут недоступны // и передатчик, и приёмник. // Метод предназначен для реализации эффективного поллинга // по проотоколу Modbus и ему подобным протоколам типа ведущий-ведомый. virtual int16 sendAndReceive ( void* buff, // Рабочий буфер int16 tx_n, // Количество байт для отправки. int16 rx_n, // Количество байт для приёма. int16 timeout // Таймаут для приёма ответа ) { return( 0 ); };
Добавлено after 4 minutes 22 seconds: Почему Дюдюка жадный.Я допустем если человек не знает .А я знаю.Обьязательно поделюсь.С собой знания не уйдут.Они должны передаватся человек к человеку.
Не жадный. Его утомило то, что вы не пользуетесь кодом, который вам дают, а так же не хотите включить голову. Возврат коретки - это ДВА СИМВОЛА в конце строки. ВСЁ. Что нужно, чтобы сделать функцию с переносом строки, если есть функция БЕЗ переноса строки? Добавить в функцию БЕЗ переноса строки код, который будет добавлять перенос строки перед выходом.
На примере моего его кода это бы выглядело так:
Код:
void console_put(char *text); // Используем прототип моей же фукнции из одного из спойлеров в теме. (Либо в соседней теме) void console_put_crlf(char *text) { console_put(text); // Передаём указатель на строку, которую нам дали console_put("\r\n"); // Добавляем перенос строки, используя ТУ ЖЕ ФУНКЦИЮ. };
Ещё в старом-добром ZX Spectrum были понятия каналов и потоков, что делало абсолютно безразличным, куда ты пишешь строку оператором "PRINT". Я уж не говорю про нынешний С++ с его iostream. Так что, пардон, но не зачётный наезд.
Да, код подобен. В первом блоке кода - то, что написал я. Во втором - то, что написали Вы.
Преобразовать куда? Зачем? Во что? Все астрологи празднуют китайский новый год. Пишите ПОНЯТНО. Потому что сейчас вопросов больше, чем ответов.
Что такое tx_uart1? Функция, кладущая данные в UART1->DR? Если так - то это НЕ DMA. DMA - это работа с буферами. То, что Вы привели - PIO обмен. Processos Input Output.
uint8_t len =* string ; int i=0; while (string[i]) {
i++;
} Usart1_send((uint8_t*) "\r\n", len); }
Вот работает но не так.в строке 2 раэа повторяется.?
А теперь разберём ВАШ код построчно.
Код:
uint8_t len =* string ;
Это вообще что? Получение указателя на строку в переменную размером 1 байт?
Код:
int i=0; while (string[i]) { i++; }
Считаем длину строки. Хорошо, можно так.
Код:
Usart1_send((uint8_t*) "\r\n", len);
Передаём в Usart1_send() УКАЗАТЕЛЬ(!) на "\r\n". Хорошо. Хотя компилятор обычно заботится об этом сам. И len. Что в len? Ноль? Первый символ? На указатель не тянет. Значение счётчика нигде не используется.
Рекомендую включить в Вашей IDE режим -pedantic и исправлять код до тех пор, пока в выводе не исчезнут даже предупреждения компилятора. Собственно, у себя в коде я делаю похожим образом. Разве что уровень сообщений об ошибках чуть ниже ставлю.
Этот код выводит два раза в строку.У меня вопрос.Как то вы прговорились.Что эта работа с буферами?Там в этом коде сколько должно быть буферов .Я думаю два.Может я не прав ?
[uquote="ivan dimir",url="/forum/viewtopic.php?p=4174881#p4174881"]А теперь разберём ВАШ код построчно.
Код:
uint8_t len =* string ;
Это вообще что?
Он получает значение первого элемента строки, к примеру строка "hello", в переменную len заносится первый элемент, то есть 'h', или в десятичном 104. Потом отправляет его
Код:
DMA2_Stream7->NDTR = len;
, а что там у него во флеш лежит после "hello" ... кто его знает. ivan dimir, ты отладчиком пользоваться умеешь?
Интересно как на перфокартах программу отлаживали? Современные IDE предоставляют такие возможности, IAR вообще позволяет в режиме отладки и код программы корректировать. Для AVR писали, не у всех полноценный отладчик был, протеусом пользовались. А тут ... без комментариев.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 17
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения