Данные не хранятся в регистре принимаемых данных (флаг UART RXNE не установлен) - PullRequest
1 голос
/ 08 июля 2019

Я программировал ядерную плату stm32l412kb, пытаясь установить базовую связь UART. Передача с платы работает отлично, но плата не получает никаких данных.

Что касается программного обеспечения, я попытался использовать стандартный код HAL несколькими различными способами, как в режиме прерывания, так и в режиме без прерывания. Я связал более базовый подход (показано ниже). Из отладки построчно я обнаружил, что регистр получения данных (RDR) не заполняется (и, следовательно, флаг, который устанавливается при наличии данных, не устанавливается). Это была ошибка в каждом случае.

Цель этого кода - вернуть введенный символ.

#include "stm32l4xx.h"

int main(void)
{

  /* USER CODE BEGIN 1 */

    /*The Usart2 peripheral needs its clock to be enabled.*/
    RCC->APB1ENR1 |= RCC_APB1ENR1_USART2EN;
    RCC->AHB2ENR |= RCC_AHB2ENR_GPIOAEN;
    /*The 72 MHz APB1 bus clock with a 9600baud rate gives a baud rate for the register of 0x1D4C*/
    USART2->BRR = 0x1D4C;
    /*For USART2 we need to enable the overall UART (U) driver, the transmission lines(T) and the reading lines(R). UART Enable is last.*/
    USART2->CR1 |= USART_CR1_RE | USART_CR1_TE | USART_CR1_UE;

/*Setting transmission pin*/
    GPIOA->MODER |= GPIO_MODE_AF_PP;
    GPIOA->OSPEEDR |= GPIO_SPEED_FREQ_HIGH;

  /* USER CODE END 1 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
      if (USART2->ISR & USART_ISR_RXNE) //if RX is not empty
        {
         char temp = USART2->RDR; //fetch the data received
         USART2->TDR = temp;  //send it back out
         while (!(USART2->ISR & USART_ISR_TC)); //wait for TX to be complete
        }
  }

      return 0;
}

Для отправки данных я использовал RealTerm Serial Capture и попробовал также консоль stm32cubeIDE. Одна из возможностей источника проблемы заключается в том, что в DataSheet написано

"В USART стартовый бит обнаруживается при распознавании определенной последовательности выборок. Эта последовательность: 1 1 1 0 X 0 X 0 X 0 0 0 0."

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

Большое спасибо заранее за любую помощь,

Harry

/ ********************************* UPDATE ************ ************************** /

Прежде всего, большое спасибо за помощь, теперь я понимаю основы, такие как использование таблицы данных для настройки регистров. Это высоко ценится. Я обновил свой код, но проблема остается.

Итак, я обновил свою конфигурацию следующим образом:

/*Configuring GPIO Pins*/
/*Clearing whatever is held in the mode registers for pins 2 and 3 (Inverting with their masks.)*/
GPIOA -> MODER &= ~(GPIO_MODER_MODE2_Msk | GPIO_MODER_MODE3_Msk);
/*The 2 bits 10 are being shifted to the position which configures Mode of pin 2 and also for pin 3 in the mode register.
 *(10 is alterntive function mode).*/
GPIOA -> MODER |= (0b10 << GPIO_MODER_MODE2_Pos) | (0b10 << GPIO_MODER_MODE3_Pos);
/*Clearing whatever is held in the output speed registers for pins 2 and 3*/
GPIOA -> OSPEEDR &= ~(GPIO_OSPEEDR_OSPEED2_Msk | GPIO_OSPEEDR_OSPEED3_Msk);
/*Setting the speed of pins 2 and 3 to be very high(11)*/
GPIOA -> OSPEEDR |= (0b11 << GPIO_OSPEEDR_OSPEED2_Pos) | (0b11 << GPIO_OSPEEDR_OSPEED3_Pos);
/*Clearing whatever is held in the alternative function registers for pins 2 and 3.*/
GPIOA -> AFR[0] &= ~(GPIO_AFRL_AFSEL2_Msk | GPIO_AFRL_AFSEL3_Msk);
/*Setting the pins 2 and 3 to their alternative functions(TX and RX)*/
GPIOA -> AFR[0] |= (7 << GPIO_AFRL_AFSEL2_Pos) | (7 << GPIO_AFRL_AFSEL3_Pos);

/*Clock Configuration*/
/*Enabling the USART2 peripheral clock.*/
RCC->APB1ENR1 &= ~(RCC_APB1ENR1_USART2EN_Msk);
RCC->APB1ENR1 |= (0b1 << RCC_APB1ENR1_USART2EN_Pos);
/*Enabling the GPIOA port peripheral clock*/
RCC->AHB2ENR &= ~(RCC_AHB2ENR_GPIOAEN_Msk);
RCC->AHB2ENR |= (0b1 << RCC_AHB2ENR_GPIOAEN_Pos);

/*USART Configuartion*/
/*The 72 MHz APB1 bus clock with a 9600baud rate gives a baud rate for the register of 0x1D4C*/
USART2->BRR = 0x1D4C;
/*For USART2 we need to enable the overall UART (U) driver, the transmission lines(T) and the reading lines(R). UART Enable is last.*/
USART2->CR1 &= ~(USART_CR1_RE_Msk | USART_CR1_TE_Msk | USART_CR1_UE_Msk);
USART2->CR1 |= USART_CR1_RE | USART_CR1_TE | USART_CR1_UE;

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

1 Ответ

1 голос
/ 08 июля 2019
  1. это не инициализирует регуляторы GPIO MODER или OPEEDR.
    GPIOA->MODER |= GPIO_MODE_AF_PP;
    GPIOA->OSPEEDR |= GPIO_SPEED_FREQ_HIGH;

GPIO_MODE_AF_PP & GPIO_SPEED_FREQ_HIGH являются определениями HAL и не могут использоваться на уровне регистра.

Вам необходимо установить соответствующие значения для каждого используемого вами контакта:

enter image description here enter image description here

Он никогда не будет получать или отправлять что-либо, поскольку вы забыли установить GPIO -> регистры AF иоборудование не подключено к контактам внутри.

Список дополнительных функций можно найти в техническом описании

enter image description here

и регистры AF GPIO в Справочном руководстве

enter image description here

эта последовательность должна быть:

                            GPIOA -> MODER &= ~(GPIO_MODER_MODE2_Msk | GPIO_MODER_MODE3_Msk);
                            GPIOA -> MODER |= (0b10 << GPIO_MODER_MODE2_Pos) | (0b10 << GPIO_MODER_MODE3_Pos);
                            GPIOA -> OSPEEDR &= ~(GPIO_OSPEEDR_OSPEED2_Msk | GPIO_OSPEEDR_OSPEED23Msk);
                            GPIOA -> OSPEEDR |= (0b11 << GPIO_OSPEEDR_OSPEED2_Pos) | (0b11 << GPIO_OSPEEDR_OSPEED3_Pos);
                            GPIOA -> AFR[0] &= ~(GPIO_AFRL_AFSEL2_Msk | GPIO_AFRL_AFSEL3_Msk);
                            GPIOA -> AFR[0] |= (7 << GPIO_AFRL_AFSEL2_Pos) | (7 << GPIO_AFRL_AFSEL3_Pos);
...