printf problem bei STM32F4

#3963340
Lesenswert?

Hallo,

ich habe ein seltsames Problem mit printf beim Programmieren STM32F4 
Discovery Board.

Nur beim Printen von mehreren Gleitkommazahlen bekomme ich entweder ganz 
verfälschte Daten, oder die nur die Hälfte, wenn ich in main schleife 
nach dem printf ohne mindestens 200ms Verzögerung habe. Mit 200ms Delay 
geht printf ohne Problem. Woran liegt das? Ist mein printf keine 
blockierende Methode?


Vielen Dank im Voraus.

PS. Ich schreib deutsch als Fremdsprache. Entschuldigung für die 
schlechtformulierten Sätze.
1
int main(void){
2

3
while(1){
4
 printf("%f %f %f %f \n", zahl1, zahl2, zahl3, zahl4);
5
 Delay(200e3);
6
}
7
}
8

9
void Delay(__IO uint32_t nTime)
10
{
11
    TimingDelay = nTime;
12
    
13
    while(TimingDelay != 0);
14
}
15

16
void TimingDelay_Decrement(void)
17
{
18
    if (TimingDelay != 0x00)
19
    {
20
        TimingDelay--;
21
    }
22
}
Usart wird so konfiguriert.
1
 
2
/* USART1 clock enable */
3
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
4

5
/* USART1 initialisieren PB6=TX PB7=RX*/
6
GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_USART1);  GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_USART1);
7
    
8
   
9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;  
10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
11
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;  
12
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
13
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
14
GPIO_Init(GPIOB, &GPIO_InitStructure);
15

16

17
USART_InitTypeDef USART_InitStructure;
18
    
19
USART_InitStructure.USART_BaudRate = 115200;
20
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
21
USART_InitStructure.USART_StopBits = USART_StopBits_1;
22
USART_InitStructure.USART_Parity = USART_Parity_No;
23
    
24
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
25
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
26
  
27
USART_Init(USART1, &USART_InitStructure);
28
USART_Cmd(USART1, ENABLE);
29

30
/**
31
 * @brief  Retargets the C library printf function to the USART.
32
 *       Overwrite __io_putchar function used by printf
33
 * @param  None
34
 * @retval None
35
 */
36
PUTCHAR_PROTOTYPE
37
{
38
  /* Put character on the serial line */
39
  USART1->DR = (ch & (uint16_t)0x01FF);
40
    
41
  /* Loop until transmit data register is empty */
42
  while ((USART1->SR & USART_FLAG_TXE) == (uint16_t) RESET);
43
    
44
  return ch;
45
}

für Prinf float zahlen
1
#include <errno.h>
2
#include <sys/stat.h>
3
#include <sys/times.h>
4
#include <sys/unistd.h>
5
#include <stdint.h>
6

7
#include <stm32f4xx_usart.h>
8

9
#ifndef UNUSED
10
#define UNUSED(x) (void)x
11
#endif
12

13
#ifndef STDOUT_USART
14
#define STDOUT_USART 1
15
#endif
16

17
#ifndef STDERR_USART
18
#define STDERR_USART 2
19
#endif
20

21
#ifndef STDIN_USART
22
#define STDIN_USART 1
23
#endif
24

25
#undef errno
26
extern int errno;
27

28
/*
29
 * A pointer to a list of environment variables and their values.
30
 * For a minimal environment, this empty list is adequate.
31
 */
32
char *__env[1] = { 0 };
33
char **environ = __env;
34

35
int _write(int file, char *ptr, int len);
36

37
void _exit(int status) {
38
  UNUSED(status);
39

40
  _write(1, "exit", 4);
41
  while (1) {
42
    ;
43
  }
44
}
45

46
int _close(int file) {
47
  UNUSED(file);
48

49
  return -1;
50
}
51

52
/*
53
 * Transfer control to a new process. Minimal implementation (for a system
54
 * without processes)
55
 */
56
int _execve(char *name, char **argv, char **env) {
57
  UNUSED(name);
58
  UNUSED(argv);
59
  UNUSED(env);
60

61
  errno = ENOMEM;
62
  return -1;
63
}
64

65
/*
66
 * Create a new process. Minimal implementation (for a system without processes)
67
 */
68
int _fork() {
69
  errno = EAGAIN;
70
  return -1;
71
}
72
/*
73
 * Status of an open file. Minimal implementation.
74
 */
75
int _fstat(int file, struct stat *st) {
76
  UNUSED(file);
77

78
  st->st_mode = S_IFCHR;
79
  return 0;
80
}
81

82
/*
83
 * Process-ID; this is sometimes used to generate strings unlikely to conflict
84
 * with other processes. Minimal implementation, for a system without processes.
85
 */
86
int _getpid() {
87
  return 1;
88
}
89

90
/*
91
 * Query whether output stream is a terminal. For consistency with the other
92
 * minimal implementation.
93
 */
94
int _isatty(int file) {
95
  UNUSED(file);
96

97
  switch (file) {
98
  case STDOUT_FILENO:
99
  case STDERR_FILENO:
100
  case STDIN_FILENO:
101
    return 1;
102
  default:
103
    //errno = ENOTTY;
104
    errno = EBADF;
105
    return 0;
106
  }
107
}
108

109
/*
110
 * Send a signal. Minimal implementation.
111
 */
