首页 文章

在8位UART上发送16位值

提问于
浏览
1

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

  • 将值拆分为两个8位值,一个用于MSB,一个用于LSB

  • 从系统1发送MSB,然后发送LSB

  • 在系统2上接收MSB然后接收LSB

  • 通过移位MSB然后对LSB进行OR屏蔽来合并两个字节 .

  • 利润

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

//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,因此如果您有任何设置,我们也可以使用提示和技巧 . 如果您需要任何其他信息或有任何想法如何解决这个破碎的狗屎请告诉我们 .

真诚的两位noob电子学生在PSoC上工作

\ de_rush

1 回答

  • 2

    首先在中断例程中使用sprintf是一个非常糟糕的想法甚至id禁用中断 . 更糟糕的是将数据发送到那里:)你可能是一个非常非常初学者 . 始终保持中断例程尽可能短 .

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

    其次,你只能读取你在中断中收到的内容(这是一个字节)而你只读了两个 .

    最后,我不认为 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);
        }
    }
    

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

相关问题