работает нормально на отправку только когда меняю в строке режим работы на вход, но приемник при этом не работает
Код:
// 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) вход
Видимо запутался я с этими регистрами, помогите/подскажите?)
Если после переконфигурирования RX начинает работать передача, то для начала нужно проверить не закорочены ли соседние RX с TX и точно ли подключаемся куда надо. Затем ставим бп после инициализации всей периферии и смотрим в отладчике действительно ли в регистрах GPIO находится то, что туда пытались записать. А в целом по коду особых косяков не вижу, разве что Pull Up бесполезен для TX и не помешал бы для RX, а у тебя все наоборот.
Зарегистрирован: Пт мар 19, 2021 08:58:45 Сообщений: 120
Рейтинг сообщения:0
припаян на плату 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 и все. По сути они только и нужны.
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++; //Кидаем данные }
Зарегистрирован: Пт мар 19, 2021 08:58:45 Сообщений: 120
Рейтинг сообщения:0
Нефертити, 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); //Дождемся поднятия флага о готовности
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 }
Каждый модуль, включая УАРТ-ы имеют отдельное тактирование от домена осциллятора. Включение тактирования портов недостаточно. И я говорил лишь о последнем приведенном коде.
kote52, на начальную настройку всего в ручном режиме уходит очень много времени. Это время можно использовать для чего-нибудь другого. Я, для себя, пришёл к выводу, что всей этой начальной настройкой пусть занимается CubeIDE, достаточно указать ему использовать LL. Я своё время лучше потрачу на поиски чего-нибудь другого.
Во вложении для ректификационной колонны делал небольшой проект на STM324F030F4P6. 4 термометра, давление в кубе на модуле с Ali, атмосферное давление на BMP180, 2 кнопки, и управление клапаном. ФоткиСпойлер
Зарегистрирован: Пт мар 19, 2021 08:58:45 Сообщений: 120
Рейтинг сообщения:0
Всем откликнувшимся спасибо, все заработало нормаль, как только отключил SET_BIT(USART1->CR1, USART_CR1_IDLEIE); //(1) Прерывание по флагу IDLE включено. Объяснить пока это не могу. И настройки портов оставил: вкл альтернативная функция, и pull up.
В обработчике прерываний была вот такая конструкция, еë соответсвенно тоже убрал.
Код:
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; //сбросим счетчик приходящих данных }
Код обработчика выложен полностью чуть выше ващего первого сообщения в данной теме, пишу с телефона не удобно полность перезалить и возможности нет пока.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 10
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения