延迟uart命令执行
问题描述:
我正在写一个小型嵌入式程序,在那里我通过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设置为开启!”被打印,但输出的状态不会改变(或者延迟几秒钟而改变)。
我想知道是否有人会知道我做错了什么?
谢谢。
答
您有一个很好的set_output(),
的定义,但您没有使用它。所以我怀疑你从来没有启用输出驱动程序。通过设置端口寄存器,您只需启用弱上拉。也许这不够强大,无法快速开启继电器驱动程序。那个驱动器电路中有电容器吗?
根据我的经验,嵌入式固件不会减慢。你如何检查输出状态?串行或调试终端可能会变慢吗?你发送的帧之间有多少延迟? – Julien
有一个灯泡连接到输出。后续命令之间的延迟大约一秒钟,因为我仍在调试。 – TheAptKid