Поиск
Показаны результаты для тегов 'gpio'.
-
В проекте использую GigaDevice GD32F103RBT6. Настраиваю GPIO. Возникла проблема при настройке порта B пины 1 и 2. Процесс настройки выглядит следующим образом: 1) Настраиваю несколько пинов, отличных от PB1 и PB2. Всё проходит нормально. 2) Настраиваю PB2 на выход в режиме pushpull и вывожу лог. 1. Всё проходит нормально, на выходе осциллографом вижу лог. 1 и в отладке в соответствующих регистрах - соответствующие биты имеются. 3) Опять настраиваю несколько пинов, отличных от PB1 и PB2. Всё проходит нормально. 4) Настраиваю PB1 на вход с внутренней подтяжкой к питанию. Сначала чищу соответствующие биты в регистре GPIO_CTL0 (регистр определяющий режим работы вывода). В отладке вижу, что сбрасывается только то, что нужно. Затем в этом же регистре устанавливаю нужные мне биты. В отладке снова вижу, что устанавливается только то, что нужно. При этом в этот момент на осциллографе наблюдаю, что на пине PB2 (именно на PB2, я не описАлся) устанавливается лог. 0 !? КАК ПОЧЕМУ?! Что было сделано: 1) Попробовал после настройки PB1, снова настроить PB2 - не помогло. В отладке вижу, что в регистрах всё правильно, но осциллограф кажет на PB2 лог. 0. 2) Попробовал читать регистр GPIO_CTL0 и проверять, что в нём творится до настройки PB1 и после. Настройки для PB2 не меняются! 3) На плате ноги PB1 и PB2 не замыкаются. Ногу PB2 поднял - она ни с чем не соединена, но это не помогло. 4) Проверил проект на другой плате - всё работает также. 5) Проверил настройку других пинов - замечаний нет. Кто сталкивался с подобным? Что ещё попробовать? В чём проблема?
-
STM32F407 (427), внешний ТГ на пин OSC_IN. Желание: сигнал ТГ завести на PH0/OSC_IN и при этом PH1/OSC_OUT использовать как порт. Конфигурю в STM32CubeMX 6.3.0 + FW_F4 1.26.2: "Pinout&Configuration" -> RCC -> High Speed Clock (HSE) -> BYPASS Clock Source. Проблема: STM32CubeMX разрешает либо оба pin'а вместе: PH0/OSC_IN + PH1/OSC_OUT, либо при попытке перевести пин в GPIO отключает "BYPASS Clock Source". Читал RM0090 rev19: 6.2.1 HSE clock (стр. 154), 8.3.14 Using the OSC_IN/OSC_OUT pins as GPIO PH0/PH1 port pins (стр. 278). Похоже на то, что если включен HSE + HSE BYPASS (биты HSEON и HSEBYP в RCC_CR) то OSC_IN и OSC_OUT по-отдельности использоваться не могут? То есть при внешнем ТГ (HSE BYPASS) использовать OSC_OUT как порт не удастся? Подтвердите или опровергните, пожалуйста.
-
Компания Xilinx добавила продукт в свой портфель модулей программирования, отладки и трассировки модуль SmartLynq+. Это высокоскоростной модуль отладки и трассировки, в первую очередь ориентированный на проекты, использующие платформу Versal, который значительно улучшает процесс конфигурации и скорость трассировки. Модуль SmartLynq+ обеспечивает до 28 раз более быстрое время загрузки Linux через высокоскоростной порт отладки (HSDP), чем через кабель передачи данных SmartLynq. Для захвата трассировки модуль SmartLynq+ поддерживает скорость до 10 Гбит/с через интерфейс HSDP. Это в 100 раз быстрее, чем стандартный JTAG. Более быстрые итерации и повторяющиеся загрузки повышают продуктивность разработки и сокращают цикл проектирования. Это означает снижение времени, затраченного на отладку, вместо которой вы можете сосредоточиться на запуске своих решений на основе Versal. Узнать больше
-
power switch и power led ПК, подключение к GPIO
Trevor опубликовал тема в Интерфейсы
Добрый день! Пытаюсь настроить одноплатник так, чтобы управлять основным ПК. Сценарий такой: одноплатник всегда включен, захожу на него по ssh, могу видеть включен ли основной ПК (считывая power led через GPIO), а так же включить или выключать его (симулируя нажатие кнопки питания через GPIO). В электронике не разбираюсь, собрал какую-то схему по интернету, работает. Все ли здесь правильно и нельзя ли упростить? Элементы U1 и U2 это такая оптопара: https://www.chipdip.ru/product/pc817-ltv817c-liteon -
Доброго всем времени суток. Столкнулся тут со странным поведением DMA у STM32F446 при использовании DMA2 для комутации GPIO. Необходимость возникла из-за того, что на новой плате не были предусмотрены инвертеры уровня UART, а ведомое устройство в режиме загрузчика их, как оказалось, требует. С STM32F302 проблем бы не было, там есть инверсия уровней, но вот в более быстром и сложном F446 такой инверсии нет, плату переделывать не хотелось, пришлось искать решение в виде софтового UART на DMA. В плане передачи проблем никаких нет, все работает, тайминги и уровни не вызывают никаких вопросов, а вот в плане приема бьюсь уже неделю. Вот так выглядит инициализация DMA: static uint32_t Buff[128]; DMA_DeInit(DMA2_Stream1); DMA_StructInit(&DMA_InitStructure); DMA_InitStructure.DMA_BufferSize = 0; DMA_InitStructure.DMA_Channel = DMA_Channel_7; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&Buff; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(GPIOA->IDR); DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; DMA_Init(DMA2_Stream1, &DMA_InitStructure); Вот так инициализирую таймер, который будет задавать тактовую частоту (57600): TIM_DeInit(TIM8); TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_Period = TIMER_PERIOD - 1; TIM_TimeBaseStructure.TIM_Prescaler = (uint16_t)(SystemCoreClock / 1 / TIMER_FREQ) - 1; TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure); TIM_GenerateEvent(TIM8, TIM_EventSource_Update); TIM_Cmd(TIM8, ENABLE); TIM_DMACmd(TIM8, TIM_DMA_Update, ENABLE); Частоты однозначно верные, потому что тот же таймер используется для передачи, а там все ок, как в плане приема на стороне прибора, так и на осциллографе. И вот так происходит прием: uint8_t i; uint8_t val = 0; /**< Empty buffer */ memset(Buff, 0, 10); DMA_Cmd(DMA2_Stream1, DISABLE); DMA_ClearFlag(DMA2_Stream1, (DMA_FLAG_TCIF1 | DMA_FLAG_HTIF1 | DMA_FLAG_TEIF1)); /**< Activate edge interrupt */ WaitingRxUART = true; EXTI_ClearITPendingBit(EXTI_Line1); NVIC_EnableIRQ(EXTI1_IRQn); /**< Wait till DMA transmission is ready */ while ((DMA2_Stream1->CR & DMA_SxCR_EN) || (WaitingRxUART == true)); /**< Stop edge interrupt */ NVIC_DisableIRQ(EXTI1_IRQn); DMA_Cmd(DMA2_Stream1, DISABLE); /**< Decode data from DMA buffer */ /**< We are processing 8 data bits, don't know yet why it should be started with Buff[2]? */ for (i = 2; i < 10; i++) { val >>= 1; if ((Buff[i] & (1 << 1)) == 0) val |= 0x80; } При комутации приемопередатчика возникает короткий импульс, который нужно фильтровать, это происходит в прерывании: /**< External interrupt for detecting rising edge of UART packet */ void EXTI1_IRQHandler(void) { if (EXTI_GetITStatus(EXTI_Line1) != RESET) { /**< Clear the UART EXTI line pending bit */ EXTI_ClearITPendingBit(EXTI_Line1); /**< Wait 1 us and check input */ TIM10->CNT = 0; TIM10->SR = 0; while ((TIM10->SR & TIM_IT_Update) == 0); if ((GPIOA->IDR & (1 << 1)) == 0) return; /**< Real start bit received, no spike */ /**< Stop edge interrupt */ NVIC_DisableIRQ(EXTI1_IRQn); WaitingRxUART = false; /**< Start DMA GPIO capture */ /**< Receive 10 bits (8 data bits * 2 stop bits) */ TIM8->CR1 &= ~TIM_CR1_CEN; TIM_SetCounter(TIM8, TIM8->ARR / 2); TIM_ClearITPendingBit(TIM8, TIM_IT_Update); TIM8->CR1 |= TIM_CR1_CEN; DMA_SetCurrDataCounter(DMA2_Stream1, 10); DMA_Cmd(DMA2_Stream1, ENABLE); } } Все вроде бы хорошо работает, прием идет, выбросы отфильтровываются, но есть одно но - периодически, причем достаточно часто, происходит сбой, вместо, к примеру 0xAA принимается 0xAB, я посмотрел, что оказывается в буфере, куда собираются значения IDR, и обнаружил там наряду с нормальными значениями состояния входов GPIO пару нулевых значений, причем они идут не первыми и не последними, то есть, буффер выглядит так: 0x9B6C, 0x00, 0x00, 0x9B6C, 0x9B6E, ... Такого не может быть, потому что просто не может быть. Такое впечатление, что канал DMA с чем-то коллидирует и пишет в буфер нули. Может быть, кто-то сталкивался с подобным? Буду рад услышать какие-то советы, потому что голова уже сломалась. На осциллографе данные выглядят нормально (за исключением выбросов), но они точно фильтруются.