Reputation: 37
I use sprintf()
to fill a buffer and then send this buffer over UART.
I have follow many exemple and use case of sprintf
but my code doesn't seems to work
Here is my code example :
#include "stdio.h"
#include "usart.h"
#define Uart husart1
int main(void)
{
uint32_t m = 3;
char c = 'A';
uint32_t o = 1;
char buffer[256];
sprintf(buffer, "AT+,%lu,%c,%lu\r\n", m, c, o);
HAL_UART_Transmit(&Uart, (uint8_t*) buffer, strlen(buffer), 1000);
}
With this piece of code my output is AT+,lu,,lu
Do you have any idea of what is going wrong ?
Edit 1 :
When I replace %lu
by %d
my compilator says this error :
format '%d' expects argument of type 'int', but argument 5 has type 'uint32_t {aka long unsigned int}' [-Wformat=]
So I have had %ld
and the buffer send is like AT+,ld,,ld
Edit 2 :
When I replace %lu
by %u
my compilator says this error :
format '%u' expects argument of type 'unsigned int', but argument 3 has type 'uint32_t {aka long unsigned int}' [-Wformat=]
Edit 3:
with #include <stdio.h>
I have the same errors
Edit 4: regarding the answers I want to keep the uint32_t
as my AT parameters can be 32bit long
Edit 5: I tried to cast the type using %d and (int16_t) as follow :
sprintf(buffer, "AT+,%d,%c,%d\r\n", (int16_t) m, c, (int16_t) o);
and this time my resut is "AT+, ,A, "
Why does my code is upset with signed or unsigned integer ?
Edit 6:
With the use of inttypes.h, it looks like this :
sprintf(buffer, "AT+,%"PRIu32",%c,%"PRIu32"\r\n", m, c, o);
and my output still look like AT+,lu,,lu
Upvotes: 0
Views: 525
Reputation: 62817
Correct format specifier for uint32_t
is in define macro PRIu32
, which expands to correct format specfier string. It's found in inttypes.h. So your code becomes like this (also fixed the include brackets, assuming none of these headers are part of your project, but part of the toolchain):
#include <stdio.h>
#include <inttypes.h>
#include <usart.h>
#define Uart husart1
int main(void)
{
uint32_t m = 3;
char c = 'A';
uint32_t o = 1;
char buffer[256];
sprintf(buffer, "AT+,%"PRIu32",%c,%"PRIu32"\r\n", m, c, o);
HAL_UART_Transmit(&Uart, (uint8_t*) buffer, strlen(buffer), 1000);
}
The macros may look a bit confusing, so an explanation. In C, you can concatenate string literals at compile time by just by putting them one after the other. In other words, "count is %" "lu" " items"
produces exactly same string literal as "count is %lu items"
. And inttypes.h contains a define like #define PRIu32 "u"
or whatever is correct format on the platform.
Reference link: https://en.cppreference.com/w/c/types/integer
If this does not work, you have non-conforming standard library. This can happen on embedded platforms. You need to construct the string in some other way than using printf
for types which it does not support. You can consult your standard library documentation, or you could write your own functions, for example using strncat
as a model you could create functions like
char *strncat_u32(char *dest, uint32_t value, size_t n);
Upvotes: 0
Reputation: 67602
Embedded targets usually use nano implementation of the standard library and it does not support many printf
formats.
Simply use %u
for uint32_t
as uint32_t
is the native integer size for the STM32 uCs.
If you want very very "conforming" add the cast to unsigned int
.
Upvotes: 1