STM32F4 printf für float implementieren

#3735581
Lesenswert?

Hallo Leute,

ich möchte printf Funktion für float Zahl auf einen STM32F407 Discovery 
Board hinzukriegen.
wenn ich mal printf("float Zahl %f \n", 123.0f) eingebe, empfange ich 
über USART gar nichts.

Kann mir jemand helfen, wie ich den printf.c Datei für float anpasse.

Vielen Dank im Voraus,

Gruß Chu
1
/**************************************************************************//*****
2
 * @file     printf.c
3
 * @brief    Implementation of several stdio.h methods, such as printf(), 
4
 *           sprintf() and so on. This reduces the memory footprint of the
5
 *           binary when using those methods, compared to the libc implementation.
6
 ********************************************************************************/
7
#include <stdio.h>
8
#include <stdarg.h>
9
#include <stm32f4xx_usart.h>
10

11

12
/**
13
 * @brief  Transmit a char, if you want to use printf(), 
14
 *         you need implement this function
15
 *
16
 * @param  pStr  Storage string.
17
 * @param  c    Character to write.
18
 */
19
void PrintChar(char c)
20
{
21
    if (c == '\n')  {
22
      while (!(USART1->SR & 0x0080));
23
      USART1->DR = 0x0D;
24
    }
25
     while (!(USART1->SR & 0x0080));
26
    USART1->DR = (c & 0x1FF);
27
}
28

29
/** Maximum string size allowed (in bytes). */
30
#define MAX_STRING_SIZE         100
31

32

33
/** Required for proper compilation. */
34
struct _reent r = {0, (FILE *) 0, (FILE *) 1, (FILE *) 0};
35
//struct _reent *_impure_ptr = &r;
36

37
/**
38
 * @brief  Writes a character inside the given string. Returns 1.
39
 *
40
 * @param  pStr  Storage string.
41
 * @param  c    Character to write.
42
 */
43
signed int PutChar(char *pStr, char c)
44
{
45
    *pStr = c;
46
    return 1;
47
}
48

49

50
/**
51
 * @brief  Writes a string inside the given string.
52
 *
53
 * @param  pStr     Storage string.
54
 * @param  pSource  Source string.
55
 * @return  The size of the written
56
 */
57
signed int PutString(char *pStr, const char *pSource)
58
{
59
    signed int num = 0;
60

61
    while (*pSource != 0) {
62

63
        *pStr++ = *pSource++;
64
        num++;
65
    }
66

67
    return num;
68
}
69

70

71
/**
72
 * @brief  Writes an unsigned int inside the given string, using the provided fill &
73
 *         width parameters.
74
 *
75
 * @param  pStr  Storage string.
76
 * @param  fill  Fill character.
77
 * @param  width  Minimum integer width.
78
 * @param  value  Integer value.   
79
 */
80
signed int PutUnsignedInt(
81
    char *pStr,
82
    char fill,
83
    signed int width,
84
    unsigned int value)
85
{
86
    signed int num = 0;
87

88
    /* Take current digit into account when calculating width */
89
    width--;
90

91
    /* Recursively write upper digits */
92
    if ((value / 10) > 0) {
93

94
        num = PutUnsignedInt(pStr, fill, width, value / 10);
95
        pStr += num;
96
    }
97
    
98
    /* Write filler characters */
99
    else {
100

101
        while (width > 0) {
102

103
            PutChar(pStr, fill);
104
            pStr++;
105
            num++;
106
            width--;
107
        }
108
    }
109

110
    /* Write lower digit */
111
    num += PutChar(pStr, (value % 10) + '0');
112

113
    return num;
114
}
115

116

117
/**
118
 * @brief  Writes a signed int inside the given string, using the provided fill & width
119
 *         parameters.
120
 *
121
 * @param pStr   Storage string.
122
 * @param fill   Fill character.
123
 * @param width  Minimum integer width.
124
 * @param value  Signed integer value.
125
 */
126
signed int PutSignedInt(
127
    char *pStr,
128
    char fill,
129
    signed int width,
130
    signed int value)
131
{
132
    signed int num = 0;
133
    unsigned int absolute;
134

135
    /* Compute absolute value */
136
    if (value < 0) {
137

138
        absolute = -value;
139
    }
140
    else {
141

142
        absolute = value;
143
    }
144

145
    /* Take current digit into account when calculating width */
146
    width--;
147

148
    /* Recursively write upper digits */
149
    if ((absolute / 10) > 0) {
150

151
        if (value < 0) {
152
        
153
            num = PutSignedInt(pStr, fill, width, -(absolute / 10));
154
        }
155
        else {
156

157
            num = PutSignedInt(pStr, fill, width, absolute / 10);
158
        }
159
        pStr += num;
160
    }
161
    else {
162

163
        /* Reserve space for sign */
164
        if (value < 0) {
165

166
            width--;
167
        }
168

169
        /* Write filler characters */
170
        while (width > 0) {
171

172
            PutChar(pStr, fill);
173
            pStr++;
174
            num++;
175
            width--;
176
        }
177

178
        /* Write sign */
179
        if (value < 0) {
180

181
            num += PutChar(pStr, '-');
182
            pStr++;
183
        }
184
    }
185

186
    /* Write lower digit */
187
    num += PutChar(pStr, (absolute % 10) + '0');
188

189
    return num;
190
}
191

192

193
/**
194
 * @brief  Writes an hexadecimal value into a string, using the given fill, width &
195
 *         capital parameters.
196
 *
197
 * @param pStr   Storage string.
198
 * @param fill   Fill character.
199
 * @param width  Minimum integer width.
200
 * @param maj    Indicates if the letters must be printed in lower- or upper-case.
201
 * @param value  Hexadecimal value.
202
 *
203
 * @return  The number of char written
204
 */
205
signed int PutHexa(
206
    char *pStr,
207
    char fill,
208
    signed int width,
209
    unsigned char maj,
210
    unsigned int value)
211
{
212
    signed int num = 0;
213

214
    /* Decrement width */
215
    width--;
216

217
    /* Recursively output upper digits */
218
    if ((value >> 4) > 0) {
219

220
        num += PutHexa(pStr, fill, width, maj, value >> 4);
221
        pStr += num;
222
    }
223
    /* Write filler chars */
224
    else {
225

226
        while (width > 0) {
227

228
            PutChar(pStr, fill);
229
            pStr++;
230
            num++;
231
            width--;
232
        }
233
    }
234

235
    /* Write current digit */
236
    if ((value & 0xF) < 10) {
237

238
        PutChar(pStr, (value & 0xF) + '0');
239
    }
240
    else if (maj) {
241

242
        PutChar(pStr, (value & 0xF) - 10 + 'A');
243
    }
244
    else {
245

246
        PutChar(pStr, (value & 0xF) - 10 + 'a');
247
    }
248
    num++;
249

250
    return num;
251
}
252

253

254

255
/* Global Functions ----------------------------------------------------------- */
256

257

258
/**
259
 * @brief  Stores the result of a formatted string into another string. Format
260
 *         arguments are given in a va_list instance.
261
 *
262
 * @param pStr    Destination string.
263
 * @param length  Length of Destination string.
264
 * @param pFormat Format string.
265
 * @param ap      Argument list.
266
 *
267
 * @return  The number of characters written.
268
 */
269
signed int vsnprintf(char *pStr, size_t length, const char *pFormat, va_list ap)
270
{
271
    char          fill;
272
    unsigned char width;
273
    signed int    num = 0;
274
    signed int    size = 0;
275

276
    /* Clear the string */
277
    if (pStr) {
278

279
        *pStr = 0;
280
    }
281

282
    /* Phase string */
283
    while (*pFormat != 0 && size < length) {
284

285
        /* Normal character */
286
        if (*pFormat != '%') {
287

288
            *pStr++ = *pFormat++;
289
            size++;
290
        }
291
        /* Escaped '%' */
292
        else if (*(pFormat+1) == '%') {
293

294
            *pStr++ = '%';
295
            pFormat += 2;
296
            size++;
297
        }
298
        /* Token delimiter */
299
        else {
300

301
            fill = ' ';
302
            width = 0;
303
            pFormat++;
304

305
            /* Parse filler */
306
            if (*pFormat == '0') {
307

308
                fill = '0';
309
                pFormat++;
310
            }
311

312
            /* Parse width */
313
            while ((*pFormat >= '0') && (*pFormat <= '9')) {
314
        
315
                width = (width*10) + *pFormat-'0';
316
                pFormat++;
317
            }
318

319
            /* Check if there is enough space */
320
            if (size + width > length) {
321

322
                width = length - size;
323
            }
324
        
325
            /* Parse type */
326
            switch (*pFormat) {
327
            case 'd': 
328
            case 'i': num = PutSignedInt(pStr, fill, width, va_arg(ap, signed int)); break;
329
            case 'u': num = PutUnsignedInt(pStr, fill, width, va_arg(ap, unsigned int)); break;
330
            case 'x': num = PutHexa(pStr, fill, width, 0, va_arg(ap, unsigned int)); break;
331
            case 'X': num = PutHexa(pStr, fill, width, 1, va_arg(ap, unsigned int)); break;
332
            case 's': num = PutString(pStr, va_arg(ap, char *)); break;
333
            case 'c': num = PutChar(pStr, va_arg(ap, unsigned int)); break;
334
            default:
335
                return EOF;
336
            }
337

338
            pFormat++;
339
            pStr += num;
340
            size += num;
341
        }
342
    }
343

344
    /* NULL-terminated (final \0 is not counted) */
345
    if (size < length) {
346

347
        *pStr = 0;
348
    }
349
    else {
350

351
        *(--pStr) = 0;
352
        size--;
353
    }
354

355
    return size;
356
}
357