112
int _kill(int pid, int sig) {
113
  UNUSED(pid);
114
  UNUSED(sig);
115

116
  errno = EINVAL;
117
  return (-1);
118
}
119

120
/*
121
 * Establish a new name for an existing file. Minimal implementation.
122
 */
123
int _link(char *old, char *new) {
124
  UNUSED(old);
125
  UNUSED(new);
126

127
  errno = EMLINK;
128
  return -1;
129
}
130

131
/*
132
 * Set position in a file. Minimal implementation.
133
 */
134
int _lseek(int file, int ptr, int dir) {
135
  UNUSED(file);
136
  UNUSED(ptr);
137
  UNUSED(dir);
138

139
  return 0;
140
}
141

142
/*
143
 * Increase program data space. Malloc and related functions depend on this.
144
 */
145
caddr_t _sbrk(int incr) {
146

147
  extern char _ebss; // Defined by the linker
148
  static char *heap_end;
149
  char *prev_heap_end;
150

151
  if (heap_end == 0) {
152
    heap_end = &_ebss;
153
  }
154
  prev_heap_end = heap_end;
155

156
  /** FIX **/
157
    char * stack = (char*) __get_MSP();
158
    if (heap_end + incr >  stack){
159
      _write (STDERR_FILENO, "Heap and stack collision\n", 25);
160
      errno = ENOMEM;
161
      return  (caddr_t) - 1;
162
      //abort ();
163
    }
164

165
  heap_end += incr;
166
  return (caddr_t) prev_heap_end;
167

168
}
169

170
/*
171
 * Read a character to a file. `libc' subroutines will use this system routine
172
 * for input from all files, including stdin.
173
 * Returns -1 on error or blocks until the number of characters have been read.
174
 */
175
int _read(int file, char *ptr, int len) {
176
  int n;
177
  int num = 0;
178
  switch (file) {
179
  case STDIN_FILENO:
180
    for (n = 0; n < len; n++) {
181
#if   STDIN_USART == 1
182
      while ((USART1->SR & USART_FLAG_RXNE) == (uint16_t)RESET) {}
183
            char c = (char)(USART1->DR & (uint16_t)0x01FF);
184
#elif STDIN_USART == 2
185
//      while ((USART2->ISR & USART_FLAG_RXNE) == (uint16_t) RESET) {}
186
//      char c = (char) (USART2->TDR & (uint16_t) 0x01FF);
187
#elif STDIN_USART == 3
188
//      while ((USART3->ISR & USART_FLAG_RXNE) == (uint16_t)RESET) {}
189
//      char c = (char)(USART3->TDR & (uint16_t)0x01FF);
190
#endif
191
      *ptr++ = c;
192
      num++;
193
    }
194
    break;
195
  default:
196
    errno = EBADF;
197
    return -1;
198
  }
199
  return num;
200
}
201

202
/*
203
 * Status of a file (by name). Minimal implementation.
204
 * int _EXFUN(stat,( const char *__path, struct stat *__sbuf ));
205
 */
206
int _stat(const char *filepath, struct stat *st) {
207
  UNUSED(filepath);
208

209
  st->st_mode = S_IFCHR;
210
  return 0;
211
}
212

213
/*
214
 * Timing information for current process. Minimal implementation.
215
 */
216
clock_t _times(struct tms *buf) {
217
  UNUSED(buf);
218

219
  return -1;
220
}
221

222
/*
223
 * Remove a file's directory entry. Minimal implementation.
224
 */
225
int _unlink(char *name) {
226
  UNUSED(name);
227

228
  errno = ENOENT;
229
  return -1;
230
}
231

232
/*
233
 * Wait for a child process. Minimal implementation.
234
 */
235
int _wait(int *status) {
236
  UNUSED(status);
237

238
  errno = ECHILD;
239
  return -1;
240
}
241

242
/*
243
 * Write a character to a file. `libc' subroutines will use this system routine
244
 * for output to all files, including stdout.
245
 * Returns -1 on error or number of bytes sent.
246
 */
247
int _write(int file, char *ptr, int len) {
248
  int n;
249

250
  switch (file) {
251
  case STDOUT_FILENO: /*stdout*/
252
    for (n = 0; n < len; n++) {
253
      while ((USART1->SR & USART_FLAG_TXE) == (uint16_t)RESET) {
254
                //USART1->DR = (*ptr++ & (uint16_t)0x01FF);
255
            }
256
      USART1->DR = (*ptr++ & (uint16_t)0x01FF);
257
    }
258
    break;
259
  case STDERR_FILENO: /* stderr */
260
    for (n = 0; n < len; n++) {
261

262
    }
263
    break;
264
  default:
265
    errno = EBADF;
266
    return -1;
267
  }
268
  return len;
269
}
Gast #3963971
Lesenswert?

Ich hab keine Ahnung, wie das C-Library deines Systems aufgebaut ist. 
Eine Sache ist mir bei deiner Patcherei aber aufgefallen: der 
PUTCHAR_PROTOTYPE und die _write Routine sind nicht kompatibel.  Der 
Prototype schreibt das Zeichen in das TX-Register und wartet dann auf TX 
Empty, die _write Routine macht es umgekehrt.  Wenn nun direkt nach 
einem Aufruf von _write ein PUTCHAR folgt, wird das gerade übertragene 
Zeichen überschrieben.  Beide Routinen sollten die gleiche Reihenfolge 
benutzen.

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