2017-09-04 194 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(),的定义,但您没有使用它。所以我怀疑你从来没有启用输出驱动程序。通过设置端口寄存器,您只需启用弱上拉。也许这不够强大,无法快速开启继电器驱动程序。那个驱动器电路中有电容器吗?