358

359
/**
360
 * @brief  Stores the result of a formatted string into another string. Format
361
 *         arguments are given in a va_list instance.
362
 *
363
 * @param pStr    Destination string.
364
 * @param length  Length of Destination string.
365
 * @param pFormat Format string.
366
 * @param ...     Other arguments
367
 *
368
 * @return  The number of characters written.
369
 */
370
signed int snprintf(char *pString, size_t length, const char *pFormat, ...)
371
{
372
    va_list    ap;
373
    signed int rc;
374

375
    va_start(ap, pFormat);
376
    rc = vsnprintf(pString, length, pFormat, ap);
377
    va_end(ap);
378

379
    return rc;
380
}
381

382

383
/**
384
 * @brief  Stores the result of a formatted string into another string. Format
385
 *         arguments are given in a va_list instance.
386
 *
387
 * @param pString  Destination string.
388
 * @param length   Length of Destination string.
389
 * @param pFormat  Format string.
390
 * @param ap       Argument list.
391
 *
392
 * @return  The number of characters written.
393
 */
394
signed int vsprintf(char *pString, const char *pFormat, va_list ap)
395
{
396
   return vsnprintf(pString, MAX_STRING_SIZE, pFormat, ap);
397
}
398

399
/**
400
 * @brief  Outputs a formatted string on the given stream. Format arguments are given
401
 *         in a va_list instance.
402
 *
403
 * @param pStream  Output stream.
404
 * @param pFormat  Format string
405
 * @param ap       Argument list. 
406
 */
407
signed int vfprintf(FILE *pStream, const char *pFormat, va_list ap)
408
{
409
    char pStr[MAX_STRING_SIZE];
410
    char pError[] = "stdio.c: increase MAX_STRING_SIZE\n\r";
411

412
    /* Write formatted string in buffer */
413
    if (vsprintf(pStr, pFormat, ap) >= MAX_STRING_SIZE) {
414

415
        fputs(pError, stderr);
416
        while (1); /* Increase MAX_STRING_SIZE */
417
    }
418

419
    /* Display string */
420
    return fputs(pStr, pStream);
421
}
422

423

424
/**
425
 * @brief  Outputs a formatted string on the DBGU stream. Format arguments are given
426
 *         in a va_list instance.
427
 *
428
 * @param pFormat  Format string.
429
 * @param ap  Argument list.
430
 */
431
signed int vprintf(const char *pFormat, va_list ap)
432
{
433
    return vfprintf(stdout, pFormat, ap);
434
}
435

436

437
/**
438
 * @brief  Outputs a formatted string on the given stream, using a variable 
439
 *         number of arguments.
440
 *
441
 * @param pStream  Output stream.
442
 * @param pFormat  Format string.
443
 */
444
signed int fprintf(FILE *pStream, const char *pFormat, ...)
445
{
446
    va_list ap;
447
    signed int result;
448

449
    /* Forward call to vfprintf */
450
    va_start(ap, pFormat);
451
    result = vfprintf(pStream, pFormat, ap);
452
    va_end(ap);
453

454
    return result;
455
}
456

457

458
/**
459
 * @brief  Outputs a formatted string on the DBGU stream, using a variable number of
460
 *         arguments.
461
 *
462
 * @param  pFormat  Format string.
463
 */
464
signed int printf(const char *pFormat, ...)
465
{
466
    va_list ap;
467
    signed int result;
468

469
    /* Forward call to vprintf */
470
    va_start(ap, pFormat);
471
    result = vprintf(pFormat, ap);
472
    va_end(ap);
473

474
    return result;
475
}
476

477

478
/**
479
 * @brief  Writes a formatted string inside another string.
480
 *
481
 * @param pStr     torage string.
482
 * @param pFormat  Format string.
483
 */
484
signed int sprintf(char *pStr, const char *pFormat, ...)
485
{
486
    va_list ap;
487
    signed int result;
488

489
    // Forward call to vsprintf
490
    va_start(ap, pFormat);
491
    result = vsprintf(pStr, pFormat, ap);
492
    va_end(ap);
493

494
    return result;
495
}
496

497

498
/**
499
 * @brief  Outputs a string on stdout.
500
 *
501
 * @param pStr  String to output. 
502
 */
503
signed int puts(const char *pStr)
504
{
505
    return fputs(pStr, stdout);
506
}
507

