2017-09-04 5 views
1

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.

+0

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

+0

Am Ausgang ist eine Glühbirne angeschlossen. Die Verzögerung zwischen folgenden Befehlen beträgt etwa eine Sekunde, da ich immer noch debugge. – TheAptKid

Antwort

1

Sie haben eine nette Definition von set_output(),, aber Sie verwenden es nicht. Also vermute ich, dass du den Ausgangstreiber nie aktiviert hast. Indem Sie das Port-Register einstellen, aktivieren Sie nur das schwache Pull-Up. Vielleicht ist das nicht stark genug, um Ihren Relay-Treiber schnell einzuschalten. Haben Sie einen Kondensator in dieser Treiberschaltung?