在 8 位 UART 上发送 16 位值

Sending 16 bit values on 8 bit UART

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

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

//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

首先,即使您禁用了中断,在中断例程中使用 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);
    }
}

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