508

509
/**
510
 * @brief  Implementation of fputc using the DBGU as the standard output. Required
511
 *         for printf().
512
 *
513
 * @param c        Character to write.
514
 * @param pStream  Output stream.
515
 * @param The character written if successful, or -1 if the output stream is
516
 *        not stdout or stderr.
517
 */
518
signed int fputc(signed int c, FILE *pStream)
519
{
520
    if ((pStream == stdout) || (pStream == stderr)) {
521

522
      PrintChar(c);
523

524
        return c;
525
    }
526
    else {
527

528
        return EOF;
529
    }
530
}
531

532

533
/**
534
 * @brief  Implementation of fputs using the DBGU as the standard output. Required
535
 *         for printf().
536
 *
537
 * @param pStr     String to write.
538
 * @param pStream  Output stream.
539
 *
540
 * @return  Number of characters written if successful, or -1 if the output
541
 *          stream is not stdout or stderr.
542
 */
543
signed int fputs(const char *pStr, FILE *pStream)
544
{
545
    signed int num = 0;
546

547
    while (*pStr != 0) {
548

549
        if (fputc(*pStr, pStream) == -1) {
550

551
            return -1;
552
        }
553
        num++;
554
        pStr++;
555
    }
556

557
    return num;
558
}
559

560
/* --------------------------------- End Of File ------------------------------ */
Gast #3735603
Lesenswert?

Stm Mc schrieb:
> /* Parse type */
>             switch (*pFormat) {
>             case 'd':
>             case 'i': num = PutSignedInt(pStr, fill, width, va_arg(ap,
> signed int)); break;
>             case 'u': num = PutUnsignedInt(pStr, fill, width, va_arg(ap,
> unsigned int)); break;
>             case 'x': num = PutHexa(pStr, fill, width, 0, va_arg(ap,
> unsigned int)); break;
>             case 'X': num = PutHexa(pStr, fill, width, 1, va_arg(ap,
> unsigned int)); break;
>             case 's': num = PutString(pStr, va_arg(ap, char *)); break;
>             case 'c': num = PutChar(pStr, va_arg(ap, unsigned int));
> break;

Na dann fang doch einfach mal damit an dir eine PutEigeneFloat zu 
basteln...
#3735942
Lesenswert?

hier ein fertiger Beispiel-Code :
1
#include "stm32_ub_string.h"
2

3

4
//--------------------------------------------------------------
5
// wandelt eine Float Zahl in einen String als Dezimahl Zahl
6
// ergebnis steht dann in "STRING_BUF"
7
// Float muss zwischen -32767 und +32767 liegen
8
//--------------------------------------------------------------
9
void UB_String_FloatToDezStr(float wert)
10
{
11
  int16_t vorkomma;
12
  uint16_t nachkomma;
13
  float rest;
14

15
  if((wert>32767) || (wert<-32767)) {
16
    // zahl zu groß oder zu klein
17
    sprintf(STRING_BUF,"%s","OVF");
18
    return;
19
  }
20

21
  vorkomma=(int16_t)(wert);
22
  if(wert>=0) {
23
    rest = wert-(float)(vorkomma);
24
  }
25
  else {
26
    rest = (float)(vorkomma)-wert;
27
  }
28
  nachkomma = (uint16_t)(rest*(float)(STRING_FLOAT_FAKTOR)+0.5);
29

30
  sprintf(STRING_BUF,STRING_FLOAT_FORMAT,vorkomma,nachkomma);
31
}

1
#include "stm32f4xx.h"
2
#include <stdio.h>
3
#include <stdarg.h>
4

5

6
//--------------------------------------------------------------
7
// Defines
8
//--------------------------------------------------------------
9
#define  STRING_BUF_SIZE     50   // maximum Grösse vom String
10

11

12
//--------------------------------------------------------------
13
// Globaler String-Puffer
14
//--------------------------------------------------------------
15
char STRING_BUF[STRING_BUF_SIZE];
16

17

18
//--------------------------------------------------------------
19
// Anzahl der Nachkommastellen bei Float
20
//  Faktor ->  100 = 2 Nachkommastellen,  Formatierung -> "%d.%02d"
21
//  Faktor -> 1000 = 3 Nachkommastellen,  Formatierung -> "%d.%03d"
22
//  usw
23
//--------------------------------------------------------------
24
#define  STRING_FLOAT_FAKTOR     1000   // 1000 = 3 Nachkommastellen
25
#define  STRING_FLOAT_FORMAT "%d.%03d"  // Formatierung
26

27

28
//--------------------------------------------------------------
29
// Globale Funktionen
30
//--------------------------------------------------------------
31
void UB_String_FloatToDezStr(float wert);

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren