Микроконтроллер STM32 и USB.

Продолжаем работать с интерфейсом USB, и сегодня пришло время практики! Как вы помните, теоретические аспекты мы уже рассмотрели (вот), так что сегодня возьмем в руки микроконтроллер от ST и напишем небольшой примерчик 😉 Сразу скажу, что я решил поэкспериментировать с контроллером STM32F303 и, соответственно, с платой STM32F3Discovery.

Микроконтроллеры STM32F3

На плате уже есть два USB разъема, один под ST-Link и второй для пользовательских задач, то есть как раз то, что нам надо )

С платой разобрались, теперь по поводу софта. STMicroelectronics любезно предоставили библиотеки для работы с USB для различных семейств микроконтроллеров, а кроме того, выпустили кучу примеров под разные отладочные платы. Но плат Discovery в этом списке нет, поэтому не станем вносить свои изменения в уже готовые проекты от ST, а лучше создадим свой новый проект, взяв из примеров и библиотек только то, что нам реально понадобится.

Задача будет такая — по приему байта данных по USB, контроллер зажигает определенное количество светодиодов. Если пришел байт 0х01 — светится один диод, 0х02 — два, 0х03 — три ну и так далее. Для того, чтобы реализовать отправку данных с компьютера, поставим драйвер виртуального ком-порта и будем общаться с платкой через обычный терминал (я использую Advanced Serial Port Monitor, например).

Нужный драйвер без проблем можно скачать на официальном сайте STMicroelectronics. Устанавливается тоже без проблем и в итоге в диспетчере устройств появляется следующее:

Virtual com-port

С этим разобрались, давайте теперь откроем какой-нибудь примерчик от ST и посмотрим как же вообще в их библиотеках устроен обмен данными по USB. Вот архив со всеми библиотеками и примерами — ST USB Library

Заходим в папку с примерами и выбираем Virtual Com Port, там без труда находим нужную нам папку с проектом для Keil’а и запускаем его.

Давайте сразу же посмотрим на файл main.c:

int main(void)
{
    Set_System();
    Set_USBClock();
    USB_Interrupts_Config();
    USB_Init();
 
    while (1)
    {
    }
}

Видим, что в теле цикла while(1) пусто, соответственно вся работа происходит в прерываниях. В функции main() всего лишь вызываются функции инициализации. Все эти функции реализованы в файле hw_config.c, его мы поправим под себя чуть позже ) Для приема и передачи данных по USB в файле usb_endp.c предусмотрены обработчики соответствующих прерываний:

void EP1_IN_Callback (void)
void EP3_OUT_Callback(void)

Как вы помните из предыдущей статьи, транзакции IN нужны для передачи данных хосту (то есть компьютеру), а транзакции OUT для приема данных от хоста. Соответственно, для отправки данных используется конечная точка 1 (End Point 1), а для приема — End Point 3. Как программа попадает в эти обработчики? Сейчас разберемся! В файле stm32_it.c есть обработчик прерывания:

void USB_LP_CAN1_RX0_IRQHandler(void)

В его теле вызывается всего лишь одна функция — USB_Istr(), которая описана в файле usb_istr.c. Идем в этот файл и изучаем функцию…А там все в принципе просто, программа выясняет какое именно событие вызвало прерывание и в соответствии с этим происходит дальнейшая работа. Соответственно, при транзакциях IN или OUT вызываются именно те функции которые мы уже рассмотрели выше, а именно:

void EP1_IN_Callback (void)
void EP3_OUT_Callback(void)

Этот проект вообще по умолчанию адаптирован для контроллеров STM32F10x, да и файлов очень много лишних, так что давайте-ка создадим свой новый пустой проект и в нем уже будем работать. Напоминаю, что я буду работать с STM32F3Discovery, поэтому проект создаю для контроллера STM32F303VC. Забираем из папки с библиотеками и примерами все файлы, которые нам понадобятся. Вот их полный список:
Дерево проекта

В папку SPL я просто запихал все файлы из Standard Peripheral Library для STM32F303. Не забываем в настройках проекта указать все пути к файлам и прописать подключение SPL (все как тут, в общем — ссылка).

Проект создан, файлы все на месте, давайте писать код. И начинаем с функций инициализации, расположенных в файле hw_config.c:

void Set_System(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
 
    // Включаем тактирование нужной периферии
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
 
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOE, ENABLE);
 
    // Настройка пинов
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
 
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_8 | GPIO_Pin_10 |  GPIO_Pin_15 | GPIO_Pin_11 | GPIO_Pin_14 | GPIO_Pin_12 | GPIO_Pin_13;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_Init(GPIOE, &GPIO_InitStructure);
 
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource11, GPIO_AF_14);
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource12, GPIO_AF_14);
 
    // Внешнее прерывание, которое внутри контроллера подключено к 
    // функциям USB
    EXTI_ClearITPendingBit(EXTI_Line18);
    EXTI_InitStructure.EXTI_Line = EXTI_Line18; 
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);
}

Что за пины мы настраиваем тут? А вот:
Пины для работы с USB

С PA11 и PA12 разобрались, а все остальные ножки — это светодиоды, которые есть на плате.

Идем дальше…Из функций для работы с USART’ом я просто все удалил, поскольку мы приемопередатчиком пользоваться не будем. Настраиваем прерывания:

void USB_Interrupts_Config(void)
{
    NVIC_InitTypeDef NVIC_InitStructure; 
 
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  
 
    NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
 
    NVIC_InitStructure.NVIC_IRQChannel = USBWakeUp_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_Init(&NVIC_InitStructure);
}

И еще я добавил небольшую функцию в этот же файл. Она просто гасит все светодиоды:

void GPIO_ResetLeds()
{
    GPIO_ResetBits(GPIOE, GPIO_Pin_8);
    GPIO_ResetBits(GPIOE, GPIO_Pin_9);
    GPIO_ResetBits(GPIOE, GPIO_Pin_10);
    GPIO_ResetBits(GPIOE, GPIO_Pin_11);
    GPIO_ResetBits(GPIOE, GPIO_Pin_12);
    GPIO_ResetBits(GPIOE, GPIO_Pin_13);
    GPIO_ResetBits(GPIOE, GPIO_Pin_14);
    GPIO_ResetBits(GPIOE, GPIO_Pin_15);
}

Не забываем в файл hw_config.h дописать прототип для этой функции:

void GPIO_ResetLeds(void);

С инициализацией вроде бы все. Открываем файл usb_endp.c. Мы будем только анализировать принятые от хоста данные, поэтому обработчик транзакций IN нам не понадобится:

void EP1_IN_Callback (void)
{  
}

В обработчике транзакций OUT принимаем данные и в зависимости от того, какой байт принят зажигаем определенное количество светодиодов, которые у нас висят на GPIOE.

void EP3_OUT_Callback(void)
{
    uint16_t USB_Rx_Cnt;
 
  // Принимаем данные
    USB_Rx_Cnt = USB_SIL_Read(EP3_OUT, USB_Rx_Buffer);
 
  // Анализируем принятый байт
    switch(USB_Rx_Buffer[0])
    {
	case 0x01:
            GPIO_ResetLeds();		
	    GPIO_Write(GPIOE, 0x0100);
	    break;
 
        case 0x02:
	    GPIO_ResetLeds();		
	    GPIO_Write(GPIOE, 0x0300);
	    break;
 
	case 0x03:
	    GPIO_ResetLeds();		
	    GPIO_Write(GPIOE, 0x0700);
	    break;
 
	case 0x04:
	    GPIO_ResetLeds();		
	    GPIO_Write(GPIOE, 0x0F00);
	    break;
 
	case 0x05:
	    GPIO_ResetLeds();		
	    GPIO_Write(GPIOE, 0x1F00);
	    break;
 
	case 0x06:
	    GPIO_ResetLeds();		
	    GPIO_Write(GPIOE, 0x3F00);
	    break;
 
	case 0x07:
	    GPIO_ResetLeds();		
	    GPIO_Write(GPIOE, 0x7F00);
	    break;
 
	case 0x08:
	    GPIO_ResetLeds();		
	    GPIO_Write(GPIOE, 0xFF00);
	    break;
    }
 
    // Включаем прием данных для конечной точки 3
    SetEPRxValid(ENDP3);
}

Так..ну вроде бы на этом все. Вот полный проект: Проект для USB

Прошиваем микроконтроллер и тестируем! Вот, что получилось:Программа для работы с USB

Послали байт 0х04 — загорелось 4 светодиода, аналогично работает и для любого другого количества светодиодов ) Так что, на сегодня, пожалуй все, но опыты с USB, на этом только начинаются!

Понравилась статья? Поделись с друзьями!

Микроконтроллер STM32 и USB.: 132 комментария
  1. А не могли бы Вы дать подсказку как настроить передачу, с помощью функции USB_SIL_Write(), и может ли плата только передавать хосту, не принимая ничего.

    • В принципе при передаче все точно также, callback само собой для транзакций IN используется

  2. Огромный респект и спасибо автору. Начал практическое изучение МК с STM32, до этого была только теория. Очень интересует тема управления контроллером с компа по USB, прием-передача данных, настройка параметров периферии (например, задание частоты дискретизации АЦП). Опробовал Ваш проект из этой статьи на STM32F3Discovery. При компиляции выскочило 3 предупреждения, вот они:
    ..\source\hw_config.c(198): warning: #188-D: enumerated type mixed with another type
    return 0;
    ..\source\usb_endp.c(74): warning: #550-D: variable «USB_Rx_Cnt» was set but never used
    uint16_t USB_Rx_Cnt;
    linking…
    .\usb.axf: Warning: L6304W: Duplicate input file .\system_stm32f30x.o ignored.
    Но все заработало на ура.
    С нетерпением буду ждать новых (а лучше расширенного цикла) статей на эту тематику.

  3. Спасибо за описание, но проект по ссылке не полный нет файла самого проекта и он не собирается сразу.

  4. Доброе время суток! 🙂
    очень хорошая статья! большое спасибо! вот начинаю пробовать работать с ЮСБ, очень интересно! вот только вопросы возникают! можно ли на 10х процессорах сделать преобразователь например в 2 кома, или сделать хид клавиатуры и мыши? или хотябы на 207?! по одному устройству примеры работоспособны. заранее спасибо!

  5. Здравствуйте.
    Спасибо за статью. Но появились проблемы при отладке. Постоянно возникает прерывание USB_LP_IRQHandler. Это нормально? При этом отладчик уходит в завис и прервать его можно только насильно. Процессор STM32F373V8, установленный в STM32F3Discovery вместо 303-го. Может в этом проблема кроется?
    Пробовал и исходный проект от STM — тоже самое.

  6. Здравствуйте.
    Подскажите пожалуйста, а как переменную типа uint32_t ( ADC_Result из вашей статьи Работа с ADC и DMA) можно передать по USB, так как в этом проэкте переменная которая передается по USB — типа uint8_t.
    Заранее благодарен за ответ!

    • Передавать 4 байта просто:
      ADC_Result_1 = (ADC_Result & 0xFF000000) >> 24;
      ADC_Result_2 = (ADC_Result & 0x00FF0000) >> 16;
      ADC_Result_3 = (ADC_Result & 0x0000FF00) >> 8;
      ADC_Result_4 = (ADC_Result & 0x000000FF);

  7. Здравствуйте.
    Подскажите пожалуйста, программировал через Keil было все в норме потом вдруг стало. Error
    No target connected.
    Flash Download failed-Target DLL has beeh cancelled. На втором компе уже такое произошло. Дрова переустанавливал не помогло. Через STM32 ST-LINK Utility зашивает без проблем.

  8. Здравствуйте. А может уважаемый автор выложить проект под STM32F10x, который, как я понял, он брал за основу, а то чего-то проект собрать не получается.

  9. Да, и где в проекте вышеизложенная функция:
    void EP3_OUT_Callback(void). Она в main.c отсутствует.

  10. И еще, можно по подробнее о функциях USB_SIL_Write и USB_SIL_Read, можно ли просто бит считать без всяких буферов?

      • Только пример от ST глюченый, мк без соединения с компом зависает намертво даже отладчик от него отваливается.

  11. Вроде бы, STM32 с нуля, а как его питать, шить и отлаживать статей нет. Все на готовых платах.

    • Ну «с нуля», но в разумных пределах ) Нет никакого смысла делать платы, которые уже есть, лучше изучить программирование и сделать что-то новое и интересное. Если есть конкретные вопросы по схемам подключения, то на каждую плату ST можно найти официальную принципиальную схему, опять же, нет смысла дублировать их документацию и копировать схемы, которые и так можно найти.

  12. Тогда это не STM32 с нуля, а программирование STM32 для начинающих.
    С нуля, это как у буржуев, когда закрыта пропасть между МК и готовой платой, а в этой пропасти односторонняя макетка утюгом, прошивка всеми способами, моргание лампочкой, отладка и прочие радости.

    • Ну из всего перечисленного не описана разве что макетка утюгом, это же «STM с нуля», а не «ЛУТ с нуля».

    • Может Вы открыли рубрику «STM32 с нуля» и не пролистали страницы до первых записей, и поэтому возникло недопонимание?)

  13. Скажите пож что делать Я запрограммировал STM32SISCOVERY проектом который вы выложили, но после этого не могу больше запрограммировать чип Программатор выдает : Internal command error Похоже , что где-то установилась защита по записи в чип. Спасибо

    • При программировании попробуй так:
      — зажимай кнопку reset на плате
      — нажимай кнопку Program
      — через секунду-две отпускай кнопку reset

  14. Спасибо за статью. Наконец-то удалось запустить usb на stm32f3discovery. Возникла такая проблема. Если я использую библиотеки из Вашего проекта в своем проекте, то все работает нормально. Если же я беру исходные ST USB Library то проект не собирается, хотя список файлов, прикрепленных к проекту, идентичен. Нужно ли вносить какие-либо изменения в библиотеки, за исключением описанных Вами в статье? Хотел бы разобраться в этом вопросе, т к собираюсь использовать usb библиотеку для stm32f103.

  15. Посмотрел внимательнее — в Вашем проекте отличается заголовочный файл platform_config.h, раздел include. Но даже после его исправления проект не собрался, похоже есть еще какие-то различия.

  16. Установил все драйвера с официального сайта. USB ST-LINK работает исправно, а вот при подключении разъема USB USER в диспетчере устройств плата отображается как Unknown Device. Подскажите пожалуйста, в чем может быть проблема ?

  17. Добрый день, что означают эти строчки ?
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL;
    Где можно почитать это?

    • В даташите описаны режимы, в которых может работать вывод микроконтроллера. В этих строках вывод просто настраивается.

    • Тогда еще вариант ) Может система 64 битная? Были случаи (и не единичные), когда на х64 отказывалось напрочь работать.

  18. Та же проблема — virtual com-port установил, com-порт не появился, при подключении USB USER появляется сообщение -> Unknown Device.
    У меня Win 7 32 бит

  19. Сам понял свою ошибку — пытался подключить непрошитое устройство. После прошивки примера — все заработало и com-порт появился.

  20. Здравствуйте! Пытаюсь собрать проект в Keil, но выходят ошибки. Не подскажите в чём проблема.

    src\hw_config.c(68): warning: #177-D: variable «GPIO_InitStructure» was declared but never referenced
    GPIO_InitTypeDef GPIO_InitStructure;
    src\hw_config.c(231): error: #20: identifier «EVAL_COM1_IRQn» is undefined
    NVIC_InitStructure.NVIC_IRQChannel = EVAL_COM1_IRQn;
    src\hw_config.c(257): error: #20: identifier «USB_DISCONNECT» is undefined
    GPIO_ResetBits(USB_DISCONNECT, USB_DISCONNECT_PIN);
    src\hw_config.c(257): error: #20: identifier «USB_DISCONNECT_PIN» is undefined
    GPIO_ResetBits(USB_DISCONNECT, USB_DISCONNECT_PIN);
    src\hw_config.c(261): error: #20: identifier «USB_DISCONNECT» is undefined
    GPIO_SetBits(USB_DISCONNECT, USB_DISCONNECT_PIN);
    src\hw_config.c(261): error: #20: identifier «USB_DISCONNECT_PIN» is undefined
    GPIO_SetBits(USB_DISCONNECT, USB_DISCONNECT_PIN);
    src\hw_config.c(291): warning: #223-D: function «STM_EVAL_COMInit» declared implicitly
    STM_EVAL_COMInit(COM1, &USART_InitStructure);
    src\hw_config.c(291): error: #20: identifier «COM1» is undefined
    STM_EVAL_COMInit(COM1, &USART_InitStructure);
    src\hw_config.c(294): error: #20: identifier «EVAL_COM1» is undefined
    USART_ITConfig(EVAL_COM1, USART_IT_RXNE, ENABLE);
    src\hw_config.c(376): warning: #223-D: function «STM_EVAL_COMInit» declared implicitly
    STM_EVAL_COMInit(COM1, &USART_InitStructure);
    src\hw_config.c(376): error: #20: identifier «COM1» is undefined
    STM_EVAL_COMInit(COM1, &USART_InitStructure);
    src\hw_config.c(395): error: #20: identifier «EVAL_COM1» is undefined
    USART_SendData(EVAL_COM1, *(data_buffer + i));
    src\hw_config.c(451): error: #20: identifier «ENDP1_TXADDR» is undefined
    UserToPMABufferCopy(&USART_Rx_Buffer[USB_Tx_ptr], ENDP1_TXADDR, USB_Tx_length);
    src\hw_config.c(468): error: #20: identifier «EVAL_COM1» is undefined
    USART_Rx_Buffer[USART_Rx_ptr_in] = USART_ReceiveData(EVAL_COM1) & 0x7F;
    src\hw_config.c(472): error: #20: identifier «EVAL_COM1» is undefined
    USART_Rx_Buffer[USART_Rx_ptr_in] = USART_ReceiveData(EVAL_COM1);
    src\hw_config.c(495): error: #20: identifier «ID1» is undefined
    Device_Serial0 = *(uint32_t*)ID1;
    src\hw_config.c(496): error: #20: identifier «ID2» is undefined
    Device_Serial1 = *(uint32_t*)ID2;
    src\hw_config.c(497): error: #20: identifier «ID3» is undefined
    Device_Serial2 = *(uint32_t*)ID3;
    src\hw_config.c: 3 warnings, 15 errors
    compiling stm32_it.c…
    .\inc\hw_config.h(53): error: #20: identifier «FunctionalState» is undefined
    void USB_Cable_Config (FunctionalState NewState);
    .\inc\hw_config.h(56): error: #20: identifier «uint8_t» is undefined
    void USB_To_USART_Send_Data(uint8_t* data_buffer, uint8_t Nb_bytes);
    .\inc\hw_config.h(56): error: #20: identifier «uint8_t» is undefined
    void USB_To_USART_Send_Data(uint8_t* data_buffer, uint8_t Nb_bytes);
    src\stm32_it.c(187): error: #20: identifier «EVAL_COM1» is undefined
    if (USART_GetITStatus(EVAL_COM1, USART_IT_RXNE) != RESET)
    src\stm32_it.c(194): error: #20: identifier «EVAL_COM1» is undefined
    if (USART_GetFlagStatus(EVAL_COM1, USART_FLAG_ORE) != RESET)
    src\stm32_it.c: 0 warnings, 5 errors
    compiling usb_endp.c…
    src\usb_endp.c(89): error: #20: identifier «ENDP1_TXADDR» is undefined
    UserToPMABufferCopy(&USART_Rx_Buffer[USB_Tx_ptr], ENDP1_TXADDR, USB_Tx_length);
    src\usb_endp.c(103): error: #247: function «NOP_Process» has already been defined
    void EP3_OUT_Callback(void)
    src\usb_endp.c: 0 warnings, 2 errors
    compiling usb_prop.c…
    src\usb_prop.c(173): error: #20: identifier «ENDP1_TXADDR» is undefined
    SetEPTxAddr(ENDP1, ENDP1_TXADDR);
    src\usb_prop.c(179): error: #20: identifier «ENDP2_TXADDR» is undefined
    SetEPTxAddr(ENDP2, ENDP2_TXADDR);
    src\usb_prop.c(185): error: #20: identifier «ENDP3_RXADDR» is undefined
    SetEPRxAddr(ENDP3, ENDP3_RXADDR);
    src\usb_prop.c: 0 warnings, 3 errors
    «.\5.axf» — 25 Error(s), 3 Warning(s).

    • Скорее всего файлы не подключены к проекту, в которых определяются переменные, на которые компилятор ругается

  21. Готовый ваш проект работает нормально, но если пытаюсь собрать сам, то лечу в ошибку:
    system_stm32f30x.c: Error: C4065E: type of input file ‘USB’ unknown
    И ещё, у вас в списке указаны файлы и около них стоят плюсики, а у меня их нет.
    Так же в списке нет файла hw_config.h, хотя у вас написано:
    «Не забываем в файл hw_config.h дописать прототип для этой функции:
    void GPIO_ResetLeds(void);»
    Похоже я упускаю где-то какую-то мелочь *think*…..

  22. Попробовал поработать к STM32L-Discovery. Однако нарвался на вопрос —
    что делать с файлом platform_config,h? Он подключён в hw_config.h и содержит некоторые определения и инклюды, некорректные без использования тех Eval Board, для которых пример предназначен.

    • Убери оттуда просто все лишнее или вообще удали этот файл, если там нет ничего нужного и include с ним удали.

  23. Cпасибо за статью! не могли бы вы рассказать как сделать настройку на передачу данных в комп. никак не могу разобраться с USB_SIL_Write();

  24. Дмитрий, можно узнать какая была причина Вашей проблемы и как вы с ней справились?

  25. В статье, походу, используется более старая версия библиотек. Та же проблема. Или придется разбираться в новых, или юзай то, что автор положил.

  26. Здравствуйте! Приобрел программатор NAND на STM32F4. При коннекте определяется как linuxg_printer. Драйвер не могу найти и прогер работает без драйверов. Но запарило каждый раз это видеть. Что это за устройство? Может ему все-таки дрова дать? Найти их не могу, вот сведения об устройстве USBPRINT\LINUXG_PRINTER\7&2181D5ED&0&USB001

  27. Добрый день! Подскажите пожалуйста! Хочу Ваш пример адаптировать под свою плату. Она на STM32F107RCTx. Подскажите что нужно убрать и поправить в готовом проекте, не считая того что все ЧТО ДЛЯ STM32F4 заменить на STM32F1 ну там библиотеки и прочее. USB разъем совпадает полностью по схеме, а диоды у меня на РА4-7. Схему могу привести, если нужно. Главное что убирать, чтобы лишнего не было. А то я сделал сходу (то что изложил) и осталась одна ошибка: ..\Virtual_COM_Port\src\system_stm32f10x.c(261): error: #20: identifier «FLASH_BASE» is undefined

    • На самом деле проще всего создать вообще пустой проект для нового контроллера, а потом в него перетащить по очереди все файлы

  28. Сделал все свое! Не пойму что править или откуда брать — platform_config.h На него ссылается и ошибки выдает, там моей платформы нет, мне что там все закоментировать?

  29. Вылезла вот такая ошибка:
    source\hw_config.c(70): error: #20: identifier «RCC_APB2Periph_SYSCFG» is undefined
    Что не сделал или убрал лишнее?

  30. Я это прописал согласно настройкам в примере, где не описаны? Чего не хватает?

  31. А как быть если нужно отправить 2 посылки хосту через УЗБ?
    Например:
    CDC_Send_DATA («One», 3);
    CDC_Send_DATA («Two», 3);

    То в терминалку приходит только последняя отправленная строка. Если выждать хотя бы 1мс, то обе посылки проходят нормально.

  32. Так, а как можно обойти это ожидание без «костылей»? Часто есть потребностью в подобной отправке данных, использовать ф-цию задержки выглядит как «костыль» при чем не очень хороший, вот с ЮАРТом все проще — отправили символ — ждем в цикле флаг. С УЗБ можно что-то подобное сделать?

  33. Это не всегда удобно. Так нет никакого флага на проверку того, что можно следующую порцию данных отправлять?

    • Ну кадр вообще начинается с SOF-пакета (start of frame), можно в исходниках драйвера USB найти обработку этого пакета и туда добавить выставление флага.

  34. А коллбеке — EP1_IN_Callback если выставлять флаг? По идее же эта ф-ция выполняется, когда данные были отправлены или я не прав?

  35. Да, так получилось.
    Выставлю флаг в коллбеке EP1_IN_Callback, а в ф-ции отправки данных жду пока этот флаг выставиться.

  36. Подскажите пожалуйста,
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
    Устанавливает «1» в RCC_APB2ENR, AFIOEN[0] бит.
    AFIOEN: Alternate function IO clock enable
    За что этот бит отвечает? Какие «Alternate function» он enable-ит?
    Заранее — спасибо!

  37. Подскажите пожалуйста последовательность — какие прерывания генерирует USB, где находится обработчик этих прерываний и как вообще программа попадает в функции EP3_IN/OUT_Callback?

  38. Спасибо за статью, все работает. Возник небольшой вопрос, после прошивки и запуска отладчика, bDeviceState у меня равен 0 (UNCONNECTED) хотя плата сразу подключена к компу через usb и нормально отображается в устройствах. И для того чтобы bDeviceState сменился на рабочий CONFIGURED необходимо переткнуть usb. Подскажите, что необходимо вызывать для конфигурирования usb при инициализации в рабочий режим.

  39. Advanced Serial Port Monitor установилась вроде бы нормально но виртуальный COM порт в диспетчере устройств не отобразился. Пробовал на 3 компьютерах с разными версиями Windows и разрядностью системы. Одно и тоже… установку произвожу согласно файла readme.

    И еще не совсем ясно могу возможно ли используя Advanced Serial Port Monitor осуществить обмен между ПК и МК как Вашей статье :

    http://microtechnics.ru/qt-usb-custom-hid-biblioteka-libusb/

    и

    http://microtechnics.ru/stm32cube-usb-custom-hid-priem-i-peredacha-dannyx/

    Вместо программы написанной на Qt.

    • Нет, через Advanced Serial Port Monitor только если реализован класс виртуального ком-порта на микроконтроллере, с hid так не получится. И, соответственно, com-порт появится только если контроллер подключить, сам терминал com-порт не создает.

  40. Здравствуйте пробую реализовать данное задание на stm32f103rf не могу найти библиотеку stm32f10x_syscfg.h подобно stm32f30x_syscfg.h. Подскажите пожалуйста, что делать или где искать

    • По-моему, в F10x этих файлов нет. Нужно все функции инициализации под F10 переделать, а те, которых не окажется в SPL просто убрать. По идее должно работать.

      • Переделал, т.е. убрал syscfg и его тактирование, поменял пины и всё равно не работает, через куб прошивал тоже не распознаёт STM

          • Да. Возможно дело в драйверах, потому что com port так и не появился после установки драйверов в сайта ST. Подскажите что необходимо сделать, что бы появился COM port в диспетчере устройств. На stm32f103rf собрал отладочную плату, на ней реализовал USB, I2C, UART. всё кроме USB работает. USB_DP, USB_DM подсоединил через резисторы по 33 Ома.

        • А плата висит просто как неопознанное устройство? По схемотехнике можно попробовать повторить схему какой-нибудь отладочной платы типа Discovery, резисторы там, к примеру по 22 стоят… Я обычно подключаю так:
          1. D- через 22 Ома
          2. D+ тоже через 22
          3. D+ резистором 1.5 КОма подтянуто к питанию +3.3
          4. четвертый пин ЮСБ разъема через 100 КОм на землю.

          • Спасибо, попробую так сделать. А что делать с COM port в диспетчере устройств его там нет, после установки драйверов

          • четвертый пин ЮСБ разъема через 100 КОм на землю. А если usb тип B там всего 4 контакта, то этот резистор на 100к не нужен?

        • COM-порт в диспетчере появляется после подключения платы, может раньше драйвер иначе работал…я точно что-то не помню уже.

  41. Реализовал COM на STM32F401DISCOVERY не появляется COM порт в диспетчере устройств

  42. Здравствуйте реализовал usb на stm32f103rf с помощью cube, компьютер видит vcp, если если использовать ваш пример и убрать syscfg (так как его нет ) и изменить AF выводов usb не определяется, подскажите что делать.

        • А PA3 это что за ножка? В целом вроде бы все нормально, можно попробовать посмотреть под отладчиком попадает ли программа в обработчик прерываний USB при подключении.

          • Всё, решил проблему, спасибо)

          • Можно все сделать как в статье про передачу, но флаг needToSend устанавливать по прошествии секунды.

          • в резисторе на 1.5к (в пике его не было и USB работал ) и с частотой намудрил, в итоге взял настройку RCC из примера.
            А как вызывать прерывание только для передачи, без отправки команды микроконтроллеру? Нужно же сначала попасть в ЕП чтобы включить передачу данных, а как попасть если ничего не передаём?

          • Необходимо каждую секунду отправлять с stm данные хосту. Как это реализовать без отправки байта от хоста. Какую функцию или какое прерывание необходимо вызвать?

          • Т.е. включаем ЕР1 в SOF выполняется условие if и программа залетает в Handler. Так?

  43. Использую два устройства на STM32. Одно управляет другим по радиоканалу (UART модемы). Возникло желание подключать одно к другому и по проводам. Так как в устройствах есть USB разъемы (использую как COM порт для настройки и прошивки устройств), думаю как можно передать данные из одного STM в другой STM через USB.
    Направьте на путь истинный как это можно реализовать.

        • Я такую связь, честно говоря, не реализовывал — не было необходимости… Надо в документации смотреть, что вообще Host в STM поддерживает.

  44. А подскажите, пожалуйста, что делать с клоком для USB. У меня есть STM32F373 и внешний источник на 4,194304 МГц.Как задать необходимую частоту, да и какую задавать? Переключться ли на внутрений источник или крутьт делители/предделители?

    • Нужно чтобы на USB было ровно 48 МГц. Либо подобрать предделители так, чтобы из частоты внешнего источника получить 48 МГц, либо использовать внутренний. Но внешний стабильнее внутреннего, так что предпочтительнее первый вариант.

      • Понятно. А такой вопрос: в серии STM32F373 в мануале прописано, что для USB, обязательно брать внешний источник. Это действительно обязательное требование, или рекомендация. У меня так и не получилось через настройку цепей тактирования (как через cube, так и через стандартные библиотеки переферии) поднять USB на внутреннем источнике.

        • Конкретно про F373 не могу сказать… Разные контроллеры F1/F4 работали от внутреннего источника (с USB), но были случаи когда работали крайне нестабильно именно из-за нестабильности внутреннего генератора. Так что я бы все-таки внешний задействовал.

          • Препаял кварец. В итоге устройство вполне корректно определилось работая с внешнего кварца.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *