Форум Микро-Чип
Поиск и заказ электронных компонентов
 

Вернуться   Форум Микро-Чип > Продукция MICROCHIP

Продукция MICROCHIP Технические вопросы по всей продукции Microchip

Ответ
 
Опции темы Опции просмотра
Старый 29.06.2014, 21:26   #1
valery1966
Junior Member
 
Регистрация: 10.11.2011
Сообщений: 15
Вес репутации: 100/31
valery1966 will become famous soon enoughvalery1966 will become famous soon enough
По умолчанию PIC32 DMA UART сбои при передаче

Доброго дня.
Работаю с PIC32MX360F512L. По UART (RS485) в режиме DMA принимаю запрос, его обрабатываю и передаю данные с использованием канала DMA. Прерывание приема формируется по приему символе конца пакета, прерывание завершения передачи - по передаче определенного кол-ва байт.
Время от времени при передаче получаются сбои. Складывается ощущение, что счетчик отправленных байт канала DMA обнуляется и передача начинается по новой, т.е. к передаваемому пакету подстыковывается еще один такой же.

Код инициализации каналов DMA:
Код:
//---------------------------------------------------------------------------
// Настройка DMA приема
void DMA_Rd_Open (int Chn)
{           
  DmaChnOpen (Chn, DMA_CHN_PRI2, DMA_OPEN_MATCH);
  DmaChnSetMatchPattern (Chn, LAST_SIM);
  // Прерывание завершения приема формируется обнаружению LAST_SIM
  DmaChnSetEventControl (Chn,  DMA_EV_START_IRQ_EN | DMA_EV_MATCH_EN | DMA_EV_START_IRQ(_UART2_RX_IRQ));
  DmaChnSetTxfer (Chn, 
                  (void*)&U2RXREG,                         // Data source
                  (void*)&UARTRcvData [0],                 // Dest addresses
                  1,                                       // Source buffer size, 1 to DmaGetMaxTxferSize() - The maximum transfer capacity for a DMA channel, in bytes)
                  sizeof(UARTRcvData),                     // Destination buffer size, 1 to DmaGetMaxTxferSize() bytes
                  1);                                      // Cell transfer size, 1 to DmaGetMaxTxferSize() bytes
  DmaChnSetEvEnableFlags (Chn, DMA_EV_BLOCK_DONE);
  INTEnable (INT_SOURCE_DMA (Chn), INT_ENABLED);            
  DmaChnEnable (Chn);
}

//---------------------------------------------------------------------------
// Настройка DMA передачи
void DMA_Tr_Open (int Chn, int TrDataSize, BYTE* TrData)
{
  avixSFR_SF(LATD, RS_485_TR_L, ON_);

  UART_WDT_TMR_START                                       // Ожидаем 25мс и сбрасываем RS_485_TR 

  DmaChnOpen (Chn, DMA_CHN_PRI2, DMA_OPEN_DEFAULT);
  // Прерывание завершения передачи формируется при передаче TrDataSize
  DmaChnSetEventControl (Chn, DMA_EV_START_IRQ_EN | DMA_EV_START_IRQ (_UART2_TX_IRQ));
  DmaChnSetTxfer (Chn, (void*)TrData, (void*)&U2TXREG, TrDataSize, 1, 1);
  DmaChnSetEvEnableFlags (Chn, DMA_EV_BLOCK_DONE);
  INTEnable (INT_SOURCE_DMA (Chn), INT_ENABLED);
  DmaChnEnable (Chn);                                          
}
Прием и передача обрабатываются в прерываниях:
Код:
//---------------------------------------------------------------------------
// Прерывание канала DMA1 - прием и проверка запроса до 50 мкс
// формирование прерывания - фиксация символа конца пакета 0x0D
// Проверка сетевого адреса и КС осуществляются тут-же
void __ISR (_DMA1_VECTOR, ipl5) _DMA_RX_ISR (void)
{    
  INTClearFlag (INT_SOURCE_DMA (DMA_Rd_Chn));               // release the interrupt in the INT controller, we're servicing int
  int evFlags = DmaChnGetEvFlags (DMA_Rd_Chn);               // event flags when getting the interrupt
  int i = 0;

  // Приемный буфер забился пустой посылкой
  if (evFlags & DMA_EV_DST_FULL)
  { 
      DmaChnClrEvFlags (DMA_Rd_Chn, DMA_EV_ALL_EVNTS);
    DMA_Rd_Open (DMA_Rd_Chn);
    if (U2STAbits.OERR)
      U2STAbits.OERR = 0;                                  // Очистили буфер UART
    for (i = 0; i < RCV_BUFSIZE; i ++)
      UARTRcvData [i] = 0;
    return;
  }

  // Принят символ LAST_SIM
  if (evFlags & DMA_EV_BLOCK_DONE)
  { 
    int  UARTDataSize = 0;
    BYTE AddrFromCmd = 255;

      DmaChnClrEvFlags (DMA_Rd_Chn, DMA_EV_ALL_EVNTS);

    DMA_Rd_Open (DMA_Rd_Chn);

    // Проверка приамбулы  
    FirstByteNum = 0;
    if (FIRST_CMD_SIM != UARTRcvData [0])
    {
      // Первый байт - не приамбула!
      for (i = 1; i < RCV_BUFSIZE; i ++)
      {
        if (FIRST_CMD_SIM == UARTRcvData [i])
        {
          FirstByteNum = i;
          break;
        }
      }
      if (0 == FirstByteNum)
      {
        if (U2STAbits.OERR)
          U2STAbits.OERR = 0;                              // Очистили буфер UART
        return;
      }
    }  
    // Проверка адреса 
    AddrFromCmd = StrToByte (UARTRcvData [FirstByteNum + 2]);       
    if (DevAddr != AddrFromCmd)
    {
      return;
    }

    // Расчет длины пакета
    for (i = FirstByteNum; i < RCV_BUFSIZE; i ++)
    {
      if (LAST_SIM == UARTRcvData [i])
      {
        UARTDataSize = i - FirstByteNum - 1;
        break;
      }
    }

    // Расчет CRC
    if (CalcRcvCheckSum ((BYTE*)&UARTRcvData [FirstByteNum], UARTDataSize))
    {
      if (U2STAbits.OERR)
        U2STAbits.OERR = 0;                                // Очистили буфер UART
      for (i = 0; i < RCV_BUFSIZE; i ++)
        UARTRcvData [i] = 0;
      return;
    }  

    CmdID = UARTRcvData [FirstByteNum + 3];

    // Измерения передаются через ПДП, остальные запросы
    // обрабатываются в DATA_PARSE
    switch (CmdID)
    {      
      case GET_VOLTAGE: 
      {
        if (TRUE == ChOne)
          DMA_Tr_Open (DMA_Tr_Chn, LENGTH_TO_TR, (BYTE*)&U2_ToTr [0]);   
        else
          DMA_Tr_Open (DMA_Tr_Chn, LENGTH_TO_TR, (BYTE*)&U1_ToTr [0]);  

        DmaChnStartTxfer (DMA_Tr_Chn, DMA_WAIT_NOT, 0); 
      }
        break;


      default:
        break;
    }
  }
  if (1 == U2STAbits.OERR)
    U2STAbits.OERR = 0; 
}

//---------------------------------------------------------------------------
// Прерывание канала DMA0 - передача - завершение - снятие строба RS_485_TR
void __ISR (_DMA0_VECTOR, ipl5) _DMA_TX_ISR (void)
{
  INTClearFlag (INT_SOURCE_DMA (DMA_Tr_Chn));               // release the interrupt in the INT controller, we're servicing int
  int evFlags = DmaChnGetEvFlags (DMA_Tr_Chn);               // get the event flags
  if (evFlags & DMA_EV_BLOCK_DONE)
  { 
       DmaChnClrEvFlags (DMA_Tr_Chn, DMA_EV_BLOCK_DONE); 
    while (!U2STAbits.TRMT){}; 

    avixSFR_SF(LATD, RS_485_TR_L, OFF_); 
  }
}
Общая настройка каналов DMA имеет вид:
Код:
  INTSetVectorPriority (INT_VECTOR_DMA (DMA_Rd_Chn), INT_PRIORITY_LEVEL_5);
  INTSetVectorSubPriority (INT_VECTOR_DMA (DMA_Rd_Chn), INT_SUB_PRIORITY_LEVEL_0);
  DMA_Rd_Open (DMA_Rd_Chn);
  INTSetVectorPriority (INT_VECTOR_DMA (DMA_Tr_Chn), INT_PRIORITY_LEVEL_5);
  INTSetVectorSubPriority (INT_VECTOR_DMA (DMA_Tr_Chn), INT_SUB_PRIORITY_LEVEL_1);
//  DMA_Tr_Open (DMA_Tr_Chn);
  INTConfigureSystem (INT_SYSTEM_CONFIG_MULT_VECTOR);
  INTEnableInterrupts();
Сбои происходят не регулярно и я пока связываю их с помехами по цепям питания контроллера. Или где-то косяк в коде?
Буду рад услышать конструктивные предложения.
С уважением...
valery1966 вне форума   Ответить с цитированием
Старый 30.06.2014, 15:09   #2
Vint
Senior Member
 
Аватар для Vint
 
Регистрация: 08.06.2007
Сообщений: 530
Вес репутации: 838/60
Vint is a splendid one to beholdVint is a splendid one to beholdVint is a splendid one to beholdVint is a splendid one to beholdVint is a splendid one to beholdVint is a splendid one to beholdVint is a splendid one to behold
По умолчанию

Я мучался с похожей проблемой с UART PIC32MX320.
Особенно в мультивекторном режиме. На С32 v1.12
удалось победить, но некоторые прерывания (не uart)
пришлось пустить по опросу, плюс распределение
уровней приоритетов.

На С32 v2.02 затыкается практически сразу,
программа работает, но uart система
не видит и для оживления только ресет. Volitale и др.
приспособления не помогли. На XC32 тоже сбоит.
Vint вне форума   Ответить с цитированием
Старый 30.06.2014, 16:32   #3
Venom
Senior Member
 
Регистрация: 19.05.2009
Сообщений: 319
Вес репутации: 127/44
Venom will become famous soon enoughVenom will become famous soon enough
По умолчанию Re: PIC32 DMA UART сбои при передаче

Вот спинным мозгом чую: это МПЛАБ Х и ХС32 глючит по-черному.
Сейчас с тем же воюю, но на pic32MZ. Я закомментировал строку инициализации Таймера 3, но всё равно после неоднократной компиляции и перепрограммирования таймер инициализирован!
Venom вне форума   Ответить с цитированием
Старый 30.06.2014, 17:02   #4
Vanizma
Senior Member
 
Аватар для Vanizma
 
Регистрация: 30.04.2008
Адрес: Pskov
Сообщений: 4,131
Вес репутации: 4577/129
Vanizma has a reputation beyond reputeVanizma has a reputation beyond reputeVanizma has a reputation beyond reputeVanizma has a reputation beyond reputeVanizma has a reputation beyond reputeVanizma has a reputation beyond reputeVanizma has a reputation beyond reputeVanizma has a reputation beyond reputeVanizma has a reputation beyond reputeVanizma has a reputation beyond reputeVanizma has a reputation beyond repute
Отправить сообщение для Vanizma с помощью ICQ
По умолчанию Re: PIC32 DMA UART сбои при передаче

Цитата:
Сообщение от Venom Посмотреть сообщение
Вот спинным мозгом чую: это МПЛАБ Х и ХС32 глючит по-черному.
Сейчас с тем же воюю, но на pic32MZ. Я закомментировал строку инициализации Таймера 3, но всё равно после неоднократной компиляции и перепрограммирования таймер инициализирован!
ни одного глюка не видел XC32... если делать очистку и полную компиляцию каждый раз
__________________

Vanizma вне форума   Ответить с цитированием
Старый 30.06.2014, 18:50   #5
Venom
Senior Member
 
Регистрация: 19.05.2009
Сообщений: 319
Вес репутации: 127/44
Venom will become famous soon enoughVenom will become famous soon enough
По умолчанию Re: PIC32 DMA UART сбои при передаче

Ну вот какая картина:
Прерывание таймера:
Код:
void __attribute__((vector(_TIMER_3_VECTOR), interrupt(IPL7AUTO), nomips16)) _T3Interrupt(void)
{

        LATBbits.LATB9=b;
        LATBbits.LATB10=~b;


   b^=1;

  SendUD1(170);
   _T3IF=0; 
}
А это инициализация системы:
Код:
void initilize (void)
{  
    asm volatile("ei");
    RemapPorts();
    IniPorts();
    LATBbits.LATB11=1;
    OutComp();
   //IniT3();
    IniUART1();

   LATBbits.LATB11=0;

   asm volatile("ei");
}
Нажимаю кнопку с молотком и метлой, а потом зашиваю и вижу размахивание ногами на ногах, которые должны меняться по прерыванию таймера (см.описание прерывания).
Нажимаю кнопку дебаггера и ставлю брейкпойнты на прерывании таймера. Он на них останавливается, но при этом дебаггер показывает, что в таймер не запущен и не сконфигурирован.
Venom вне форума   Ответить с цитированием
Старый 30.06.2014, 22:16   #6
Vanizma
Senior Member
 
Аватар для Vanizma
 
Регистрация: 30.04.2008
Адрес: Pskov
Сообщений: 4,131
Вес репутации: 4577/129
Vanizma has a reputation beyond reputeVanizma has a reputation beyond reputeVanizma has a reputation beyond reputeVanizma has a reputation beyond reputeVanizma has a reputation beyond reputeVanizma has a reputation beyond reputeVanizma has a reputation beyond reputeVanizma has a reputation beyond reputeVanizma has a reputation beyond reputeVanizma has a reputation beyond reputeVanizma has a reputation beyond repute
Отправить сообщение для Vanizma с помощью ICQ
По умолчанию Re: PIC32 DMA UART сбои при передаче

