在8位UART

时间:2018-04-30 09:06:33

标签: c uart cypress psoc

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

  • 将值拆分为两个8位值,一个用于MSB,一个用于LSB
  • 从系统1发送MSB然后发送LSB
  • 在系统2上接收MSB然后接收LSB
  • 通过比特移位MSB然后对屏蔽LSB进行合并来合并两个字节。
  • 利润

所以我们这样做的方法是:

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

1 个答案:

答案 0 :(得分:2)

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

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