Hallo Leute,
habe mal wieder eine Frage an euch. Ich habe hier ein STM32VL-Discovery
Board liegen. Ich programmiere gerade eine Art Gateway, welches einen
Computer mit einem I/O-Modul verbindet, für meine Bachelorarbeit. Ich
möchte hier jetzt nicht den ganzen Code posten, da er zu lang ist, aber
hier folgt der Code für den USART2, welcher für die Kommunikation mit
einem Computer zuständig ist.
1 | // Handle Interrupts on USART2 (USB connection)
|
2 | void USART2_IRQHandler()
|
3 | {
|
4 | uint8_t i;
|
5 | uint16_t crc;
|
6 |
|
7 | // Receive-Interrupt
|
8 | if(USART_GetITStatus(USART2, USART_IT_RXNE))
|
9 | {
|
10 | // Reset the interrupt-flag
|
11 | USART_ClearFlag(USART2, USART_FLAG_RXNE);
|
12 |
|
13 | TIM4->CNT = 0x00;
|
14 |
|
15 | // Enable the status LED "Connection to computer okay"
|
16 | GPIOB -> BSRR = GPIO_Pin_0;
|
17 |
|
18 | ReceiveByte(USART_ReceiveData(USART2));
|
19 |
|
20 | }
|
21 |
|
22 | // Transmit-Interrupt
|
23 | else if(USART_GetITStatus(USART2, USART_IT_TXE))
|
24 | {
|
25 | // Reset the interrupt-flag
|
26 | USART_ClearFlag(USART2, USART_FLAG_TXE);
|
27 |
|
28 | if(getNewMsg)
|
29 | {
|
30 | // Calculate the CRC for the temporary buffer
|
31 | crc = calcCRC(pcSendBuf[posPCsendBufRead].payload, pcSendBuf[posPCsendBufRead].msgLen);
|
32 |
|
33 | // Add the CRC to the last two positions in the temporary buffer
|
34 | pcSendBuf[posPCsendBufRead].payload[pcSendBuf[posPCsendBufRead].msgLen] = (crc & 0xff00) >> 8;
|
35 | pcSendBuf[posPCsendBufRead].payload[pcSendBuf[posPCsendBufRead].msgLen + 1] = (crc & 0xff);
|
36 | pcSendBuf[posPCsendBufRead].msgLen = pcSendBuf[posPCsendBufRead].msgLen + 2;
|
37 |
|
38 | getNewMsg = 0;
|
39 | pcSendBuf[posPCsendBufRead].pos = 0;
|
40 | }
|
41 |
|
42 | else
|
43 | {
|
44 | // Send data via USART
|
45 | USART_SendData(USART2, pcSendBuf[posPCsendBufRead].payload[pcSendBuf[posPCsendBufRead].pos]);
|
46 |
|
47 | pcSendBuf[posPCsendBufRead].pos++;
|
48 |
|
49 | // See if the end of the actual sub-buffer is reached
|
50 | if(pcSendBuf[posPCsendBufRead].pos >= pcSendBuf[posPCsendBufRead].msgLen)
|
51 | {
|
52 | for(i = 0; i < MAX_PC_MESSAGE_SIZE; i++)
|
53 | {
|
54 | pcSendBuf[posPCsendBufRead].payload[i] = '\0';
|
55 | }
|
56 |
|
57 | pcSendBuf[posPCsendBufRead].msgLen = 0;
|
58 |
|
59 | posPCsendBufRead++;
|
60 |
|
61 | getNewMsg = 1;
|
62 |
|
63 | // Check if the end of the send-buffer is reached
|
64 | if(posPCsendBufRead >= PC_SEND_BUFFER_SIZE)
|
65 | {
|
66 | // Chose the first sub-buffer
|
67 | posPCsendBufRead = 0;
|
68 | pcSendBuf[posPCsendBufRead].pos = 0;
|
69 | }
|
70 |
|
71 | // See if the sendBuf is empty
|
72 | if(posPCsendBufRead == posPCsendBufWrite)
|
73 | {
|
74 | pcSendBuf[posPCsendBufRead].pos = 0;
|
75 | // Disable the transmit interrupt on USART
|
76 | USART_ITConfig(USART2, USART_IT_TXE, DISABLE);
|
77 | }
|
78 | }
|
79 | }
|
80 | }
|
81 | }
|
Die Kommunikation funktioniert soweit prima. Wenn ich zum Computer jede
Menge Daten vom I/O-Modul schicke, ohne das der Computer sich einmischt,
klappt das auch soweit. Da habe ich schon über Millionen Daten rüber
geschaufelt. Wenn der Computer aber nun während der Übertragung noch
anfragen nach dem aktuellen Status des Gateways stellen soll,
funktioniert dies zunächst auch noch und dann bricht die Kommunikation
zusammen. Wenn ich nun mit Atolic TrueStudio debugge und schau wo er
hängen geblieben ist, dann springt er immer wieder in die oben
aufgeführte ISR, aber beide abfragen (Receive-Interrupt und
Transmit-Interrupt) sind falsch. Kurz danach springt er wieder rein und
die abfragen sind wieder beide falsch. Irgendwie scheint er also in
dieser ISR zu hängen, obwohl es keinen Interrupt gibt. Die
Interrupt-Flags setzte ich aber immer wieder sofort zurück.
Ich weiß, es sind nicht viele Infos und wahrscheinlich könnt ihr mir da
nicht groß weiter helfen. Vielleicht hat aber der ein oder andere von
euch doch so eine Vermutung, woran der Fehler liegen könnte.
Gruß
Mister232