hallo!
auf einem STM32F205RC benutze ich nur das USART1, RX mit
Interrupt-Routine, TX wird gepollt:
1 | int
|
2 | putchar (int c1)
|
3 | {
|
4 | if (c1 == '\n') putchar ('\r');
|
5 | while ((USART1->SR & USART_SR_TXE) == 0);
|
6 | USART1->DR = c1;
|
7 | return c1;
|
8 | }
|
Gelegentlich bleibt das Teil in der while-Schleife hängen. Hat man schon
mal von so einem Dreckeffekt gehört? In den errata vom Dezember 2013
finde ich nichts.
Es kommen nur selten einzelne RX-Interrupts, da gibt es keinen
zeitlichen Zusammenhang. DMA-Controller sind zwar für I2C initialisiert,
aber das wird z.Zt. nicht benutzt. Die Initialisierung scheint mir auch
unspektakulär:
1 | void
|
2 | usart1_init (int baud)
|
3 | {
|
4 | int brr;
|
5 |
|
6 | RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
|
7 | brr = (((16000000 / 16) * 16) + (baud / 2)) / baud;
|
8 | USART1->BRR = brr;
|
9 | USART1->CR2 = USART_CR2_STOP_1;
|
10 | USART1->CR1 = USART_CR1_UE | USART_CR1_TE | USART_CR1_RE
|
11 | | USART_CR1_M | USART_CR1_PCE | USART_CR1_RXNEIE;
|
12 | NVIC->ISER[(53 - 16) / 32] |= 1 << ((53 - 16) % 32);
|
13 | }
|
Aber jetzt kommt's: es ist nicht rein zufällig, ein (auch viele)
putchar() vor und nach einer beep()-Funktion funktioniert, ein putchar
in der beep() hängt sich zuverlässig auf, egal, ob vor oder nach dem
einschalten des Timers. Na klar, Timer und Uart geht nicht
gleichzeitig!?
1 | putchar ('+'); /* ok */
|
2 | beep (0, 5, 200);
|
3 | putchar ('+'); /* ok */
|
4 |
|
5 |
|
6 | void
|
7 | beep (int tone, int octave, int ms)
|
8 | {
|
9 | static const int div12[] = {
|
10 | 2273, 2145, 2025, 1911, 1804, 1703, 1607, 1517, 1432, 1351, 1276, 1204 };
|
11 | int psc;
|
12 |
|
13 | putchar ('!'); /* geht nicht */
|
14 | if (octave < 3) octave = 3;
|
15 | if (octave > 7) octave = 7;
|
16 | if (tone < 0 || tone > 11) tone = 11;
|
17 | psc = (div12[tone] * (1 << (7 - octave))) / 2;
|
18 | RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
|
19 | TIM3->PSC = psc;
|
20 | TIM3->ARR = 2;
|
21 | TIM3->CCR4 = 1;
|
22 | TIM3->CCMR2 = 6 << 12;
|
23 | TIM3->CCER = TIM_CCER_CC4E;
|
24 | TIM3->CR1 = TIM_CR1_ARPE;
|
25 | TIM3->CR1 = TIM_CR1_ARPE | TIM_CR1_CEN;
|
26 | // TIM3->EGR = TIM_EGR_UG;
|
27 | sleep (ms);
|
28 | TIM3->CCR4 = 0;
|
29 | putchar ('!'); /* geht nicht */
|
30 | }
|
Momentan hab' ich der while-Schleife einen Time-Out spendiert, das
sollte man ja immer machen, deshalb bleibt der auch drin. Aber falls
jemand eine Idee hat, was da passiert wäre ich dankbar für einen Tipp.