2013-03-07 6 views
3

ПроблемаPIC32 UART Drops байт

  • Внешний источник посылает эти четыре байта 0x2A, 0x42, 0x78, 0x25
  • PIC32 UART не генерирует INT
  • Внешний источник посылает еще один байт
  • The PIC32 УАПП then генерирует int
  • В этом int отображается только 0x25 байт из предыдущей передачи
  • т.е. первые три исчезают
  • Однажды в некоторое время (может быть, 5% времени) УАПП действительно производит все 4 байта правильно

[пятница вечер отладки Результаты]

Мы написали другое эхо-рутина; он просто читает, что получает, и записывает его обратно.

Мы построили его в режиме выпуска (по рекомендации другого здесь)

Я написал процедуру, чтобы отправить такое же количество из 25 раз, и посмотреть, что я вернусь.

После этого я ввожу значение и отправляю его 25 раз, и цикл.

Результаты прилагаются в конце этого сообщения.

Я не получаю первый байт обратно. Основываясь на разных факторах, я не буду беспокоиться об этом в этот момент.

Следующие пять раундов, я получаю все обратно совершенно

Я постараюсь включить все соответствующие исходные коды, надеюсь, что это не стена текста. Если для понимания этого требуется больше кода, пожалуйста, спросите.

Это код инициализации UART в вопросе. Я могу включать

//*****************************************************************// 
    void initUART1(void) // UART1 for MCU1/2 communication 
    { 
    U1MODE=0;      //// Mode Register, Manual DS61168D page 180 
    U1MODEbits.FRZ=0; 
    U1MODEbits.SIDL=0; 
    U1MODEbits.IREN=0; 
    U1MODEbits.RTSMD=0; 

    U1MODEbits.UEN=0b00;   //// Just TX/RX, No CTS/RTS 

    U1MODEbits.WAKE=1; 
    U1MODEbits.LPBACK=0; 
    U1MODEbits.ABAUD=0; 
    U1MODEbits.RXINV=0; 
    U1MODEbits.BRGH=1; 
    U1MODEbits.PDSEL=0b00; 
    U1MODEbits.STSEL=0; 

    U1STA=0; 
    U1STAbits.ADM_EN=0; 
    U1STAbits.UTXINV=0; 
    U1STAbits.URXEN=1; 
    U1STAbits.UTXBRK=0; 
    U1STAbits.UTXEN=1; 
    U1STAbits.ADDEN=0; 
    U1STAbits.OERR=0;  
           //// Status register, Manual DS61168D page 183 

    //U1BRG=21;     //// 21 for 921600 (80 MIPS) 
    U1BRG=172;     //// 172 for 115200 (80 MIPS) 

    IFS0bits.U1RXIF=0; 
    IPC6bits.U1IP=5; 
    IPC6bits.U1IS=3; 
    IEC0bits.U1RXIE=1; 

    U1MODEbits.ON=1; 
    } 


    //*****************************************************************// 

Это процедура обработки прерывания, которое обрабатывает конкретные UART

//*********************************************************// 
    void __ISR(_UART1_VECTOR, ipl5) IntUart1Handler(void) //MCU communication port 
    {  
    if(INTGetFlag(INT_SOURCE_UART_RX(UART1))) //if it's a rx interrupt 
    { 
     U1RxBuf=UARTGetDataByte(UART1); 

    switch (CmdRecording) 
    { 
    case 0: 
      if(U1RxBuf=='*') 
      { 
      CmdRecording=1; //set the cmd recording flag 
      Command_U1[0]=U1RxBuf; 
      TimeOut=1; //time out=1 means the timeout for MCU1 command receiver is enabled 
      initT3(0x0100); //time out=0 means the timeout for MCU1 command receiver is enabled 
      } 
      else 
     { 
      putcharUART1('$'); 
      putcharUART1('e'); 
      putcharUART1('2'); 
      putcharUART1('%'); 
     } 
      break; 
    case 1: 
      CmdRecording=2; //set the cmd recording flag 
      Command_U1[1]=U1RxBuf; 
      break; 
    case 2: 
      CmdRecording=3; //set the cmd recording flag 
      Command_U1[2]=U1RxBuf; 
      break; 
    case 3: 
      CmdRecording=0; //reset the cmd recording flag 
      Command_U1[3]=U1RxBuf; 
      if(U1RxBuf=='%') //if this is the last command byte 
      { 
       if((Command_U1[1]=='O')) 
      { 
       CMD_Err=0;  //clear error 
      CMD_OK=1;  //send cmd OK; 
      } 
       else if((Command_U1[1]=='e')) 
      { 
       CMD_OK=0;  //clear OK 
      CMD_Err=1;  //send cmd Err; 
      } 
      else 
      Command_flag=1; 
      } 
      else 
      { 
      Command_flag=0; 
      } 

      disableT3(0); //the command receiving is done, disable the time out #0 (command receving time out) 
      TimeOut=0; //the command receiving is done, disable the time out 

      break; 
    default: 
      break; 
    } 
    INTClearFlag(INT_SOURCE_UART_RX(UART1)); 
    } 

    if (INTGetFlag(INT_SOURCE_UART_TX(UART1))) //if it's a tx interrupt 
    { 
     INTClearFlag(INT_SOURCE_UART_TX(UART1)); 
    } 
    } 

    //***********************************************// 

Это данные, которые я видел при запуске байт через систему «эхо»; то есть подпрограмма, которая считывает один, записывает один.

PIC-32 работает на частоте 80 МГц, а UART - 115200 бит/с, поэтому меня не беспокоит скорость.

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 
    02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 
    03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 
    04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 
    05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 
+1

«Появляется только последний байт» - где? У вас есть этот массив Command_U1 - что находится в четырех байтах? –

+0

Ваш ISR в первую очередь связан с RX, для TX он просто очищает флаг прерывания - я бы предположил, что это вовсе не «все соответствующие исходные коды» – Clifford

+0

Command-U1 содержит '0x00, 0x00, 0x00, 0x00' –

ответ

5

Похоже, UART, вероятно, имеет 4 байт FIFO и не генерирует прерывание, пока FIFO не заполнится. Я не знаком с этой частью, но часто вы можете запрограммировать UART для генерации прерывания на определенном уровне FIFO или после тайм-аута n-символа, чтобы можно было считывать данные в неполном FIFO. Кроме того, если это так, ваш ISR должен зацикливаться до тех пор, пока FIFO не будет опустошен, вместо простого чтения одного символа.

+0

Код Init (предположительно) устанавливает UART для генерации int на каждый байт. Я отправил ему пятый байт (жаль, что редактирование пересекает интернет-облако), и я получил четвертый. Я продолжаю использовать однобайтовые передачи. –

+0

Вы думаете? Я просто посмотрел на лист данных, и вам нужно запрограммировать 'U1STAbits.URXISEL = 0'. Я не вижу этого в вашем коде. – Clifford

+0

, если вы правы, и я ошибаюсь, СПАСИБО !!! Позвольте мне рассмотреть. U1STA удерживает '0x00001510', который, как представляется, устанавливает URXISEL = 0, т. Е. Из Manual DS61168D-page 183, говорят: * 00 = бит флага прерывания утверждается, в то время как буфер приема не пуст (т. Е. Имеет как минимум 1 символ данных) * если у меня мои биты правильные. Кроме того, секция init имеет 'U1STA = 0;' в начале, которая должна очистить все. Но держите идеи в движении. Я продолжаю эксперименты с одним байтом. –

Смежные вопросы