Цитата:
Сообщение от Venom Посмотреть сообщение
Ну вот какая картина:
Прерывание таймера:
Код:
void __attribute__((vector(_TIMER_3_VECTOR), interrupt(IPL7AUTO), nomips16)) _T3Interrupt(void)
{

        LATBbits.LATB9=b;
        LATBbits.LATB10=~b;


   b^=1;

  SendUD1(170);
   _T3IF=0; 
}
А это инициализация системы:
Код:
void initilize (void)
{  
    asm volatile("ei");
    RemapPorts();
    IniPorts();
    LATBbits.LATB11=1;
    OutComp();
   //IniT3();
    IniUART1();

   LATBbits.LATB11=0;

   asm volatile("ei");
}
Нажимаю кнопку с молотком и метлой, а потом зашиваю и вижу размахивание ногами на ногах, которые должны меняться по прерыванию таймера (см.описание прерывания).
Нажимаю кнопку дебаггера и ставлю брейкпойнты на прерывании таймера. Он на них останавливается, но при этом дебаггер показывает, что в таймер не запущен и не сконфигурирован.
я ничего не понял. но вопрос - оптимизация включена? если да, то предсказать работу gcc отладчиком практически не реально, переменные не отследить. даже volatile не помогает.
но работает правильно
__________________

Vanizma вне форума   Ответить с цитированием
Старый 01.07.2014, 09:55   #7
besogon
Senior Member
 
Регистрация: 12.07.2012
Возраст: 33
Сообщений: 2,187
Вес репутации: 4133/90
besogon has a reputation beyond reputebesogon has a reputation beyond reputebesogon has a reputation beyond reputebesogon has a reputation beyond reputebesogon has a reputation beyond reputebesogon has a reputation beyond reputebesogon has a reputation beyond reputebesogon has a reputation beyond reputebesogon has a reputation beyond reputebesogon has a reputation beyond reputebesogon has a reputation beyond repute
По умолчанию Re: PIC32 DMA UART сбои при передаче

Venom
Вот как сказать-то..
смотрю я на инициализацию Вашей системы и понимаю, что маловато.
не может быть такого, чтобы pic32mx инициализировался столь коротко.
Там же кеш/префетчер настраивать, dma настраивать и.т.д - это довольно-таки некороткое дело.
почитайте внимательней.
*
я так понял вы plib используете - попробуйте без всего этого - уверен, Вы разберетесь и все будет нормально.
***
IPLxAUTO - зачем? почти всегда можно определить, кому отдать SRS, кому довольствоваться стеком. весьма нечасто, на мой взгляд, имеет смысл использовать auto.
besogon вне форума   Ответить с цитированием
Старый 01.07.2014, 16:55   #8
valery1966
Junior Member
 
Регистрация: 10.11.2011
Сообщений: 15
Вес репутации: 100/31
valery1966 will become famous soon enoughvalery1966 will become famous soon enough
По умолчанию Re: PIC32 DMA UART сбои при передаче

Хочется подвести итог этому оживленному обсуждению.
При ближайшем рассмотрении осциллографом схемы электрической принципиальной были обнаружены помехи из линии поступающие на вход UART и вызывающие не обнулние счетчика переданных байт, а ложное прерывание приема команды запроса. Они были подавлены, и логика программы заработала как я и планировал.
Т.о. могу предположить, что работа с DMA была реализована корректно.
С уважением
ПС Кстати компилятором я пользуюсь pic32-gcc.exe v2.02 и сильных нареканий к нему нет.
valery1966 вне форума   Ответить с цитированием
Старый 01.07.2014, 17:11   #9
Venom
Senior Member
 
Регистрация: 19.05.2009
Сообщений: 319
Вес репутации: 127/44
Venom will become famous soon enoughVenom will become famous soon enough
По умолчанию Re: PIC32 DMA UART сбои при передаче

Дальнейшую беседу я думаю перенести в основной раздел по соседству, посвященный 32MZ. Ответы мои на Ваши посты там

Прямая ссылка.
http://www.microchip.su/showthread.p...283#post203283
Venom вне форума   Ответить с цитированием
Ответ


Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 
Опции темы
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Имитатор DS18B20 Filya44 Вопросы начинающих 14 12.03.2012 17:39
DMA в dsPIC33 - помогите! Andy1982 Продукция MICROCHIP 8 12.11.2010 19:21
PIC32 реализация Modbus RTU c DMA Otuck Продукция MICROCHIP 5 09.07.2010 08:33
Потери при передаче по RS-232 Varcharamir Вопросы начинающих 16 17.02.2010 06:53
Второй байт команды при передаче в PS/2 клавиатуру DL36 Общетехнические вопросы 2 21.07.2007 17:11


Часовой пояс GMT +3, время: 06:22.


Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd. Перевод: zCarot