Кто любит RISC в жизни, заходим, не стесняемся.
Ответить

st32f303cct6 USART настройка GPIO

Сб фев 03, 2024 10:02:35

Всем привет! Второй день бьюсь с настройкой портов для USART1.
Код инициализации:

Код:
//Выше по коду включен тактирование порта А
void ADC1_Init(void) {
        SET_BIT(RCC->AHBENR, RCC_AHBENR_GPIOAEN); //Настроили тактирование PORT A
        //свой код
}
void USART1_Init(void) {
   // USART1: Rx - PA10 , Tx - PA9
        // PA9 (TxD)
   MODIFY_REG(GPIOA->MODER, GPIO_MODER_MODER9_Msk, 0b10 << GPIO_MODER_MODER9_Pos); // (10) режим альтернативной функции
   CLEAR_BIT(GPIOA->OTYPER, GPIO_OTYPER_OT_9); //(0) двухтактный выход или push-pull сокращено PP
   MODIFY_REG(GPIOA->PUPDR, GPIO_PUPDR_PUPDR9_Msk, 0b01 << GPIO_PUPDR_PUPDR9_Pos); // (01) подтяжка к плюсу питания или pull-up сокращено PU
   MODIFY_REG(GPIOA->OSPEEDR, GPIO_OSPEEDER_OSPEEDR9_Msk, 0b11 << GPIO_OSPEEDER_OSPEEDR9_Pos); //(11) 50 MHz, высокочастотный выход
   MODIFY_REG(GPIOA->AFR[1], GPIO_AFRH_AFRH1_Msk, 0b0111 << GPIO_AFRH_AFRH1_Pos); // 7 << (1 * 4)

   // PA10 (RxD)
   MODIFY_REG(GPIOA->MODER, GPIO_MODER_MODER10_Msk, 0b10 << GPIO_MODER_MODER10_Pos); // (10) режим альтернативной функции
   CLEAR_BIT(GPIOA->OTYPER, GPIO_OTYPER_OT_10); //(0) двухтактный выход или push-pull сокращено PP
   MODIFY_REG(GPIOA->OSPEEDR, GPIO_OSPEEDER_OSPEEDR10_Msk, 0b11 << GPIO_OSPEEDER_OSPEEDR10_Pos); //(11) 50 MHz, высокочастотный выход
   MODIFY_REG(GPIOA->PUPDR, GPIO_PUPDR_PUPDR10_Msk, 0b00 <<  GPIO_PUPDR_PUPDR10_Pos); //(00) состояние после сброса, no pull up, pull down
   MODIFY_REG(GPIOA->AFR[1], GPIO_AFRH_AFRH2_Msk, 0b0111 << GPIO_AFRH_AFRH2_Pos); // 7 << (2 * 4)

   SET_BIT(RCC->APB2ENR, RCC_APB2ENR_USART1EN); //Запустим тактирование USART1
   
   USART1->BRR = 0xEA6; //19200
   CLEAR_BIT(USART1->CR1, USART_CR1_OVER8); //0: Передискретизация равна 16
   SET_BIT(USART1->CR1, USART_CR1_UE); //(1)USART включить
   MODIFY_REG(USART1->CR1, USART_CR1_M_Msk, 0b00 << USART_CR1_M_Pos); //(00) Word lenght 1 Start bit, 8 Data bits, n Stop bit

   SET_BIT(USART1->CR1, USART_CR1_RE); //(1) Влючить приемник Rx
   SET_BIT(USART1->CR1, USART_CR1_TE); //(1) Включить передатчик Tx
   SET_BIT(USART1->CR1, USART_CR1_RXNEIE); //(1) Прерывание по приему данных включено
   SET_BIT(USART1->CR1, USART_CR1_IDLEIE); //(1) Прерывание по флагу IDLE включено
   
   USART1->CR2 = 0;
   CLEAR_BIT(USART1->CR2, USART_CR2_STOP); //1 стоп бит
   USART1->CR3 = 0;
   USART1->GTPR = 0;
   USART1->ICR = 0;
   NVIC_EnableIRQ(USART1_IRQn);
}


работает нормально на отправку только когда меняю в строке режим работы на вход, но приемник при этом не работает
Код:
   // PA10 (RxD) shall use the alternate function 7 (see data sheet)
   MODIFY_REG(GPIOA->MODER, GPIO_MODER_MODER10_Msk, 0b00 << GPIO_MODER_MODER10_Pos); //(00) вход

Видимо запутался я с этими регистрами, помогите/подскажите?)

Re: st32f303cct6 USART настройка GPIO

Сб фев 03, 2024 11:27:05

Если после переконфигурирования RX начинает работать передача, то для начала нужно проверить не закорочены ли соседние RX с TX и точно ли подключаемся куда надо. Затем ставим бп после инициализации всей периферии и смотрим в отладчике действительно ли в регистрах GPIO находится то, что туда пытались записать.
А в целом по коду особых косяков не вижу, разве что Pull Up бесполезен для TX и не помешал бы для RX, а у тебя все наоборот.

Re: st32f303cct6 USART настройка GPIO

Сб фев 03, 2024 13:48:28

припаян на плату BluePill от stm32f103, выводы не закорочены, сделал по вашему, нет приема только передача корректная работа. На лог анализаторе вижу то что отправляю. Обе линии в высоком уровне.
Код:
   // USART1: Rx - PA10 , Tx - PA9
    // PA9 (TxD) shall use the alternate function 7 (see data sheet)
   MODIFY_REG(GPIOA->MODER, GPIO_MODER_MODER9_Msk, 0b10 << GPIO_MODER_MODER9_Pos); // (10) режим альтернативной функции
   CLEAR_BIT(GPIOA->OTYPER, GPIO_OTYPER_OT_9); //(0) двухтактный выход или push-pull сокращено PP
   MODIFY_REG(GPIOA->PUPDR, GPIO_PUPDR_PUPDR9_Msk, 0b00 << GPIO_PUPDR_PUPDR9_Pos); // (00) без подтяжки
   MODIFY_REG(GPIOA->OSPEEDR, GPIO_OSPEEDER_OSPEEDR9_Msk, 0b11 << GPIO_OSPEEDER_OSPEEDR9_Pos); //(11) 50 MHz, высокочастотный выход
   MODIFY_REG(GPIOA->AFR[1], GPIO_AFRH_AFRH1_Msk, 0b0111 << GPIO_AFRH_AFRH1_Pos); // 7 << (1 * 4)

   // PA10 (RxD) shall use the alternate function 7 (see data sheet)
   MODIFY_REG(GPIOA->MODER, GPIO_MODER_MODER10_Msk, 0b00 << GPIO_MODER_MODER10_Pos); //(00) input
   CLEAR_BIT(GPIOA->OTYPER, GPIO_OTYPER_OT_10); //(0) двухтактный выход или push-pull сокращено PP
   MODIFY_REG(GPIOA->PUPDR, GPIO_PUPDR_PUPDR10_Msk, 0b01 <<  GPIO_PUPDR_PUPDR10_Pos); //(01) подтяжка к плюсу питания или pull-up сокращено PU
   MODIFY_REG(GPIOA->OSPEEDR, GPIO_OSPEEDER_OSPEEDR10_Msk, 0b11 << GPIO_OSPEEDER_OSPEEDR10_Pos); //(11) 50 MHz, высокочастотный выход
   MODIFY_REG(GPIOA->AFR[1], GPIO_AFRH_AFRH2_Msk, 0b0111 << GPIO_AFRH_AFRH2_Pos); // 7 << (2 * 4)

В отладке смотрел регистры, все верно ставит.
Проверил тактирование мк, все правильно косяков нет.
У людей смтрю примеры вообще настроены только два регистра MODER и AFR и все. По сути они только и нужны.

Re: st32f303cct6 USART настройка GPIO

Сб фев 03, 2024 14:01:56

Input то не нужно на RX делать, это на старых портах для F1 работало, на всех остальных должен быть режим AF.

Re: st32f303cct6 USART настройка GPIO

Сб фев 03, 2024 14:26:38

Input то не нужно на RX делать, это на старых портах для F1 работало, на всех остальных должен быть режим AF.

Код:
   // USART1: Rx - PA10 , Tx - PA9
    // PA9 (TxD) shall use the alternate function 7 (see data sheet)
   MODIFY_REG(GPIOA->MODER, GPIO_MODER_MODER9_Msk, 0b10 << GPIO_MODER_MODER9_Pos); // (10) режим альтернативной функции
   CLEAR_BIT(GPIOA->OTYPER, GPIO_OTYPER_OT_9); //(0) двухтактный выход или push-pull сокращено PP
   MODIFY_REG(GPIOA->PUPDR, GPIO_PUPDR_PUPDR9_Msk, 0b00 << GPIO_PUPDR_PUPDR9_Pos); // (00) сброс
   MODIFY_REG(GPIOA->OSPEEDR, GPIO_OSPEEDER_OSPEEDR9_Msk, 0b11 << GPIO_OSPEEDER_OSPEEDR9_Pos); //(11) 50 MHz, высокочастотный выход
   MODIFY_REG(GPIOA->AFR[1], GPIO_AFRH_AFRH1_Msk, 0b0111 << GPIO_AFRH_AFRH1_Pos); // 7 << (1 * 4)

   // PA10 (RxD) shall use the alternate function 7 (see data sheet)
   MODIFY_REG(GPIOA->MODER, GPIO_MODER_MODER10_Msk, 0b10 << GPIO_MODER_MODER10_Pos); //(10) режим альтернативной функции
   CLEAR_BIT(GPIOA->OTYPER, GPIO_OTYPER_OT_10); //(0) двухтактный выход или push-pull сокращено PP
   MODIFY_REG(GPIOA->PUPDR, GPIO_PUPDR_PUPDR10_Msk, 0b01 <<  GPIO_PUPDR_PUPDR10_Pos); //(01) PU
   MODIFY_REG(GPIOA->OSPEEDR, GPIO_OSPEEDER_OSPEEDR10_Msk, 0b11 << GPIO_OSPEEDER_OSPEEDR10_Pos); //(11) 50 MHz, высокочастотный выход
   MODIFY_REG(GPIOA->AFR[1], GPIO_AFRH_AFRH2_Msk, 0b0111 << GPIO_AFRH_AFRH2_Pos); // 7 << (2 * 4)

При таких настройках, одна буква "H" передается из "Hello World" когда нажмешь кнопку RESET. Но прием начинает работать.

Код:
void USART1_IRQHandler(void) {   
   if (READ_BIT(USART1->ISR, USART_ISR_RXNE)) {
      //RXNE - Сбрасывается автоматически при чтении регистра RDR. Также можно сбросить записью в этот бит нуля.
      //Если пришли данные по USART
      husart1.rx_buffer[husart1.rx_counter] = USART1->RDR; //Считаем данные в соответствующую ячейку в rx_buffer
      husart1.rx_counter++; //Увеличим счетчик принятых байт на 1
   }
   if (READ_BIT(USART1->ISR, USART_ISR_IDLE)) {
      //Если прилетел флаг IDLE
      USART1->RDR; //Сбросим флаг IDLE
      husart1.rx_len = husart1.rx_counter; //Узнаем, сколько байт получили
      CMSIS_USART_Transmit(USART1, husart1.rx_buffer, husart1.rx_counter); //Отправим в порт то, что прилетело для проверки.
      husart1.rx_counter = 0; //сбросим счетчик приходящих данных
   }
}

void CMSIS_USART_Transmit(USART_TypeDef *USART, uint8_t *data, uint16_t Size) {
   for (uint16_t i = 0; i < Size; i++) {
      while (READ_BIT(USART->ISR, USART_ISR_TXE) == 0) ; //Ждем, пока линия не освободится
      USART->TDR = *data++; //Кидаем данные 
   }
   
}

Re: st32f303cct6 USART настройка GPIO

Вс фев 04, 2024 00:34:09

Наверное, забыли USART1 clock source selection в RCC_CFGR3 занести.

Re: st32f303cct6 USART настройка GPIO

Вс фев 04, 2024 07:55:10

Тогда бы весь модуль не работал. А у автора передача работает.

Re: st32f303cct6 USART настройка GPIO

Вс фев 04, 2024 09:25:59

Нефертити, RCC_CFGR3->USART1SW я смотрел его в отладке, он - 00: PCLK selected as USART1 clock source (default) или нужно было сбросить наверняка?
Скину еще настройки тактирования мк
Код:
void CMSIS_RCC_SystemClock_72MHz(void) {
   //Настройка 72MHz
   SET_BIT(RCC->CR, RCC_CR_HSION); //(1)Запустили внутрений RC генератор на 8 MHz
   while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0); //Дождемся поднятия флага о готовности

   CLEAR_BIT(RCC->CR, RCC_CR_HSEBYP); //(0)
   SET_BIT(RCC->CR, RCC_CR_HSEON);//(1) //Запустим внешний кварцевый резонатор на 8 MHz
   while (READ_BIT(RCC->CR, RCC_CR_HSEON) == 0); //Дождемся поднятия флага о готовности

   //SET_BIT(RCC->CR, RCC_CR_CSSON); //(1)Вкл. CSS
   CLEAR_BIT(RCC->CR, RCC_CR_CSSON); //(0)Выкл .CSS

   MODIFY_REG(FLASH->ACR, FLASH_ACR_LATENCY, FLASH_ACR_LATENCY_1); //(010) Two wait states, if 48 MHz < SYSCLK <= 72 MHz
   SET_BIT(FLASH->ACR, FLASH_ACR_PRFTBE); //(1) Prefetch is enabled
   SET_BIT(FLASH->ACR, FLASH_ACR_PRFTBS); //(1) Prefetch buffer is enabled

   MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, RCC_CFGR_SW_PLL); //(10)Выберем PLL в качестве System Clock
   MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_CFGR_HPRE_DIV1); //(0)AHB Prescaler /1
   MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE1, RCC_CFGR_PPRE1_DIV2); //(100) APB1 Prescaler /2, т.к. PCLK1 max 36MHz
   MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE2, RCC_CFGR_PPRE2_DIV1); //(0) APB2 Prescaler /1. 72MHz.

   MODIFY_REG(RCC->CFGR, RCC_CFGR_PLLSRC, RCC_CFGR_PLLSRC_HSE_PREDIV); //(10) В качестве входного сигнала для PLL выберем HSE
   MODIFY_REG(RCC->CFGR2, RCC_CFGR2_PREDIV_Msk, 0b0000 << RCC_CFGR2_PREDIV_Pos); //(0000) PREDIV коэффициент деления PREDIV.
   MODIFY_REG(RCC->CFGR, RCC_CFGR_PLLXTPRE, RCC_CFGR_PLLXTPRE_HSE_PREDIV_DIV1);  //(0000) HSE input to PLL not divided предделение перед PLL /1
   MODIFY_REG(RCC->CFGR, RCC_CFGR_PLLMUL, RCC_CFGR_PLLMUL9); //(0111) т.к. кварц на 8Mhz, а нужно 72MHz
   CLEAR_BIT(RCC->CFGR, RCC_CFGR_USBPRE); //(1) OFF или (0) Для USB 72MHz/1.5 = 48MHz

   SET_BIT(RCC->CR, RCC_CR_PLLON); //PLL Вкл.
   while (READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0);//Дождемся поднятия флага о готовности PLL
}

Re: st32f303cct6 USART настройка GPIO

Вс фев 04, 2024 09:54:17

В вашем коде нет включения тактирования периферии.

Re: st32f303cct6 USART настройка GPIO

Вс фев 04, 2024 10:06:37

В вашем коде нет включения тактирования периферии.

Какую именно вы периферию имеете в виду? В первом моем сообщение самые первые строчки кода:
Код:
SET_BIT(RCC->AHBENR, RCC_AHBENR_GPIOAEN); //Настроили тактирование PORT A

я вас правильно понял?

Re: st32f303cct6 USART настройка GPIO

Вс фев 04, 2024 10:34:25

Каждый модуль, включая УАРТ-ы имеют отдельное тактирование от домена осциллятора.
Включение тактирования портов недостаточно.
И я говорил лишь о последнем приведенном коде.

Re: st32f303cct6 USART настройка GPIO

Вс фев 04, 2024 10:48:16

Включение тактирования портов недостаточно.

ну хорошо в USART_Init(); прописано включение тактирования, первое сообщение.
Код:
SET_BIT(RCC->APB2ENR, RCC_APB2ENR_USART1EN); //Запустим тактирование USART1

Re: st32f303cct6 USART настройка GPIO

Вс фев 04, 2024 11:02:48

Ну и замечательно. Если тактирование включено, значит должен работать в полном составе.

Re: st32f303cct6 USART настройка GPIO

Вс фев 04, 2024 15:35:48

kote52, на начальную настройку всего в ручном режиме уходит очень много времени. Это время можно использовать для чего-нибудь другого.
Я, для себя, пришёл к выводу, что всей этой начальной настройкой пусть занимается CubeIDE, достаточно указать ему использовать LL.
Я своё время лучше потрачу на поиски чего-нибудь другого.

Во вложении для ректификационной колонны делал небольшой проект на STM324F030F4P6.
4 термометра, давление в кубе на модуле с Ali, атмосферное давление на BMP180, 2 кнопки, и управление клапаном.
Фотки
СпойлерИзображение Изображение
Вложения
EagleRectification_2024-02-04_14-44-24.rar
Проект в EagleCAD
(222.71 KiB) Скачиваний: 8
IdeRectification_2024-02-04_14-38-49.rar
Проект в CubeIDE
(434.39 KiB) Скачиваний: 9
Rectification.png
Схема
(204.59 KiB) Скачиваний: 14

Re: st32f303cct6 USART настройка GPIO

Вс фев 04, 2024 17:41:44

Всем откликнувшимся спасибо, все заработало нормаль, как только отключил SET_BIT(USART1->CR1, USART_CR1_IDLEIE); //(1) Прерывание по флагу IDLE включено. Объяснить пока это не могу.
И настройки портов оставил: вкл альтернативная функция, и pull up.

Re: st32f303cct6 USART настройка GPIO

Вс фев 04, 2024 17:45:00

А что вы пытались поймать по IDLE? У вас прием в кольцевой буфер?

Re: st32f303cct6 USART настройка GPIO

Вс фев 04, 2024 18:30:44

А что вы пытались поймать по IDLE?

В обработчике прерываний была вот такая конструкция, еë соответсвенно тоже убрал.
Код:
if (READ_BIT(USART1->ISR, USART_ISR_IDLE)) {
      //Если прилетел флаг IDLE
      USART1->RDR; //Сбросим флаг IDLE
      husart1.rx_len = husart1.rx_counter; //Узнаем, сколько байт получили
      CMSIS_USART_Transmit(USART1, husart1.rx_buffer, husart1.rx_counter); //Отправим в порт то, что прилетело для проверки.
      husart1.rx_counter = 0; //сбросим счетчик приходящих данных
   }

Re: st32f303cct6 USART настройка GPIO

Вс фев 04, 2024 18:49:17

А можно привести весь обработчик и показать принимаемый пакет (диаграмму)? Есть смутное подозрение, что вы допускали переполнение приемника...

Re: st32f303cct6 USART настройка GPIO

Вс фев 04, 2024 18:59:46

А можно привести весь обработчик

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

Re: st32f303cct6 USART настройка GPIO

Вс фев 04, 2024 19:26:42

del

удалил - сообщение было не во всем корректно.
но вызывать передачу строки в обработчике прерывания ни есть гуд.
Последний раз редактировалось a797945 Пн фев 05, 2024 12:07:43, всего редактировалось 1 раз.
Ответить