Ich schreibe ein kleines embedded Programm, wo ich einige Befehle über uart an den atmega328p Chip sende. Die Befehle beginnen mit dem Zeichen $
und enden mit dem Zeichen (ich weiß also, wann das Parsen durchgeführt werden soll). Nach Empfang des Befehls parse ich ihn und schalte das Gerät ein (COMMAND: TURN_ON_I1) oder aus (COMMAND: TURN_OFF_I1). Die Anwendung sieht derzeit wie folgt aus:Verzögerte uart Befehlsausführung
// ------- Defines -------- //
#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/power.h>
#include <stdio.h>
#include <string.h>
#include "pinDefines.h"
#include "USART.h"
#define RECEIVE_BUFFER_SIZE 100
// Control output value
#define output_low(port,pin) port &= ~(1<<pin)
#define output_high(port,pin) port |= (1<<pin)
// Set pin mode (input or output)
#define set_input(portdir,pin) portdir &= ~(1<<pin)
#define set_output(portdir,pin) portdir |= (1<<pin)
// The DDRD port contains only two pins:
#define REL_BTN_SIM_2 PD6 // PD6 = REL_BTN_SIM_2
void initUSART(void) { /* requires BAUD */
UBRR0H = UBRRH_VALUE; /* defined in setbaud.h */
UBRR0L = UBRRL_VALUE;
#if USE_2X
UCSR0A |= (1 << U2X0);
#else
UCSR0A &= ~(1 << U2X0);
#endif
/* Enable USART transmitter/receiver */
UCSR0B = (1 << TXEN0) | (1 << RXEN0);
UCSR0C = (1 << UCSZ01) | (1 << UCSZ00); /* 8 data bits, 1 stop bit */
}
void printString(const char myString[]) {
uint8_t i = 0;
while (myString[i]) {
transmitByte(myString[i]);
i++;
}
}
uint8_t receiveByte(void) {
loop_until_bit_is_set(UCSR0A, RXC0); /* Wait for incoming data */
return UDR0; /* return register value */
}
void transmitByte(uint8_t data) {
/* Wait for empty transmit buffer */
loop_until_bit_is_set(UCSR0A, UDRE0);
UDR0 = data; /* send data */
}
int main(void) {
//$COMMAND:TURN_ON_I1#
//$COMMAND:TURN_OFF_I1#
char s[RECEIVE_BUFFER_SIZE];
char readSerialCharacter;
// -------- Inits --------- //
DDRB = 0b00000111;
DDRC = 0b00001000;
DDRD = 0b11000000;
initUSART();
// ------ Event loop ------ //
while (1) {
printString("Waiting for the start of string (char $).\r\n");
do { } while (receiveByte() != '$'); // Wait for start of string.
// Fill the array until the end of transmission is received
int i=0;
do {
// If nearing end of buffer, don't fill the buffer and exit the loop
if(i<RECEIVE_BUFFER_SIZE-1){
readSerialCharacter = receiveByte();
s[i++] = readSerialCharacter;
}else
break;
} while (readSerialCharacter != '#'); // Wait for end of string.
s[i] ='\0'; // Terminate the string
printString("The whole received command:\r\n");
printString(s);
printString("\r\n");
// Other commands (temperature, relay control)
// REL_BTN_SIM_2
else if(strstr(s, "COMMAND:TURN_ON_I1") != NULL)
{
printString("Will set I1 on!");
output_high(PORTD, REL_BTN_SIM_2);
}
else if(strstr(s, "COMMAND:TURN_OFF_I1") != NULL)
{
printString("Will set I1 off!");
output_low(PORTD, REL_BTN_SIM_2);
}
else
printString("Unknown command.\r\n");
// Clear the buffer
memset(s,'\0', sizeof(s));
}
/* End event loop */
return (0);
}
Ich bemerkte, dass, nachdem ich einen Befehl etwa sieben oder acht Mal (oder mehr) senden, wird die serielle Kommunikation unterbrochen oder dass der Befehl mit einer Verzögerung ausgeführt wird. Ich kann auch sehen, dass die Debug-Strings "Will I1 ausschalten!", "Will I1 einschalten!" werden gedruckt, aber der Status der Ausgänge wird nicht geändert (oder mit einer Verzögerung von ein paar Sekunden geändert).
Ich fragte mich, ob jemand wissen würde, was ich falsch mache?
Danke.
Aus meiner Erfahrung wird die Embedded-FW nicht verlangsamen. Wie überprüfen Sie den Ausgangszustand? Ist es möglich, dass das serielle oder Debug-Terminal langsamer wird? Und wie viel Verzögerung lässt du zwischen den Frames, die du sendest? – Julien
Am Ausgang ist eine Glühbirne angeschlossen. Die Verzögerung zwischen folgenden Befehlen beträgt etwa eine Sekunde, da ich immer noch debugge. – TheAptKid