延迟的uart命令执行

时间:2017-09-04 15:44:28

标签: embedded avr atmega

我正在编写一个小型嵌入式程序,我将一些命令通过uart发送到atmega328p芯片。命令以字符$开头,以字符#结束(所以我知道何时执行解析)。收到命令后,我解析它并打开设备(COMMAND:TURN_ON_I1)或关闭(COMMAND:TURN_OFF_I1)。该应用程序目前看起来像这样:

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

我注意到,在发送命令大约七或八次(或更多)后,串行通信中断或命令执行延迟。我还可以看到,调试字符串&#34;将I1设置为关闭!&#34;,&#34;将设置I1!&#34;打印,但输出状态不会改变(或延迟几秒钟更改)。

我想知道是否有人知道,我做错了什么?

感谢。

1 个答案:

答案 0 :(得分:1)

您对set_output(),有一个很好的定义,但您没有使用它。所以我怀疑你从未启用输出驱动程序。通过设置端口寄存器,您只需启用弱上拉。也许这还不够强大,无法快速打开继电器驱动器。那个驱动电路中有电容吗?