Перейти к содержанию
    

Проблема UART на Kinetis K70

странная проблема с UART.

сначала инициализация.

void UART_Init (UART_MemMapPtr uartch, int sysclk, int baud)
{
  register uint16_t sbr, brfa;
  uint8_t temp;

  if (uartch == UART2_BASE_PTR)
  {
      PORTE_PCR16 = PORT_PCR_MUX(0x3); 
      PORTE_PCR17 = PORT_PCR_MUX(0x3); 
     SIM_SCGC4 |= SIM_SCGC4_UART2_MASK;
  }

  /* Make sure that the transmitter and receiver are disabled while we change settings. */
  UART_C2_REG(uartch) &= ~(UART_C2_TE_MASK| UART_C2_RE_MASK );

  /* Configure the UART for 8-bit mode, no parity */
  UART_C1_REG(uartch) = 0;      /* We need all default settings, so entire register is cleared */

  /* Calculate baud settings */
  sbr = (uint16_t)((sysclk*1000)/(baud * 16));

  /* Save off the current value of the UARTx_BDH except for the SBR field */
  temp = UART_BDH_REG(uartch) & ~(UART_BDH_SBR(0x1F));

  UART_BDH_REG(uartch) = temp | UART_BDH_SBR(((sbr & 0x1F00) >> 8));
  UART_BDL_REG(uartch) = (uint8_t)(sbr & UART_BDL_SBR_MASK);

  /* Determine if a fractional divider is needed to get closer to the baud rate */
  brfa = (((sysclk*32000)/(baud * 16)) - (sbr * 32));

  /* Save off the current value of the UARTx_C4 register except for the BRFA field */
  temp = UART_C4_REG(uartch) & ~(UART_C4_BRFA(0x1F));

  UART_C4_REG(uartch) = temp | UART_C4_BRFA(brfa);

  /* Enable receiver and transmitter */
    UART_C2_REG(uartch) |= (UART_C2_TE_MASK  | UART_C2_RE_MASK | UART_C2_RIE_MASK); 

   //errors – FOR DEBUG ONLY
   UART_C3_REG(uartch) |= UART_C3_PEIE_MASK | UART_C3_FEIE_MASK | UART_C3_NEIE_MASK |  UART_C3_ORIE_MASK;

      NVIC_EnableIRQ(UART2_RX_TX_IRQn); 
    //FOR DEBUG ONLY
      NVIC_EnableIRQ(UART2_ERR_IRQn ); 
}

void UART2_RX_TX_IRQHandler(void)
{
  if ((UART_S1_REG(channel) & UART_S1_RDRF_MASK))
  {
      uint8_t chr = UART2->D;
      UART_SendByte(UART2, chr);
  }
}

void UART2_ERR_IRQHandler(void)
{
      uint32_t st = UART2_BASE_PTR->S1;
}

так я посылаю строку на терминал

void UART_SendByte (UART_MemMapPtr channel, char ch)
{
   /* Wait until space is available in the FIFO */
   while(!(UART_S1_REG(channel) & UART_S1_TDRE_MASK));

   /* Send the character */
   UART_D_REG(channel) = (uint8_t)ch;
}

void UART_SendString(UART_MemMapPtr uartChannel, const char *p)
{
   while(*p)
   {
      UART_SendByte(uartChannel, *p++);
   }
}

в main.c

UART_Init (UART2, 60000, 115200);

UART_SendString(UART2, "HELLO EVERYBODY\0");

While (1)
{
}

на терминале вижу мусор. но если ввожу задержку

void UART_SendString(UART_MemMapPtr uartChannel, uint8_t *p)
{
    while(*p)
    {
        UART_SendByte(uartChannel, *p++);
        //~100us
        for (int i = 0; i < 10000; i++)
        {
            asm("NOP");
        }
    }
}

на терминале вижу коректную строку.

также если печатаю попадаю в UART2_ERR_IRQHandler с ошибкой Framing Error .

очень похоже на Framing Error вопрос откуда она береться.

Изменено пользователем Jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

С процом незнаком, но... включения фифо нигде не вижу.

так я без фифо.

 

у них фифо дурацкий. нету отдельного флага на принятие чара и достижения заданного уровня фифо. один флаг на все и крутись как хочешь.

хотя...сейчас посмотрел. есть Receive Buffer/FIFO Empty Flag. можно и его использовать.

но по любому фифо выключен и не должен влиять на посылку.

Изменено пользователем Jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

так я без фифо.

 

Может не в тему, с их кинетисами не работал, но в МХ серии уарт с выключенным фифо у меня отказывался нормально работать, пришлось включить и установить прерывание по 1 входящему символу.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

но по любому фифо выключен и не должен влиять на посылку.

Опять же вангование на основе чтения доки, но кмк там описано, что UART_S1_REG(channel) & UART_S1_TDRE_MASK флаг работает только с фифо. Такое ощущение что без фифо он всегда 1, вследствие чего в регистр пихается новое значение до отправки старого. Проверьте пожалуйста.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Опять же вангование на основе чтения доки, но кмк там описано, что UART_S1_REG(channel) & UART_S1_TDRE_MASK флаг работает только с фифо. Такое ощущение что без фифо он всегда 1, вследствие чего в регистр пихается новое значение до отправки старого. Проверьте пожалуйста.

А вы знаете вы таки правы. Надо проверять Transmit Complete Flag (UART_S1_TC_MASK). Тогда все работает. Снимаю шляпу.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...