2017-09-04 192 views
1

我正在寫一個小型嵌入式程序,在那裏我通過uart發送一些命令到atmega328p芯片。這些命令以字符$開頭並以字符#結尾(所以我知道何時執行解析)。接收到命令後,我解析並打開設備(COMMAND:TURN_ON_I1)或關閉(COMMAND:TURN_OFF_I1)。該應用目前看起來是這樣的:延遲uart命令執行

// ------- 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); 
    } 

我注意到,我將命令發送後周圍七八次(或更多),串行通信中斷或該命令與延遲執行。我還可以看到,調試字符串「將I1設置爲關閉!」,「將I1設置爲開啓!」被打印,但輸出的狀態不會改變(或者延遲幾秒鐘而改變)。

我想知道是否有人會知道我做錯了什麼?

謝謝。

+0

根據我的經驗,嵌入式固件不會減慢。你如何檢查輸出狀態?串行或調試終端可能會變慢嗎?你發送的幀之間有多少延遲? – Julien

+0

有一個燈泡連接到輸出。後續命令之間的延遲大約一秒鐘,因爲我仍在調試。 – TheAptKid

回答

1

您有一個很好的set_output(),的定義,但您沒有使用它。所以我懷疑你從來沒有啓用輸出驅動程序。通過設置端口寄存器,您只需啓用弱上拉。也許這不夠強大,無法快速開啓繼電器驅動程序。那個驅動器電路中有電容器嗎?