Author Topic: using printf for two uart  (Read 2138 times)

0 Members and 1 Guest are viewing this topic.

Offline tariqTopic starter

  • Contributor
  • Posts: 24
  • Country: ir
using printf for two uart
« on: July 18, 2020, 02:31:35 pm »
hi
my printf function is in attachment. in this function printf only sends data by usart1.i want to send data by printf with choosing my uart channel
for example
printf(&huart2,"HELLO WORLD"%d,variable);
can any one help me?
Thank you.
 

Offline ebclr

  • Super Contributor
  • ***
  • Posts: 2331
  • Country: 00
Re: using printf for two uart
« Reply #1 on: July 18, 2020, 03:48:41 pm »
Most compilers relay on the Putchar to send print,  take a look at your put char function and change that one , according to the com needed
 

Offline tariqTopic starter

  • Contributor
  • Posts: 24
  • Country: ir
Re: using printf for two uart
« Reply #2 on: July 18, 2020, 04:23:04 pm »
can you give me an example please?
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 7541
  • Country: fi
    • My home page and email address
Re: using printf for two uart
« Reply #3 on: July 18, 2020, 04:51:09 pm »
If you use
Code: [Select]
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */

static UART_HandleTypeDef *printf_uart = &huart1;

void printf_to(UART_HandleTypeDef *uart)
{
    printf_uart = uart;
}

PUTCHAR_PROTOTYPE
{
  HAL_UART_Transmit(printf_uart, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
  return ch;
}
Then you can use printf_to(&huart1); or similar to change which UART is used for future printf()s.
 

Offline phil from seattle

  • Super Contributor
  • ***
  • Posts: 1149
  • Country: us
Re: using printf for two uart
« Reply #4 on: July 18, 2020, 04:53:57 pm »
In the past, sprintf has been the go to way of using printf formatting for arbitrary outputs.  You do somethinglike:

Code: [Select]
char buffer[64], * bp;

sprintf(buffer, /* normal printf stuff */);
bp = buffer;
while (*bp != 0) putchar(streamhw, *bp++);


you supply putchar, what ever library you are using supplies sprintf.

Teensyduino has added printf to the stream class so I can do:
Code: [Select]
Serial2.begin(115400);


Serial2.printf(...)
Which is way better than Arduino's clunky-assed print and println.

 

Offline newbrain

  • Super Contributor
  • ***
  • Posts: 1849
  • Country: se
Re: using printf for two uart
« Reply #5 on: July 18, 2020, 09:37:35 pm »
Which library are you using?
Many libraries that try to be C standard compliant (eg: newlib-nano) provide a vprintf function, which takes a va_list argument, instead of being variadic as printf.
In fact, printf is often implemented using vprintf.

vprintf() can easily be used to build your own special printf(), exactly as the one you prototyped in the OP - well, apart from the syntax error...

Code: [Select]
/* Global variable to hold the UART in use */
extern UART_HandleTypeDef *currentUart;

int printfUart(UART_HandleTypeDef *uart, const char *format, ...)
{
    /* Assign the passed UARAT handle to a global variable, to be used in printchar */
    currentUart = uart;
    va_list va;
    va_start(va, format);
    const int returnValue = vprintf(format, va);
    va_end(va);
    return returnValue;
}

The currentUart variable (of type UART_HandleTypeDef *) should be visible and used by your putchar() to send the character  to the right UART.
Code: [Select]
[...]
UART_HandleTypeDef *currentUart;

PUTCHAR_PROTOTYPE
{
    HAL_UART_Transmit(currentUart, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
    return ch;
}


Reentrancy is not supported by the simple implementation above (important if you have a degree of parallelism, or if you want to call the function from an ISR - you shouldn't in any case, though).

If you do not have a vprintf, I often use this very small implementation of the printf family.

Note: code not tested. I take no liability if your toothbrush catches fire or your cat becomes green.
Nandemo wa shiranai wa yo, shitteru koto dake.
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4413
  • Country: us
Re: using printf for two uart
« Reply #6 on: July 19, 2020, 04:54:36 am »
Quote
i want to send data by printf with choosing my uart channel for example
printf(&huart2,"HELLO WORLD"%d,variable);
that would usually be "fprintf(file, format, ...);"How you associate a particular "file" with a particular UART (or "whatever") depends on the environment you're using.Which you failed to mention.
 

Online abyrvalg

  • Frequent Contributor
  • **
  • Posts: 852
  • Country: es
Re: using printf for two uart
« Reply #7 on: July 19, 2020, 06:57:34 am »
If the hardware supports using pointers to peripherals the “file” param can be a just a pointer to uart cast to FILE * (and back in fputc).
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4413
  • Country: us
Re: using printf for two uart
« Reply #8 on: July 20, 2020, 07:55:53 am »
Quote
How you associate a particular "file" with a particular UART (or "whatever") depends on the environment you're using.Which you failed to mention.
It looks like in current microcontrollers with newlib or newlib nano, you would use "funopen" or "fopencookie", depending on the exact "featrues" enabled.  (I wrote something for Energia some years ago using fopencookie(), and it doesn't work any more (hmm.  maybe it was MPIDE that worked.)  However, funopen() works, now, on ARM-based Arduinos...
Code: [Select]
int myWrite(void *cookie, const char *buf, int n)
{
  Stream *s = (Stream *)cookie;
  // Serial.println("myWrite");
  return s->write((uint8_t*)buf, n);
}

FILE *myOut;

void setup() {
  pinMode(LED, OUTPUT);
  Serial.begin(115200);
  while (!Serial)
    ;
  myOut = funopen((void *)(&Serial), NULL, myWrite, NULL, NULL);
  setlinebuf(myOut);
  fprintf(myOut, "This is a test of funopen() based printf\n");
}
 
The following users thanked this post: oPossum


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf