Отправка 16-битных значений на 8-битном UART - PullRequest
0 голосов
/ 30 апреля 2018

Мы пытаемся отправить 16-битное значение из одного PSoC в другой. Суть этой операции должна быть довольно простой:

  • Разделить значение на два 8-битных значения, одно для MSB и одно для LSB
  • Отправьте MSB, а затем LSB из системы 1
  • Получите MSB и затем LSB в системе 2
  • Объединить два байта путем сдвига битов 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);

Проблема в том, что этот код не соответствует. И мы почти никогда не получаем те же данные, что отправляем.

Другая проблема возникает, когда мы пытаемся отправить данные на компьютер с помощью функции UART_USB_PutString в системе 2. Мы получаем два набора% d \ n \ r в терминале замазки, один из которых может быть отправлено правильное значение и другой, который кажется довольно случайным.


Другая информация

Имейте в виду, что мы впервые работаем с UART в любых условиях, поэтому мы также можем использовать советы и рекомендации, если они у вас есть. Если вам нужна какая-либо другая информация или у вас есть идеи, как починить этот сломанный кусок дерьма, сообщите нам.

С уважением, два студента электроники noob работают над PSoC

\ de_rush

1 Ответ

0 голосов
/ 30 апреля 2018

Прежде всего, использование 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);
    }
}

Но помните - когда вы отправляете данные отладки, может появиться много других значений, и вы можете что-то потерять. Вам необходимо реализовать буфер цикла - но это выходит за рамки этого вопроса.

...