Alex_Golubev 0 9 сентября, 2020 Опубликовано 9 сентября, 2020 · Жалоба Не могу запустить USART на stm32h743. Нет сигнала на выходе TX Что сделал: Скрытый текст /*настройка uart + DMA для внешнех блоков*/ RCC->APB1LENR |= RCC_APB1LENR_USART3EN; // подключаем USART 3 к шине ABP1 while(!(RCC->APB1LENR & RCC_APB1LENR_USART3EN));// ждем чтобы гарантировано подключился SET_BIT(RCC->AHB4ENR, RCC_AHB4ENR_GPIODEN); GPIOD->MODER |= 0x2 << GPIO_MODER_MODE8_Pos; // перевод порта на альтернативную функцию в частности USART_TX GPIOD->MODER |= 0x2 << GPIO_MODER_MODE9_Pos; // перевод порта на альтернативную функцию в частности USART_RX GPIOD->OSPEEDR |= 0x2 << GPIO_OSPEEDR_OSPEED8_Pos; // настройка скорости фронта USART скорость наибольшая GPIOD->OSPEEDR |= 0x2 << GPIO_OSPEEDR_OSPEED9_Pos; // настройка скорости фронта USART GPIOD->PUPDR &= 0x00 << GPIO_PUPDR_PUPD8_Pos; // отключение подтяжки GPIOD->PUPDR &= 0x00 << GPIO_PUPDR_PUPD9_Pos; // отключение подтяжки GPIOD->AFR[1] |= 0x7 << GPIO_AFRH_AFSEL8_Pos | 0x7 << GPIO_AFRH_AFSEL9_Pos; // переключение мультиплексора на альтернативные выводы AF7 USART3->CR1 &= ~USART_CR1_UE; // отключение USART 3 для настройки while(USART3->CR1 & USART_CR1_UE); // проверяем что бит включения USART сброшен USART3->CR2 = 0x00; /*USART3->CR2 = 0x00 << USART_CR2_ADD_Pos | ~USART_CR2_RTOEN | 0x00 << USART_CR2_ABRMODE_Pos | ~USART_CR2_ABREN | ~USART_CR2_MSBFIRST | ~USART_CR2_DATAINV | \ ~USART_CR2_TXINV | ~USART_CR2_RXINV | ~USART_CR2_SWAP | ~USART_CR2_LINEN | 0x00 << USART_CR2_STOP_Pos | ~USART_CR2_CLKEN | ~USART_CR2_CPOL | ~USART_CR2_CPHA | ~USART_CR2_LBCL | ~USART_CR2_LBDIE | \ ~USART_CR2_LBDL | 0x00 << USART_CR2_ADDM7_Pos | ~USART_CR2_DIS_NSS | ~USART_CR2_SLVEN; // 1 стоп, младшим байтом вперед, оверсемпл включен на 16 бит.*/ USART3->CR3 = 0x00 << USART_CR3_TXFTCFG_Pos | 0x00 << USART_CR3_RXFTCFG_Pos /*| USART_CR3_DMAT | USART_CR3_DMAR*/; // USART3->PRESC = 0; // предделитель тактовой частоты. Частота на входе 120 МГц USART3->BRR = 521; // установка скорости расчетная формула. Хочу скорость 230400 USART3->CR1 |= USART_CR1_UE; // включаем USART3 while(1){ USART3->TDR = 0xa5; // передаем данные в UART while(!USART3->ISR & USART_ISR_TC); // На ножке USART_TX сигнала нет. } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 60 9 сентября, 2020 Опубликовано 9 сентября, 2020 · Жалоба 11 minutes ago, Alex_Golubev said: GPIOD->MODER |= 0x2 << GPIO_MODER_MODE8_Pos; // перевод порта на альтернативную функцию в частности USART_TX GPIOD->MODER |= 0x2 << GPIO_MODER_MODE9_Pos; // перевод порта на альтернативную функцию в частности USART_RX А вы уверены, что MODER содержал нули по указанной позиции? Если там было, например 0x01b, то двоечки уже не будет. 13 minutes ago, Alex_Golubev said: GPIOD->AFR[1] |= 0x7 << GPIO_AFRH_AFSEL8_Pos | 0x7 << GPIO_AFRH_AFSEL9_Pos; // переключение мультиплексора на альтернативные выводы AF7 А где включаете клок для этих пинов? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 131 9 сентября, 2020 Опубликовано 9 сентября, 2020 · Жалоба 8 минут назад, Alex_Golubev сказал: Не могу запустить USART на stm32h743. Нет сигнала на выходе TX Что сделал... Ну, а разрешение работы приемника и передатчика где? Оно в CR1 должно быть. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 60 9 сентября, 2020 Опубликовано 9 сентября, 2020 · Жалоба 15 minutes ago, Alex_Golubev said: USART3->CR1 |= USART_CR1_UE; // включаем USART3 А приёмник и передатчик не включили? 1 minute ago, Arlleex said: Ну, а разрешение работы приемника и передатчика где? Оно в CR1 должно быть. Уважаемый @Arlleex опередил) 17 minutes ago, Alex_Golubev said: SET_BIT(RCC->AHB4ENR, RCC_AHB4ENR_GPIODEN); А, увидел, что пины включаете. Стиль кодирования у вас разный. Не сразу заметил. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 9 сентября, 2020 Опубликовано 9 сентября, 2020 · Жалоба 23 minutes ago, Alex_Golubev said: while(!USART3->ISR & USART_ISR_TC); // На ножке USART_TX сигнала нет Доктора!!!!!!!!!!!!! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alex_Golubev 0 9 сентября, 2020 Опубликовано 9 сентября, 2020 · Жалоба Цитата Доктора!!!!!!!!!!!! Что не так ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 9 сентября, 2020 Опубликовано 9 сентября, 2020 (изменено) · Жалоба Разница между ! и ~ небольшаяю Или приоритеты операций изучать Изменено 9 сентября, 2020 пользователем GenaSPB Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 131 9 сентября, 2020 Опубликовано 9 сентября, 2020 · Жалоба 11 минут назад, GenaSPB сказал: Доктора!!!!!!!!!!!!! А, кстати да - но я туда чего-то не посмотрел даже 7 минут назад, GenaSPB сказал: Разница между ! и ~ небольшая... Тем не менее, оптимальнее все-таки через !. Хотя при оптимизации, возможно, и не важно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 9 сентября, 2020 Опубликовано 9 сентября, 2020 · Жалоба Там скорее всего просто забыты скобки: while (!(USART3->ISR & USART_ISR_TC)); А вот такое: GPIOD->MODER |= 0x2 << GPIO_MODER_MODE8_Pos; И такое: GPIOD->OSPEEDR |= 0x2 << GPIO_OSPEEDR_OSPEED8_Pos; и подобное - признаки типичного быдлокода. Раз делается операция "|=" то предполагается, что предыдущее содержимое регистров может быть !=0, но тогда результат будет ошибочный. А если предыдущее содержимое ==0 то зачем тогда |= ??? Это уже не говоря о том, что нет никакой заботы об атомарности модификации этих регистров. Если в соседней задаче РТОС (или ISR) завтра потребуется сконфигурить другие пины порта из того же регистра - начнутся очередные поиски и костыление багов. Вроде очевидные вещи, но чайники повторяют и повторяют такое, таская друг у друга такие "шедевры". А здесь: GPIOD->PUPDR &= 0x00 << GPIO_PUPDR_PUPD8_Pos; // отключение подтяжки (и строкой ниже) решили подтяжки для всего порта сразу отключить. Видимо - чтобы два раза не бегать. Фиг с ним что там могут использоваться ещё и другие пины, в другом месте. RCC->APB1LENR |= RCC_APB1LENR_USART3EN; // подключаем USART 3 к шине ABP1 А если не повезёт - то параллельно отключаем тактирование другой периферии. Ежли вдруг в это время другая задача захочет его включить. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 60 9 сентября, 2020 Опубликовано 9 сентября, 2020 · Жалоба 24 minutes ago, jcxz said: Раз делается операция "|=" то предполагается, что предыдущее содержимое регистров может быть !=0, но тогда результат будет ошибочный. Тут всё правильно, т.к. MODER включает в себя одинаковые группы битов для конфигруцаии пинов. И другие состояние мы трогать не имеем права. Другое дело, что перед такой операцией группу нужно обнулить, и наложить новую маску. Про атомарность операции согласен, сам так делаю. Хотя раньше грешил)) Вот фрагмент из либы управления пинами static void setAlternate( const Function func ) { TCritSect cs; auto &afr = base()->AFR[PinNum / 8]; afr &= ~AFR_MASK; afr |= static_cast<uint32_t>(func) << AFR_SHIFT; } /* true sets aoutput as logic 1 and false sets it as logic 0*/ static void set( const bool level ) { base()->BSRR = level ? SET_MASK : CLEAR_MASK; // здесь атомарность обеспечена железом } static void toggle() { TCritSect cs; base()->ODR ^= SET_MASK; } static void setModer( const Moder moder ) { TCritSect cs; base()->MODER &= ~MODER_MASK; base()->MODER |= static_cast<uint8_t>(moder) << MODER_SHIFT; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 9 сентября, 2020 Опубликовано 9 сентября, 2020 · Жалоба 9 минут назад, haker_fox сказал: Тут всё правильно, т.к. MODER включает в себя одинаковые группы битов для конфигруцаии пинов. А что именно "правильно"? Если до этого был режим 0, станет 2, если был 1 - станет 3. Сомневаюсь, что автор хотел именно такого поведения. Полагаю что он хотел какой-то один определённый режим поставить. 9 минут назад, haker_fox сказал: static void toggle() { TCritSect cs; base()->ODR ^= SET_MASK; } А здесь можно и без критической секции обойтись. Подумайте как. Если конечно не переключаете один и тот же пин из разных задач. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 14 9 сентября, 2020 Опубликовано 9 сентября, 2020 · Жалоба 1 час назад, Alex_Golubev сказал: GPIOD->PUPDR &= 0x00 << GPIO_PUPDR_PUPD8_Pos; // отключение подтяжки Здесь вы весь регистр обнулили, вместо одного бита. Бит обнулять так: GPIOD->PUPDR &= ~(1UL << GPIO_PUPDR_PUPD8_Pos); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alex_Golubev 0 10 сентября, 2020 Опубликовано 10 сентября, 2020 (изменено) · Жалоба Поправил код с вашей критикой. USART заработал. Добавил DMA ---> USART3. И не смог запустить. Скрытый текст ExternalsBlocks_TX[0] = 0x85; RCC->APB1LENR |= RCC_APB1LENR_USART3EN; // подключаем USART 3 к шине ABP1 while (!(RCC->APB1LENR & RCC_APB1LENR_USART3EN)); // ждем чтобы гарантированно подключилась MODIFY_REG(GPIOD->MODER, GPIO_MODER_MODE8, 0x2 << GPIO_MODER_MODE8_Pos); // перевод порта на альтернативную функцию в частности USART_TX MODIFY_REG(GPIOD->MODER, GPIO_MODER_MODE9, 0x2 << GPIO_MODER_MODE9_Pos); // перевод порта на альтернативную функцию в частности USART_RX MODIFY_REG(GPIOD->OSPEEDR, GPIO_OSPEEDR_OSPEED8,0x2 << GPIO_OSPEEDR_OSPEED8_Pos); // настройка скорости фронта USART скорость наибольшая MODIFY_REG(GPIOD->OSPEEDR, GPIO_OSPEEDR_OSPEED9,0x2 << GPIO_OSPEEDR_OSPEED9_Pos); // настройка скорости фронта USART скорость наибольшая MODIFY_REG(GPIOD->PUPDR, GPIO_PUPDR_PUPD8, 0x00 << GPIO_PUPDR_PUPD8_Pos); // отключение подтяжки MODIFY_REG(GPIOD->PUPDR, GPIO_PUPDR_PUPD9, 0x00 << GPIO_PUPDR_PUPD9_Pos); // отключение подтяжки MODIFY_REG(GPIOD->AFR[1], GPIO_AFRH_AFSEL8, 0x7 << GPIO_AFRH_AFSEL8_Pos); // переключение на альтернативный режим работы порта AF7 MODIFY_REG(GPIOD->AFR[1], GPIO_AFRH_AFSEL9, 0x7 << GPIO_AFRH_AFSEL9_Pos); // переключение на альтернативный режим работы порта AF7 MODIFY_REG(GPIOD->MODER, GPIO_MODER_MODE10, 0x1 << GPIO_MODER_MODE10_Pos); // перевод порта на выход RE MODIFY_REG(GPIOD->OSPEEDR,GPIO_OSPEEDR_OSPEED10,0x2 << GPIO_OSPEEDR_OSPEED10_Pos); // настройка скорости фронта для RE скорость наибольшая MODIFY_REG(GPIOD->PUPDR, GPIO_PUPDR_PUPD10, 0x00 << GPIO_PUPDR_PUPD10_Pos); // отключение подтяжки SET_BIT(GPIOD->BSRR, GPIO_BSRR_BR10); //установка логического нуля на линии RE USART3->CR1 &= ~USART_CR1_UE; // отключение USART 3 для настройки while (USART3->CR1 & USART_CR1_UE); // проверяем что бит включения USART3 сброшен USART3->CR2 = 0x00; USART3->CR3 = USART_CR3_DMAT | USART_CR3_DMAR; // включение DMA USART3->PRESC = 0; // предделитель тактовой частоты USART3->BRR = 521; // установка скорости расчетная формула 521 USART3->CR1 |= USART_CR1_TE; // включение передатчика USART3->CR1 |= USART_CR1_RE; // включение приемника USART3->CR1 |= USART_CR1_UE; // включаем USART3 while (!(USART3->CR1 & USART_CR1_UE)); // проверяем что бит включения USART3 установлен RCC->AHB1ENR |= RCC_AHB1LPENR_DMA1LPEN; // подключаем DMA1 к шине AHB1 while (!(RCC->AHB1ENR & RCC_AHB1LPENR_DMA1LPEN)); // ждем гарантированого включения DMA1_Stream1->CR &= ~DMA_SxCR_EN; // выключаем DMA while (DMA1_Stream1->CR & DMA_SxCR_EN); // ждем чтобы гарантировано был отключен DMA DMA1_Stream1->CR = DMA_SxCR_MINC | DMA_SxCR_TCIE; // настройка ДМА для USART3 инкремент памяти, включение прерывания по завершению приема DMA1_Stream1->NDTR = 1; // количество данных для передачи с USART3 в ОЗУ буфер DMA1_Stream1->PAR = (uint32_t) &USART3->RDR; // адрес от куда брать данные DMA1_Stream1->M0AR = (uint32_t)&ExternalsBlocks_RX; // указываем адрес масива куда писать DMA1_Stream1->CR |= DMA_SxCR_EN; // включаем DMA while (!(DMA1_Stream1->CR & DMA_SxCR_EN)); // ждем гарантированого включения DMA1_Stream2->CR &= ~DMA_SxCR_EN; // выключаем DMA while (DMA1_Stream2->CR & DMA_SxCR_EN); // ждем чтобы гарантировано был отключен DMA DMA1_Stream2->CR = DMA_SxCR_MINC | DMA_SxCR_DIR_0 | DMA_SxCR_CIRC; // настройка ДМА для USART3 инкремент памяти, передача из памяти ---> USART3 DMA1_Stream2->NDTR = 1; // количество данных для передачи с USART3 в ОЗУ буфер DMA1_Stream2->PAR = (uint32_t) &USART3->TDR; // адрес от куда брать данные DMA1_Stream2->M0AR = (uint32_t)&ExternalsBlocks_TX; // указываем адрес масива куда писать DMA1_Stream2->CR |= DMA_SxCR_EN; // включаем DMA while (!(DMA1_Stream2->CR & DMA_SxCR_EN)); // ждем гарантированого включения Добавил буферы: Скрытый текст __attribute__((section(".dma_buffer"))) uint8_t ExternalsBlocks_TX[256]; __attribute__((section(".dma_buffer"))) uint8_t ExternalsBlocks_RX[256]; Определил их в файле flash.id Скрытый текст .dma_buffer : { *(.dma_buffer) } >RAM_D3 Изменено 10 сентября, 2020 пользователем Alex_Golubev Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться