首页 > 解决方案 > 在 8 位 UART 上发送 16 位值

问题描述

我们正在尝试从一个 PSoC 向另一个 PSoC 发送一个 16 位值。这个操作的本质应该很简单:

所以我们这样做的方式在实践中是:

//Split and send
uint16 utest = (uint16)test;
uint8 hibyte = utest>>8;
uint8 lowbyte = utest;        
UART_PutChar(hibyte);
UART_PutChar(lowbyte);

系统 2(收到字节的 ISR):

//Recieve and merge
uint8 rx_msb = UART_GetByte();
uint8 rx_lsb = UART_GetByte();
rx_udata = ((uint16)rx_msb << 8) | rx_lsb;
sprintf(TransmitBufferUSB,"%d\n\r",rx_udata);
UART_USB_PutString(TransmitBufferUSB);

问题是这段代码不一致。而且我们似乎从来没有收到我们发送的相同数据。

当我们尝试通过系统 2 中的 UART_USB_PutString 函数将数据发送到计算机时,会出现另一个问题。我们在 putty 终端中接收到两组 %d\n\r,其中一组可能是发送的正确值,另一组可能是发送的正确值这似乎相当随机。


其他信息

请记住,这是我们第一次在任何环境中使用 UART,因此如果您有任何提示和技巧,我们也可以使用。如果您需要任何其他信息或对如何修复这个破碎的狗屎有任何想法,请告诉我们。

真诚的两位从事 PSoC 工作的电子学菜鸟学生

\de_rush

标签: cuartpsoccypress-psoc

解决方案


首先,即使您禁用了中断,在中断例程中使用 sprintf 也是一个非常糟糕的主意。更糟糕的是在那里发送数据:) 你可能是一个非常非常初学者。始终保持中断程序尽可能短。

将调试代码移到中断之外。

其次,您只能读取在中断中收到的内容(一个字节),然后读取两个。

最后,我不认为它UART_GetByte被发明用于中断例程。只需读取数据寄存器即可。

我个人更喜欢工会。

typedef union
{
    uint16_t u16;
    int16_t i16;
    uint8_t b[2];
}data16;

volatile data16 revcb, tb;  // tb can be local and not volatile
volatile int pointer = 0;
volatile int flag = 0;

CY_ISR(UART_ISR){
    Status_pin_Write(0xFF); //Used for debugging
    revcb.b[pointer] = dataregister;  // place the appripriate code here
    pointer = ! pointer;
    if(!pointer) flag = 1;
    Status_pin_Write(0x00);
}

//in the main function

while(1)
{
    if(flag) 
    {
        ISR_Rx_Disable();   // make it atomic
        tb = recv;
        flag = 0;
        ISR_Rx_Enable();
        sprintf(TransmitBufferUSB,"%d\n\r",tb.u16);
        UART_USB_PutString(TransmitBufferUSB);
    }
}

但请记住 - 当您发送调试数据时 - 许多其他值可能会出现,您可能会丢失一些东西。您需要实现一个循环缓冲区 - 但这超出了这个问题的范围。


推荐阅读