use*_*581 2 c embedded firmware msp430
我需要有关处理UART通信的正确方法的建议.我觉得我已经完成了通过UART发送串行命令的处理,但我不知道我解析响应或接收串行数据的方式是否是最好的方法.任何提示都很受欢迎,但我只是想知道是否有更好,更优雅的解析UART RX的方法.
这是一个MSP430 uC的方式......
首先,我在头文件中声明了这些:
const unsigned char *UART_TX_Buffer;
unsigned char UART_TX_Index;
unsigned char UART_TX_Length;
unsigned char UART_TX_Pkt_Complete;
unsigned char UART_RX_Buffer[25];
unsigned char UART_RX_Pkt_Complete;
unsigned char UART_RX_Index;
Run Code Online (Sandbox Code Playgroud)
这是在ISR中设置标志UART_RX_Pkt_Complete后调用的函数:
void Receive_Resp()
{
switch (UART_RX_Buffer[UART_RX_Index - 3])
{
case 0x4B:
break;
case 0x56:
P1OUT &= ~(tos_sel0 + tos_sel1);
break;
case 0x43:
P1OUT |= tos_sel0;
P1OUT &= ~tos_sel1;
break;
case 0x34:
P1OUT |= tos_sel1;
P1OUT &= ~tos_sel0;
break;
case 0x33:
P1OUT |= tos_sel0 + tos_sel1;
break;
default:
break;
}
UART_RX_Pkt_Complete = 0;
UART_RX_Index = 0;
}
Run Code Online (Sandbox Code Playgroud)
这里是RX ISR的参考:
#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCIA0RX_ISR(void)
{
UART_RX_Buffer[UART_RX_Index++] = UCA0RXBUF;
if (UART_RX_Buffer[UART_RX_Index - 1] == 0x0A)
{
UART_RX_Pkt_Complete = 1;
_BIC_SR_IRQ(LPM3_bits);
}
IFG2 &= ~UCA0RXIFG;
}
Run Code Online (Sandbox Code Playgroud)
这里还有TX ISR并发送UART命令例程:
if (UART_TX_Index < UART_TX_Length) // Check if there are more bytes to be sent
{
UCA0TXBUF = UART_TX_Buffer[UART_TX_Index++];
}
else // Last byte has been sent
{
UART_TX_Pkt_Complete = 1; // Set flag to show last byte was sent
_BIC_SR_IRQ(LPM3_bits);
}
IFG2 &= ~UCA0TXIFG;
void Send_CMD (const unsigned char *Data, const unsigned char Length)
{
UART_TX_Buffer = Data; // Move into global variables
UART_TX_Length = Length;
UART_TX_Pkt_Complete = 0; // Starting values
UART_RX_Pkt_Complete = 0;
UART_TX_Index = 0;
UCA0TXBUF = UART_TX_Buffer[UART_TX_Index++];
while(!UART_TX_Pkt_Complete)
{
Delay(5,'u');
}
while(!UART_RX_Pkt_Complete)
{
Delay(5,'u');
}
}
Run Code Online (Sandbox Code Playgroud)
如果这样可以满足您的系统要求,那就没关系.但有几种方法可以改进.
Receive_Resp()并且USCIA0RX_ISR()是紧密耦合的,这是不希望的.它们都UART_RX_Index为另一个操作(USCIA0RX_ISR()递增并Receive_Resp()清除它),并且它们都依赖于另一个来构成每个消息的部分(USCIA0RX_ISR()在Receive_Resp()解释和重置下一帧时找到帧的结尾).如果将这些例程解耦,那会更好.ReceiveResp()例程不会处理任何错误,例如丢弃的字符.它假定所有三个字符都被正确接收.也许这对您的应用和要求很好.但通常应该在这里执行一些错误检查.至少你应该UART_RX_Index >= 3在从它中减去3之前确保它.换句话说,确保消息长度合理.更健壮的串行协议将在每个帧中具有校验和或CRC,以确保正确接收帧,但这可能对您的应用程序而言过度.请来电来Delay的Send_CMD()意思是你的应用程序完全停顿,而它的等待完成传输?再一次,也许这对你的应用来说没问题,但通常这是不可取的.通常,您希望应用程序即使在等待UART准备好传输时也能继续运行.通过使用循环发送缓冲区,可以在发送缓冲区中排队多个消息,并且在排队另一个消息之前不必等待先前的消息完成.但是,您应该为缓冲区溢出添加保护,这可能会使您不必要地复杂化.这让我回到了我的第一点,如果你有什么工作并满足你的要求,那就没关系了.