Кто любит RISC в жизни, заходим, не стесняемся.
Ответить

Re: stm32f4 usart+DMA

Чт фев 03, 2022 23:05:59

Ребята, давайте поаккуратнее с выражениями ! Не на базаре находитесь !

Re: stm32f4 usart+DMA

Пт фев 04, 2022 12:27:01

Поддерживаю модерратора.Эх жаль меня забанили на паяльнике.

Добавлено after 4 hours 29 minutes 16 seconds:
У меня вопрос.Как можно сделать функцию по отправке по ДМА с возвратом коретки
Спойлер
Код:
void Usart1_send( uint8_t*data, uint16_t len)
{
 uint8_t i=0;
 
DMA2_Stream7-> CR &=~ DMA_SxCR_EN;         //wait transmit all data
 //DMA2->HIFCR |= DMA_HIFCR_CTCIF7;               //clear flag transmit
 for(i = 0; i < len; i++)

{
         txData[i]= *data++;
         //copy data to buff
       //  *data++;
        // i++;
        // i=len;
      }
 //
 DMA2_Stream7->NDTR = len;                      //Set len
 DMA2_Stream7->CR |= DMA_SxCR_EN;                 //enable DMA
}

Re: stm32f4 usart+DMA

Пт фев 04, 2022 14:03:11

Поскольку, почему-то, просят воздерживаться от использования ярких, образных, деперсонифицированных, но адекватных выражений, описывающих происходящее в этой теме, то предлагаю ТС для осмысления взглянуть на концепцию организации ввода-вывода через последовательные интерфейсы, которой я пользуюсь уже не один год. Кое-что было подсмотрено у Адвантека, врать не буду. На этой базе работают UART, USB, Ethernet под FreeRTOS, MiniOS7, ROM-DOS, Windows.
Спойлер
Код:
////////////////////////////////////////////////////////////////////////////////
//
//      AbsTrans.h
//
////////////////////////////////////////////////////////////////////////////////

#pragma once

#ifndef __ABSTRACT_TRANSPORT_H__
#define __ABSTRACT_TRANSPORT_H__

#include "MyTypes.h"

////////////////////////////////////////////////////////////////////////////////

#define TRANSPORTS_NAME_LEGHT   16

////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////

class AbstractTransport
{
    public:
   
        enum MODE
        {
            BLOCK     = 0,
            NON_BLOCK = 1
        };

        //----------
        //      В STM32 последовательный порт может работать как в терминальном
        // режиме, обрабатывая каждый принятый и отправленный символ, так и в
        // блочном режиме по Модбас-подобным протоколам, используя ДМА и обмен
        // блоками данных. Поэтому определяем как методы для посимвольного
        // ввода-вывода, так и методы для блочного. В наследника наполним их
        // смыслом, применительно к способу использования конкретного порта.

        //----------
        //      Очистка буферов приёмника и передатчика.
        virtual void purgeRxBuff( void ) = 0;
        virtual void purgeTxBuff( void ) = 0;

        //----------
        //      Копирует принятые байты из буфера приёмника физического порта
        // в буфер 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 ); };

        //----------
        //      Возвращает количество оставшихся в буфере физического
        // передатчика неотправленных байт.
        //      Реализация наследников должна обеспечивать правильную работу
        // следующей конструкции:
        //
        //  if( getAvailableTxBytes() == 0 )
        //      send( buff, buffSize );
        //
        virtual int16 getAvailableTxBytes( void ) = 0;

        //----------
        //      Возвращают количество байт в буфере приёмника.

        virtual int16 getAvailableRxBytes( void ) = 0;

        //----------
        //      Методы-заглушки для поддержки посимвольного ввода-вывода.

        virtual int16 putChar( int16 c ) = 0;
        virtual int16 getChar( void ) = 0;
        virtual bool  peekChar( int16* c ){ return( false ); }

        virtual int16 putString( const char* str ) = 0;

        //----------
        //

        virtual void enableReceiving( void ){};
        virtual void disableReceiving( void ){};

        //----------
        //      Печать диагностической информации об объекте.
       
        virtual ostream& print( ostream& os );
       
        friend ostream& operator << ( ostream& os, AbstractTransport& );
       
        //----------
       
    protected:

        AbstractTransport( const char* name );
        virtual ~AbstractTransport( void );

        char name[ TRANSPORTS_NAME_LEGHT ];
};

////////////////////////////////////////////////////////////////////////////////
#endif  // __ABSTRACT_TRANSPORT__
////////////////////////////////////////////////////////////////////////////////

Re: stm32f4 usart+DMA

Пт фев 04, 2022 14:21:26

Можно ещё у модератра спросить.

Re: stm32f4 usart+DMA

Пт фев 04, 2022 14:34:40

Можно ещё у модератра спросить.
А у Дюдюки?

Добавлено after 4 minutes 22 seconds:
Почему Дюдюка жадный.Я допустем если человек не знает .А я знаю.Обьязательно поделюсь.С собой знания не уйдут.Они должны передаватся человек к человеку.

Re: stm32f4 usart+DMA

Пт фев 04, 2022 15:05:27

У меня вопрос.Как можно сделать функцию по отправке по ДМА с возвратом коретки

Псевдокод ниже:
Код:
void console_put(char *text) {
 i = 0;
 while (*text) {
  Some_Write_Buffer[i++] = *text;
  text++;
 };
 Some_Write_Buffer[i++] = '\r';
 Some_Write_Buffer[i++] = '\n';
 DMA_SendBuffer(i);
};


ivan dimir писал(а):Почему Дюдюка жадный

Не жадный. Его утомило то, что вы не пользуетесь кодом, который вам дают, а так же не хотите включить голову.
Возврат коретки - это ДВА СИМВОЛА в конце строки. ВСЁ.
Что нужно, чтобы сделать функцию с переносом строки, если есть функция БЕЗ переноса строки?
Добавить в функцию БЕЗ переноса строки код, который будет добавлять перенос строки перед выходом.

На примере моего его кода это бы выглядело так:
Код:
void console_put(char *text); // Используем прототип моей же фукнции из одного из спойлеров в теме. (Либо в соседней теме)
void console_put_crlf(char *text) {
 console_put(text); // Передаём указатель на строку, которую нам дали
 console_put("\r\n"); // Добавляем перенос строки, используя ТУ ЖЕ ФУНКЦИЮ.
};

Это когда лень переписывать функцию.

Re: stm32f4 usart+DMA

Пт фев 04, 2022 15:54:27

Спойлер
Код:
void Usart1_send( uint8_t*data, uint16_t len)

У меня вопрос.А в какое место мне вставить вот это?В вашей функции где это будет находится?

Re: stm32f4 usart+DMA

Пт фев 04, 2022 19:03:28

незачет так незачет
Последний раз редактировалось Dimon456 Пт фев 04, 2022 19:58:01, всего редактировалось 2 раз(а).

Re: stm32f4 usart+DMA

Пт фев 04, 2022 19:11:15

Dimon456 писал(а):то ли лсд

Я поржал! Думаю, что не один!
Dimon456 писал(а):Под словом дисплей не понятно что это

Ещё в старом-добром ZX Spectrum были понятия каналов и потоков, что делало абсолютно безразличным, куда ты пишешь строку оператором "PRINT". Я уж не говорю про нынешний С++ с его iostream. Так что, пардон, но не зачётный наезд.

Re: stm32f4 usart+DMA

Пт фев 04, 2022 21:58:00

tonyk, добавление функции printf это легко сделать, достаточно прописать в
Спойлер
Код:
int _write(int file, char *ptr, int len)
{
   Send_USART1_DMA(ptr, len);
   return len;
}
и можно выводить
Код:
printf("Hello, world!\r\n")
размер прошивки в режиме nano увеличится на 2,2кБайта и озу +100 байт.

Re: stm32f4 usart+DMA

Сб фев 05, 2022 15:51:48

незачет так незачет

Это наверное в мой адрес камень.
Я пока видео не посмотрел.Не понимал как настроить правильно ДМА

Добавлено after 4 hours 44 minutes 15 seconds:
Код:
void console_put(char *text) {
 i = 0;
 while (*text) {
  Some_Write_Buffer[i++] = *text;
  text++;
 };
 Some_Write_Buffer[i++] = '\r';
 Some_Write_Buffer[i++] = '\n';
 DMA_SendBuffer(i);
};


Код:
void tx_str1(char * string)
{
  // uint8_t i=0;
   int i=0;
   while (string[i])
   {
      tx_uart1(string[i]);
      i++;
     // tx_uart(string[i++]);
   }
   tx_uart1('\r');
   tx_uart1('\n');
}

Вот подобный код.Но как же преобразовать его?

Re: stm32f4 usart+DMA

Сб фев 05, 2022 16:40:31

Вот подобный код.Но как же преобразовать его?

Да, код подобен. В первом блоке кода - то, что написал я. Во втором - то, что написали Вы.

Преобразовать куда? Зачем? Во что?
Все астрологи празднуют китайский новый год.
Пишите ПОНЯТНО. Потому что сейчас вопросов больше, чем ответов.

Что такое tx_uart1? Функция, кладущая данные в UART1->DR? Если так - то это НЕ DMA.
DMA - это работа с буферами. То, что Вы привели - PIO обмен.
Processos Input Output.

Re: stm32f4 usart+DMA

Сб фев 05, 2022 17:09:23

Код:
void tx_str_DMA(char * string)
{
   
  uint8_t len =* string ;
   int i=0;
   while (string[i])
   {
   
      i++;
   
   }
   Usart1_send((uint8_t*) "\r\n", len);
}

Вот работает но не так.в строке 2 раэа повторяется.?

Re: stm32f4 usart+DMA

Сб фев 05, 2022 18:17:01

ivan dimir, вот уж на изобретал так на изобретал, не удивительно что тебе замучились помогать.
Смотри еще раз
Спойлеримеем наши функции
Код:
void usart_send_str(const char* str)
{
    while(*str) {
    while ((USART1->SR & USART_SR_TXE) == 0) {}
       USART1->DR = *str++;
    }
}


void Send_str_USART1_DMA(const char *adr)
{
  DMA1_Channel4->CCR &= ~DMA_CCR1_EN;
  DMA1_Channel4->CMAR = (uint32_t) adr;
  char *p = (char *)adr;
  while(*p) p++;
  DMA1_Channel4->CNDTR = p-adr;
  DMA1_Channel4->CCR |= DMA_CCR1_EN;
}

void Send_USART1_DMA(const char *adr, uint32_t len)
{
   DMA1_Channel4->CCR &= ~DMA_CCR1_EN;
   DMA1_Channel4->CMAR = (uint32_t) adr;
   DMA1_Channel4->CNDTR = len;
   DMA1_Channel4->CCR |= DMA_CCR1_EN;
}

void console_put(const char *text) {
   while(*text) {
      // Пока не нуль-терминатор
      tty0_TX_BUF[tty0_WR_POS] = *text;      // Копируем данные в буфер
      text++;                  // Сдвигаем указатель текста.
      tty0_WR_POS++;               // Сдвигаем указатель на 1 байт дальше.
      if (tty0_WR_POS >= sizeof(tty0_TX_BUF)) tty0_WR_POS = 0;   // Указатель должен быть в пределах допустимых значений.
   };
   // Запускаем.
   tty0_ActivateDMA();
};
вот сколько их много.
Далее пишем, как хотим
Код:
//#define SEND(str) usart_send_str(str)
//#define SEND(str) console_put(str)
//#define SEND(str) Send_str_USART1_DMA(str)
//#define SEND_l(str,len) Send_USART1_DMA(str,len)
да, с высокой горки как будем выводить
Код:
SEND("\r\n STM32F100RB USART DMA-tx !!! 31");
SEND("\r\n");

printf("Hello, world!\r\n");
Вот твой пример кода вывода на лсд
Код:
      case 1:
        //LCD_Clear();
        sprintf(buf, " a= %4d", a);
        LCD_SetPos(0, 0);
        LCD_String(buf);
        // delay_ms(5);
        break;
ну что сложного
Код:
sprintf(buf, " a= %4d \r\n", a);
SEND(buf);
да же не задумываясь над этим.

Вот еще примеры
Код:
sprintf(buf, " a= %4lu \r\n", ms_tick);
SEND(buf);
Код:
uint8_t len = sprintf(buf, " a= %4lu \r\n", ms_tick);
Send_USART1_DMA(buf,len); // SEND_l(buf,len);
Код:
printf(" a= %4lu \r\n", ms_tick);

Re: stm32f4 usart+DMA

Сб фев 05, 2022 19:26:59

Код:
void tx_str_DMA(char * string)
{
   
  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 и исправлять код до тех пор, пока в выводе не исчезнут даже предупреждения компилятора.
Собственно, у себя в коде я делаю похожим образом. Разве что уровень сообщений об ошибках чуть ниже ставлю.

Re: stm32f4 usart+DMA

Сб фев 05, 2022 22:57:39

Этот код выводит два раза в строку.У меня вопрос.Как то вы прговорились.Что эта работа с буферами?Там в этом коде сколько должно быть буферов .Я думаю два.Может я не прав ?
Код:
  DMA2_Stream7->M0AR |=(uint32_t)&txData;

Код:
DMA2_Stream7->NDTR = len;
и здесь.

Re: stm32f4 usart+DMA

Вс фев 06, 2022 07:31:34

AlanDrakes писал(а):[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, ты отладчиком пользоваться умеешь?

Re: stm32f4 usart+DMA

Вс фев 06, 2022 08:44:56

Нет.Смотрел так и не понял.Это чтобы не прошивать контроллер.Смотреть код программы?

Re: stm32f4 usart+DMA

Вс фев 06, 2022 09:18:07

Интересно как на перфокартах программу отлаживали?
Современные IDE предоставляют такие возможности, IAR вообще позволяет в режиме отладки и код программы корректировать.
Для AVR писали, не у всех полноценный отладчик был, протеусом пользовались.
А тут ... без комментариев.

Re: stm32f4 usart+DMA

Вс фев 06, 2022 10:20:36

Протеус.Не отладчик.У меня не IAR.Cubeide
Ответить