Наверняка многие из вас начинали свое знакомство с микроконтроллерной техникой с платы Arduino, которая проста в освоении и позволяет реализовать огромное число сравнительно несложных проектов. Но при создании сложных устройств вы неизбежно столкнетесь с ограничениями платы Arduino: небольшая вычислительная мощность, скромный объем памяти, сравнительно малое число свободных контактов.
Более "продвинутой" по сравнению с платой Arduino в этом плане является плата STM32F103C8 (Blue Pill), достаточно много проектов с которой мы рассмотрели на нашем сайте. Но в этой статье мы рассмотрим начало работы со сравнительно новым продуктом в семействе плат STM32 – платой разработки STM32 Nucleo64. Для понимания основ работы с платой STM32 Nucleo64 вы можете посмотреть обучающее видео по ней от авторов данной статьи (ссылка на источник приведена в конце статьи). Оно на английском языке, но достаточно понятное. В данном видео показана возможность программирования платы STM32 Nucleo64 с помощью платформы ARM Mbed, но в данной статье мы будем использовать вместо нее платформу от компании ST Microelectronics под названием TrueSTUDIO.
Также на нашем сайте вы можете посмотреть обзор отладочной платы STM32F Nucleo-64.
Примечание: существует достаточно много разновидностей платы STM32 Nucleo64, в данной статье мы будем использовать плату с обозначением NUCLEO-F030R8, отличающейся невысокой ценой. Но если даже у вас другая разновидность платы STM32 Nucleo64, то большинство моментов, описанных в данной статье, будет подходить и для нее.
Выбор платформы разработки для платы STM32 Nucleo64
Для работы с любым микроконтроллером (платой) необходима специализированная интегрированная среда разработки (Integrated Development Environment, IDE): для плат Arduino это Arduino IDE, для микроконтроллеров AVR – Atmel Studio, для микроконтроллеров PIC – MP Lab и т.д. Для работы с платой STM32 Nucleo64 необходима подходящая для нее IDE. Семейство плат STM32 основано на 32-битных микроконтроллерах и поддерживает следующие IDE и инструментальные средства:
- IAR Embedded Workbench® for ARM® (EWARM);
- MDK-ARM Keil;
- TrueSTUDIO;
- System Workbench for STM32.
В нашем проекте мы будем использовать платформу TrueSTUDIO для написания программы, ее компиляции и отладки поскольку она бесплатна для скачивания и может даже использоваться для коммерческих проектов без нарушения лицензии. Также мы будем использовать программу STM32CubeMX для облегчения работы с периферийными устройствами (ранее мы использовали данную программу для облегчения работы с платой STM32F103C8). Для загрузки программы (hex файла) в плату STM32 Nucleo64 можно использовать инструмент под названием STM32 ST-LINK, но в нашем проекте вместо него мы будем использовать TrueSTUDIO, которая имеет режим отладки (debug mode) и позволяет загружать hex файл непосредственно в платы STM32. Скачать TrueSTUIO и STM32CubeMX можно по следующим ссылкам:
Необходимые компоненты
- Отладочная плата STM32 Nucleo64 (купить на AliExpress).
- Резистор 1 кОм (купить на AliExpress).
- Светодиод (купить на AliExpress).
- Кнопка.
- Макетная плата.
- Соединительные провода.
Реклама: ООО "АЛИБАБА.КОМ (РУ)" ИНН: 7703380158
Схема проекта
Схема для управления светодиодом с помощью платы STM32 Nucleo64 представлена на следующем рисунке.
Как вы уже, наверное, знаете, плата STM32 Nucleo64 имеет два набора контактов – по одному на каждой стороне, которые называются контактами ST Morpho.
В нашем проекте нам необходимо подключить светодиод к контакту PA5 порта PORTA, а кнопку – к контакту PC13 порта PORTC. Внешний вид собранной конструкции проекта показан на следующем рисунке.
Также вместо внешних светодиода и кнопки можно использовать встроенные в плату светодиод и кнопку. Мы использовали внешние компоненты для большей наглядности.
Начало работы с платой STM32 Nucleo64 с помощью программы STM32CubeMX
Выполните следующую последовательность шагов.
Шаг 1. После установки запустите программу STM32CubeMX, в ней в селекторе плат выберите плату STM32.
Шаг 2. После этого выполните поиск платы STM32 с названием NUCLEO-F030R8 и нажмите на появившуюся картинку платы. Если у вас другая разновидность платы STM32 Nucleo64, то выполните поиск по ее названию. Программа STM32CubeMX поддерживает все виды плат STM32 от компании ST Microelectronics.
Шаг 3. Затем нажмите на "yes" как показано на картинке ниже чтобы инициализировать все контакты платы в режим по умолчанию (default mode). В дальнейшем мы можем изменить их настройки по своему желанию.
После нажатия на ‘Yes’ вы увидите экран как показано на рисунке ниже. Зеленый цвет контактов свидетельствует о том, что они установлены в режим по умолчанию.
Шаг 4. Затем можно вручную сконфигурировать режим работы необходимых нам контактов. В нашем проекте мы будем включать светодиод с помощью кнопки, поэтому нам необходимо установить режим работы для контакта, к которому подключен светодиод, на вывод данных (output), а для контакта, к которому подключена кнопка – на ввод данных (input).
Для подключения светодиода в нашем проекте мы использовали контакт PA5, поэтому в программе STM32CubeMX мы установим для него режим GPIO_Output как показано на следующем рисунке.
Аналогичным образом мы установили для контакта PC13 режим GPIO_Input чтобы на нем можно было считывать состояние кнопки.
Также режимы работы контактов можно настроить на вкладке конфигурации (configuration tab) как показано на рисунке ниже.
Шаг 5. На следующем шаге можно вручную настроить желаемую частоту работы микроконтроллера и контактов платы в зависимости от частоты внешнего или внутреннего генератора. По умолчанию используется внутренний кварцевый генератор на 8 MHz и при режиме PLL эта частота преобразуется в 48MHz. То есть по умолчанию контакты платы STM32 и ее микропроцессор работают на частоте 48MHz.
Шаг 6. Теперь перейдите в менеджер проектов (project manager), в котором введите имя для своего проекта, укажите его местоположение и выберите необходимые инструментальные средства (toolchain) или IDE. Мы в качестве IDE будем использовать TrueSTUDIO, поэтому выберем ее как показано на рисунке ниже.
Шаг 7. После этого нажмите на ссылку "Generate Code" (обведена красной линией на следующем рисунке).
Шаг 8. После этого вы на экране увидите всплывающее окно, в нем нажмите на кнопку открытия проекта (open project). Но прежде чем выполнять данный шаг убедитесь в том, что вы установили TrueSTUDIO.
Программирование платы STM32 Nucleo64 с помощью TrueSTUDIO
После нажатия на кнопку открытия проекта в предыдущем пункте программа TrueSTUDIO запустится у вас автоматически. Если она запросит у вас местоположение проекта (workspace location) – укажите его, или используйте местоположение по умолчанию.
После этого откроется окно показанное на следующем рисунке – в нем необходимо нажать на иконку в левом верхнем углу, обведенную красным цветом на показанном рисунке.
После этого вы увидите код программы в TrueSTUDIO IDE. На левой стороне в папке ‘src’ вы увидите все файлы программы (с расширением .c), которые были сгенерированы для нас программой STM32Cube. В нашем проекте нам необходимо будет внести изменения только в файл main.c. Полный код данного файла с необходимыми изменениями приведен в конце нашей статьи.
Программа управления светодиодом для платы STM32 Nucleo64
Поскольку все необходимые файлы для нашего проекта были сгенерированы программой STM32CubeMX, нам необходимо просто задать для контакта светодиода режим работы на вывод данных, а для контакта кнопки – режим работы на ввод данных. Для этого необходимо отредактировать файл main.c.
Нам нужно дописать код для включения/выключения светодиода с помощью кнопки. Для этого нам необходимо дать осмысленные имена (инициализировать) контактам, к которым подключены кнопка и светодиод. Сначала сконфигурируем контакт 5 порта PORTA, к которому подключен светодиод.
1 2 |
#define LED_PORT GPIOA #define LED_PIN GPIO_PIN_5 |
Затем настроим контакт 13 порта PORTC.
1 2 |
#define SW_PORT GPIOC #define SW_PIN GPIO_PIN_13 |
Затем в функции main инициализируем все используемые контакты.
1 2 3 |
/* Initialize all configured peripherals */ MX_GPIO_Init(); MX_USART2_Init(); |
И затем будем считывать состояние кнопки и в зависимости от ее состояния включать или выключать светодиод.
1 2 3 4 5 6 7 8 9 10 |
While (1) { /* USER CODE END WHILE */ If (!HAL_GPIO_ReadPin(SW_PORT, SW_PIN)) { HAL_GPIO_TogglePin(SW_PORT, LED_PIN); HAL_Delay(200); } /* USER CODE BEGIN 3 */ } |
Функция HAL_GPIO_ReadPin(SW_PORT, SW_PIN) имеет два аргумента: один из них название порта, а второй – контакт, к которому подключена кнопка. Режим работы данного контакта был сконфигурирован нами на вывод данных в программе STM32CubeMX.
Отладка и загрузка программы в STM32 Nucleo64 с помощью TrueSTUDIO
Подключите вашу плату STM32 Nucleo64 к компьютеру, используя кабель для программирования. После ее подключения драйвер для нее должен установиться автоматически, вы можете проверить это в диспетчере устройств.
Затем нажмите на иконку отладки программы, обведенную красным цветом на рисунке ниже. После этого произойдет компиляция программы и вход в режим ее отладки.
В режиме отладки (debug mode) код программы будет автоматически загружен в плату. После этого нам необходимо запустить код программы на выполнение нажав ‘Resume’ (обведена красным цветом на рисунке ниже) или F8.
После этого можно протестировать управление светодиодом нажимая на кнопку. В соответствии с кодом программы светодиод должен изменять свое состояние с каждым нажатием кнопки. Более подробно работу проекта вы можете посмотреть на видео, приведенном в конце статьи.
После тестирования мы можем прервать (terminate) работу программы нажав для этого иконку остановки программы, обведенную красным цветом на следующем рисунке.
Исходный код программы (скетча)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 |
/* USER CODE BEGIN Header */ /** ****************************************************************************** * @file : main.c * @brief : Main program body ****************************************************************************** * @attention * * <h2><center>© Copyright (c) 2020 STMicroelectronics. * All rights reserved.</center></h2> * * This software component is licensed by ST under BSD 3-Clause license, * the "License"; You may not use this file except in compliance with the * License. You may obtain a copy of the License at: * opensource.org/licenses/BSD-3-Clause * ****************************************************************************** */ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "main.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ #define LED_PORT GPIOA #define LED_PIN GPIO_PIN_5 #define SW_PORT GPIOC #define SW_PIN GPIO_PIN_13 /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ UART_HandleTypeDef huart2; /* USER CODE BEGIN PV */ /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_USART2_UART_Init(void); /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ /** * @brief The application entry point. * @retval int */ int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_USART2_UART_Init(); /* USER CODE BEGIN 2 */ /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ if (!HAL_GPIO_ReadPin(SW_PORT, SW_PIN)) { HAL_GPIO_TogglePin(LED_PORT, LED_PIN); HAL_Delay(200); } /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ } /** * @brief System Clock Configuration * @retval None */ void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; /** Initializes the CPU, AHB and APB busses clocks */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL12; RCC_OscInitStruct.PLL.PREDIV = RCC_PREDIV_DIV1; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } /** Initializes the CPU, AHB and APB busses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK) { Error_Handler(); } } /** * @brief USART2 Initialization Function * @param None * @retval None */ static void MX_USART2_UART_Init(void) { /* USER CODE BEGIN USART2_Init 0 */ /* USER CODE END USART2_Init 0 */ /* USER CODE BEGIN USART2_Init 1 */ /* USER CODE END USART2_Init 1 */ huart2.Instance = USART2; huart2.Init.BaudRate = 38400; huart2.Init.WordLength = UART_WORDLENGTH_8B; huart2.Init.StopBits = UART_STOPBITS_1; huart2.Init.Parity = UART_PARITY_NONE; huart2.Init.Mode = UART_MODE_TX_RX; huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart2.Init.OverSampling = UART_OVERSAMPLING_16; huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE; huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; if (HAL_UART_Init(&huart2) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN USART2_Init 2 */ /* USER CODE END USART2_Init 2 */ } /** * @brief GPIO Initialization Function * @param None * @retval None */ static void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; /* GPIO Ports Clock Enable */ __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOF_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_RESET); /*Configure GPIO pin : PC13 */ GPIO_InitStruct.Pin = GPIO_PIN_13; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_PULLUP; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); /*Configure GPIO pin : LD2_Pin */ GPIO_InitStruct.Pin = LD2_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(LD2_GPIO_Port, &GPIO_InitStruct); } /* USER CODE BEGIN 4 */ /* USER CODE END 4 */ /** * @brief This function is executed in case of error occurrence. * @retval None */ void Error_Handler(void) { /* USER CODE BEGIN Error_Handler_Debug */ /* User can add his own implementation to report the HAL error return state */ /* USER CODE END Error_Handler_Debug */ } #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */ void assert_failed(char *file, uint32_t line) { /* USER CODE BEGIN 6 */ /* User can add his own implementation to report the file name and line number, tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* USER CODE END 6 */ } #endif /* USE_FULL_ASSERT */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
Вы сами то проверяли? Ничего не работает, причем ошибки каждый раз разные)
Не, сам не проверял потому что у меня такой платы в наличии нет. Только перевел данную статью. Ну у автора статьи на видео показано же что все работает. Может он просто при описании своего проекта опечатку какую-нибудь допустил. Но я не сомневаюсь в том что у него это получилось. Сайт хороший, и с него я перевел уже очень много статей для своего сайта. И очень редко поступают жалобы на то, что в них что то не работает. В основном это касается только уже старых статей, где использованы старые версии необходимых библиотек, которые в текущий момент уже неактуальны
спасибо за материал! дай вам бог здоровьичка!
Спасибо и вам что оценили мой труд