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

Кто любит RISC в жизни, заходим, не стесняемся.
kote52
Встал на лапы
Сообщения: 120
Зарегистрирован: Пт мар 19, 2021 08:58:45

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

Сообщение kote52 »

Всем привет! Второй день бьюсь с настройкой портов для 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) вход
Видимо запутался я с этими регистрами, помогите/подскажите?)
Reflector
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

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

Сообщение Reflector »

Если после переконфигурирования RX начинает работать передача, то для начала нужно проверить не закорочены ли соседние RX с TX и точно ли подключаемся куда надо. Затем ставим бп после инициализации всей периферии и смотрим в отладчике действительно ли в регистрах GPIO находится то, что туда пытались записать.
А в целом по коду особых косяков не вижу, разве что Pull Up бесполезен для TX и не помешал бы для RX, а у тебя все наоборот.
kote52
Встал на лапы
Сообщения: 120
Зарегистрирован: Пт мар 19, 2021 08:58:45

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

Сообщение kote52 »

припаян на плату 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 и все. По сути они только и нужны.
Reflector
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

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

Сообщение Reflector »

Input то не нужно на RX делать, это на старых портах для F1 работало, на всех остальных должен быть режим AF.
kote52
Встал на лапы
Сообщения: 120
Зарегистрирован: Пт мар 19, 2021 08:58:45

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

Сообщение kote52 »

[uquote="Reflector",url="/forum/viewtopic.php?p=4538541#p4538541"]Input то не нужно на RX делать, это на старых портах для F1 работало, на всех остальных должен быть режим AF.[/uquote]

Код: Выделить всё

	// 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++; //Кидаем данные  
	}
	
}
Аватара пользователя
Нефертити
Встал на лапы
Сообщения: 83
Зарегистрирован: Ср дек 06, 2023 23:51:29
Откуда: 48

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

Сообщение Нефертити »

Наверное, забыли USART1 clock source selection в RCC_CFGR3 занести.
Относись к людям так, как хочешь, чтобы они относились к тебе.
Аватара пользователя
КРАМ
Друг Кота
Сообщения: 25122
Зарегистрирован: Чт янв 10, 2008 22:01:02
Откуда: Московская область, Фрязино

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

Сообщение КРАМ »

Тогда бы весь модуль не работал. А у автора передача работает.
kote52
Встал на лапы
Сообщения: 120
Зарегистрирован: Пт мар 19, 2021 08:58:45

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

Сообщение kote52 »

Нефертити, 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
}
Аватара пользователя
КРАМ
Друг Кота
Сообщения: 25122
Зарегистрирован: Чт янв 10, 2008 22:01:02
Откуда: Московская область, Фрязино

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

Сообщение КРАМ »

В вашем коде нет включения тактирования периферии.
kote52
Встал на лапы
Сообщения: 120
Зарегистрирован: Пт мар 19, 2021 08:58:45

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

Сообщение kote52 »

[uquote="КРАМ",url="/forum/viewtopic.php?p=4538824#p4538824"]В вашем коде нет включения тактирования периферии.[/uquote]
Какую именно вы периферию имеете в виду? В первом моем сообщение самые первые строчки кода:

Код: Выделить всё

SET_BIT(RCC->AHBENR, RCC_AHBENR_GPIOAEN); //Настроили тактирование PORT A
я вас правильно понял?
Аватара пользователя
КРАМ
Друг Кота
Сообщения: 25122
Зарегистрирован: Чт янв 10, 2008 22:01:02
Откуда: Московская область, Фрязино

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

Сообщение КРАМ »

Каждый модуль, включая УАРТ-ы имеют отдельное тактирование от домена осциллятора.
Включение тактирования портов недостаточно.
И я говорил лишь о последнем приведенном коде.
kote52
Встал на лапы
Сообщения: 120
Зарегистрирован: Пт мар 19, 2021 08:58:45

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

Сообщение kote52 »

[uquote="КРАМ",url="/forum/viewtopic.php?p=4538835#p4538835"]Включение тактирования портов недостаточно.[/uquote]
ну хорошо в USART_Init(); прописано включение тактирования, первое сообщение.

Код: Выделить всё

SET_BIT(RCC->APB2ENR, RCC_APB2ENR_USART1EN); //Запустим тактирование USART1
Аватара пользователя
КРАМ
Друг Кота
Сообщения: 25122
Зарегистрирован: Чт янв 10, 2008 22:01:02
Откуда: Московская область, Фрязино

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

Сообщение КРАМ »

Ну и замечательно. Если тактирование включено, значит должен работать в полном составе.
Аватара пользователя
Нефертити
Встал на лапы
Сообщения: 83
Зарегистрирован: Ср дек 06, 2023 23:51:29
Откуда: 48

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

Сообщение Нефертити »

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

Во вложении для ректификационной колонны делал небольшой проект на STM324F030F4P6.
4 термометра, давление в кубе на модуле с Ali, атмосферное давление на BMP180, 2 кнопки, и управление клапаном.
Фотки
СпойлерИзображение Изображение
Относись к людям так, как хочешь, чтобы они относились к тебе.
kote52
Встал на лапы
Сообщения: 120
Зарегистрирован: Пт мар 19, 2021 08:58:45

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

Сообщение kote52 »

Всем откликнувшимся спасибо, все заработало нормаль, как только отключил SET_BIT(USART1->CR1, USART_CR1_IDLEIE); //(1) Прерывание по флагу IDLE включено. Объяснить пока это не могу.
И настройки портов оставил: вкл альтернативная функция, и pull up.
Аватара пользователя
КРАМ
Друг Кота
Сообщения: 25122
Зарегистрирован: Чт янв 10, 2008 22:01:02
Откуда: Московская область, Фрязино

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

Сообщение КРАМ »

А что вы пытались поймать по IDLE? У вас прием в кольцевой буфер?
kote52
Встал на лапы
Сообщения: 120
Зарегистрирован: Пт мар 19, 2021 08:58:45

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

Сообщение kote52 »

[uquote="КРАМ",url="/forum/viewtopic.php?p=4538988#p4538988"]А что вы пытались поймать по IDLE?[/uquote]
В обработчике прерываний была вот такая конструкция, еë соответсвенно тоже убрал.

Код: Выделить всё

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; //сбросим счетчик приходящих данных
   }
Аватара пользователя
КРАМ
Друг Кота
Сообщения: 25122
Зарегистрирован: Чт янв 10, 2008 22:01:02
Откуда: Московская область, Фрязино

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

Сообщение КРАМ »

А можно привести весь обработчик и показать принимаемый пакет (диаграмму)? Есть смутное подозрение, что вы допускали переполнение приемника...
kote52
Встал на лапы
Сообщения: 120
Зарегистрирован: Пт мар 19, 2021 08:58:45

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

Сообщение kote52 »

[uquote="КРАМ",url="/forum/viewtopic.php?p=4539014#p4539014"]А можно привести весь обработчик[/uquote]
Код обработчика выложен полностью чуть выше ващего первого сообщения в данной теме, пишу с телефона не удобно полность перезалить и возможности нет пока.
a797945
Мучитель микросхем
Сообщения: 446
Зарегистрирован: Вс ноя 01, 2015 09:15:16
Откуда: 69.Ржев

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

Сообщение a797945 »

del

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

Вернуться в «ARM»