【问题标题】:Delayed uart command execution延迟 UART 命令执行
【发布时间】:2017-09-04 15:44:27
【问题描述】:

我正在编写一个小型嵌入式程序,通过 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);
    }

我注意到在我发送命令大约七八次(或更多)后,串行通信中断或命令执行延迟。我还可以看到,调试字符串“Will set I1 off!”、“Will set I1 on!”已打印,但输出的状态未更改(或延迟几秒钟后更改)。

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

谢谢。

【问题讨论】:

  • 根据我的经验,嵌入式 FW 不会变慢。你如何检查输出状态?串行或调试终端是否可能变慢?您在发送的帧之间允许多少延迟?
  • 有一个灯泡连接到输出端。后续命令之间的延迟大约是一秒,因为我还在调试。

标签: embedded avr atmega


【解决方案1】:

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

【讨论】: