آموزش برنامه نویسی STM32 با کیل Keil و STM32Cube MX
محتویات
سلام. آموزش برنامه نویسی STM32 با کیل Keil uVision و STM32Cube MX را آماده کردیم.
آموزش کد نویسی روی برد STM32 با کیل
میکروکنترلرهای STM32 که از معماری ARM Cortex M استفاده می کنند ، امروزه رواج یافته و به دلیل ویژگی های زیاد ، هزینه کم و کارایی بالا در بسیاری از پروژه ها مورد استفاده قرار می گیرند. ما برنامه نویسی STM32 با آردوینو را قبلا آموزش داده ایم. برنامه نویسی STM32 با Arduino IDE بسیار ساده است ، زیرا تعداد زیادی کتابخانه برای سنسورهای مختلف برای انجام هر کار وجود دارد و ما فقط باید آن کتابخانه ها را در برنامه اضافه کنیم. برنامه نویسی ARM با آردوینو روشی آسان است و ممکن است در مورد پردازنده های ARM باعث یادگیری عمیق نشود. بنابراین اکنون در مرحله برنامه نویسی ARM هستیم. با این کار ما می توانیم نه تنها ساختار کد خود را بهبود بخشیم بلکه با استفاده نکردن از کتابخانه های غیر ضروری می توان فضای حافظه را نیز ذخیره کرد.
STMicroelectronic ابزاری به نام STM32Cube MX معرفی کرد که کد اصلی را با توجه به لوازم جانبی و برد انتخابی STM32 تولید می کند. بنابراین نیازی نیست که نگران برنامه نویسی برای درایور اصلی و لوازم جانبی باشیم. علاوه بر این از این کد تولید شده می توان در Keil uVision برای ویرایش با توجه به نیاز استفاده کرد. سرانجام این کد با استفاده از پروگرامر ST-Link از STMicroelectect در STM32 بارگذاری می شود.
در این آموزش نحوه برنامه نویسی روی برد قرص آبی یا همان STM32 با استفاده از کیل یو ویژن (Keil uVision) را می آموزیم و در نهایت یک پروژه را طراحی میکنیم که با فشردن کلید، LED را روشن میکند. ما کد را با استفاده از STM32Cube MX تولید می کنیم و سپس کد را با استفاده از Keil uVision در STM32F103C8 ویرایش و بارگذاری می کنیم. قبل از جزییات ، ما ابتدا با پروگرامر ST-LINK و ابزار نرم افزاری STM32CubeMX آشنا می شویم.
پروگرامر ST-LINK V2
ST-LINK / V2 یک دیباگر برنامه و پروگرامر برای خانواده های میکروکنترلر STM8 و STM32 است. با استفاده از این ST-LINK می توانیم کد را در STM32F103C8 و سایر میکروکنترلرهای STM8 و STM32 بارگذاری کنیم. برای ارتباط با هر میکروکنترلر STM8 یا STM32 که در یک برد قرار دارند، از ماژول های ارتباطتک سیم (SWIM) و JTAG / serial دیباگر سیم (سریال SWD) استفاده می شود. از آنجا که برنامه های STM32 از رابط کاربری کامل USB برای برقراری ارتباط با محیط های توسعه یکپارچه Atollic ، IAR ، Keil یا TASKING استفاده می کنند، بنابراین می توانیم از این سخت افزار برای برنامه ریزی میکروکنترلرهای STM 8 & STM32 استفاده کنیم.
در بالا تصویر دانگل ST-LINK V2 از STMicroelectronic مشاهده میشود که طیف کاملی از STM32 SWD ، دیباگر و رابط کاربری ساده 4 سیم (از جمله قدرت) را پشتیبانی می کند. این دانگل در رنگهای متنوعی موجود است. بدنه از آلیاژ آلومینیوم ساخته شده است. این دانگل یک LED آبی دارد که برای مشاهده وضعیت کار ST-LINK استفاده می شود. همانطور که در تصویر بالا مشاهده می کنیم نام پین ها به وضوح روی بدنه مشخص شده است. میتوان برنامه ها را با آن با نرم افزار Keil روی میکروکنترلر های STM32 فلش کرد. بنابراین در این آموزش خواهیم دید چگونه میتوان از این پروگرامر St link برای برنامه نویسی میکروکنترلر های STM 32 استفاده کرد. تصویر زیر پین های ماژول ST-LINK V2 را نشان میدهد.
STM32CubeMX چیست؟
ابزار STM32CubeMX بخشی از STMicroelectronic STMCube است. این نرم افزار با کاهش زمان و هزینه توسعه ، پیشرفت را آسان تر می کند. STM32Cube شامل STM32CubeMX است که یک ابزار پیکربندی گرافیکی است که امکان تولید کد اولیه C را فراهم می کند. این کد می تواند در محیط های مختلف توسعه مانند keil uVision ، GCC ، IAR و … مورد استفاده قرار گیرد. دانلود ابزار STM32CubeMX
STM32CubeMX دارای ویژگی های زیر است :
- حل مشکلات پین ها
- کمک به تنظیم درخت ساعت
- محاسبه گر مصرف برق
- یکربندی محیطی MCU مانند پین های GPIO ، USART و …
- پیکربندی محیطی MCU را برای Stack های میانی مانند USB ، TCP / IP و …
قطعات مورد نیاز
- STM32 – برد توسعه (BluePill) (STM32F103C8T6)
- پروگرامر ST-LINK V2
- دکمه
- LED
مدار راه اندازی STM32 با Keil
تصویر زیر شماتیک مدار این پروژه را نشان میدهد که ما در آن یک دکمه و یک ال ای دی را به برد STM32 متصل میکنیم.
اتصال بین ST-LINK V2 و STM32F103C8
در اینجا بورد STM32 Blue Pill از ST-LINK که به درگاه USB رایانه متصل است، تغذیه می شود. بنابراین لازم نیست که STM32 را جداگانه نیرو دهیم. در جدول زیر ارتباط بین ST-Link و برد قرص آبی نشان داده شده است.
STM32F103C8 | ST-Link V2 |
GND | GND |
SWCLK | SWCLK |
SWDIO | SWDIO |
3.3V | 3.3V |
با فشار دادن یک دکمه، از LED برای نشان دادن خروجی از صفحه Blue Pill استفاده می شود. آند LED به پین PC13 برد STM32 متصل شده و کاتد پایه به GND متصل است.
یک دکمه برای ارائه ورودی به پین PA1 برد STM32 وصل شده است. همچنین باید از مقاومت 10 کیلو اهم استفاده کنیم زیرا ممکن است هنگام آزاد شدن دکمه، نویز بوجود آید و دوباره ال ای دی روشن شود. یک انتهای دکمه به زمین وصل می شود و انتهای دیگر به پین PA1 و یک مقاومت تا 10k نیز به 3.3 ولت متصل است
ایجاد برنامه در STM32 با استفاده از Keil uVision و ST-Link
مرحله 1: ابتدا تمامی درایورهای دستگاه را برای ST-LINK V ، ابزارهای نرم افزاری STM32Cube MX & Keil uVision و بستههای لازم برای STM32F103C8 را نصب کنید.
مرحله 2: STM32Cube MX را باز کنید.
مرحله 3: سپس بر روی New Project کلیک کنید.
مرحله 4: جستجو و میکروکنترلر STM32F103C8 خود را انتخاب کنید.
مرحله 5: – اکنون پین های STM32F103C8 ظاهر می شوند ، در اینجا می توانیم تنظیمات پین ها را انجام دهیم. همچنین می توانیم پین های خود را مطابق با پروژه خود در قسمت لوازم جانبی انتخاب کنیم.
مرحله 6: همچنین می توانید مستقیماً روی پین کلیک کنید و لیستی ظاهر می شود ، حالا پیکربندی پین مورد نیاز را انتخاب کنید.
مرحله 7: – برای این پروژه ما PA1 را به عنوان ورودی GPIO انتخاب میکنیم. سپس پین PC13 را به عنوان خروجی GPIO و SYS debug SERIAL WIRE انتخاب میکنیم. پین های انتخاب شده و پیکربندی شده با رنگ سبز ظاهر می شوند. در تصویر زیر می توانید مشاهده کنید.
مرحله 8: در تب Configuration ، مانند تصویر زیر GPIO را انتخاب کنید تا پین های GPIO را برای پین هایی که انتخاب کرده ایم تنظیم کنید.
مرحله 9: در مرحله بعد در پنجره pin configuration می توانیم User Label را برای پین هایی که استفاده می کنیم پیکربندی کنیم ، یعنی نام های پین تعریف شده توسط کاربر.
مرحله 10: پس از آن بر روی Project >> Generate Code کلیک کنید.
مرحله 11: اکنون پنجره project settings ظاهر می شود. در این کادر نام و محل پروژه خود را انتخاب کرده و محیط توسعه را انتخاب می کنیم. ما از Keil استفاده می کنیم بنابراین MDK-ARMv5 را به عنوان IDE انتخاب کنید.
مرحله 12: در تب Generator Code ، فقط پرونده های کتابخانه لازم را کپی کنید و سپس بر روی OK کلیک کنید.
مرحله 13: – اکنون پنجره تولید کد ظاهر می شود. Open Project را انتخاب کنید تا کد تولید شده در Keil uvsion به طور خودکار پروژه باز شود.
مرحله 14: اکنون Keil uVision با کد تولید شده ما در STM32CubeMx با همان نام پروژه با کتابخانه و کدهای لازم که برای پین های انتخاب شده تنظیم شده است ، باز می شود.
مرحله 15: اکنون فقط کافی است که منطقی را برای انجام برخی اقدامات در LED خروجی (پین PC13) در هنگام فشردن دکمه در ورودی GPIO (پین PA1) وارد کنیم. بنابراین main.c را انتخاب کنید تا برخی کدها را در آن وارد کنید.
مرحله 16: – اکنون کد را در While1 اضافه کنید.
while (1) { if(HAL_GPIO_ReadPin(BUTN_GPIO_Port,BUTN_Pin)==0) //=> شتخیص فشرده شدن دکمه { HAL_GPIO_WritePin(LEDOUT_GPIO_Port,LEDOUT_Pin,1); //ایجاد خروجی هنگام فشرده شدن دکمه } else { HAL_GPIO_WritePin(LEDOUT_GPIO_Port,LEDOUT_Pin,0); //غیرفعال کردن خروجی هنگام رها شدن دکمه } }
مرحله 17: – پس از پایان ویرایش کد ، روی Options for Target کلیک کنید و سپس به تب Debug بروید و ST-LINK Debugger را انتخاب کنید.
همچنین ، بر روی دکمه Settings و سپس در زیر گزینه Flash Download ، گزینه Reset and Run را تیک بزنید و “ok” را بزنید.
مرحله 18: اکنون روی آیکون Rebuild کلیک کنید تا کلیه فایلهای هدف بازسازی شود.
مرحله 19: اکنون می توانید ST-LINK را با اتصال مدار به رایانه وصل کنید و بر روی نماد DOWNLOAD کلیک کنید یا F8 را فشار دهید تا STM32F103C8 را با کدی که تولید کرده اید فلش کنید.
مرحله 20: می توانید نشانگر چشمک زن را در پایین پنجره keil uVision مشاهده کنید.
نتیجه نهایی برنامه نویسی STM32 با Keil
حالا وقتی دکمه را فشار می دهیم ، LED روشن می شود و وقتی آن را رها می کنیم ، LED خاموش می شود.
کد کامل پروژه چشمک زن در Keil
قسمت اصلی که در برنامه تولید شده اضافه کرده ایم در زیر آورده شده است. این کد زیر باید در while 1 برنامه main.c ایجاد شده توسط STM32CubeMX درج شود. برای یادگیری نحوه اضافه کردن آن در برنامه main.c می توانید به مرحله 15 و مرحله 17 برگردید.
while (1) { if(HAL_GPIO_ReadPin(BUTN_GPIO_Port,BUTN_Pin)==0) //=> شتخیص فشرده شدن دکمه { HAL_GPIO_WritePin(LEDOUT_GPIO_Port,LEDOUT_Pin,1); //ایجاد خروجی هنگام فشرده شدن دکمه } else { HAL_GPIO_WritePin(LEDOUT_GPIO_Port,LEDOUT_Pin,0); //غیرفعال کردن خروجی هنگام رها شدن دکمه } }
کد کامل main.c در زیر آورده شده است. علاوه بر این ، می توانید مجموعه کاملی از پروژه های STM32 ما را ببینید.
/* Includes ------------------------------------------------------------------*/ #include "main.h" #include "stm32f1xx_hal.h" /* USER CODE BEGIN Includes */ /* USER CODE END Includes */ /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN PV */ /* Private variables ---------------------------------------------------------*/ /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); static void MX_GPIO_Init(void); /* USER CODE BEGIN PFP */ /* Private function prototypes -----------------------------------------------*/ /* USER CODE END PFP */ /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ /** * @brief The application entry point. * * @retval None */ 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(); /* USER CODE BEGIN 2 */ /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { if(HAL_GPIO_ReadPin(BUTN_GPIO_Port,BUTN_Pin)==0) //=> Button is Pressed { HAL_GPIO_WritePin(LEDOUT_GPIO_Port,LEDOUT_Pin,1); } else //=>Button is released { HAL_GPIO_WritePin(LEDOUT_GPIO_Port,LEDOUT_Pin,0); } /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ } /** * @brief System Clock Configuration * @retval None */ void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct; RCC_ClkInitTypeDef RCC_ClkInitStruct; /**Initializes the CPU, AHB and APB busses clocks */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSICalibrationValue = 16; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } /**Initializes the CPU, AHB and APB busses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } /**Configure the Systick interrupt time */ HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000); /**Configure the Systick */ HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK); /* SysTick_IRQn interrupt configuration */ HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0); } /** Configure pins as * Analog * Input * Output * EVENT_OUT * EXTI */ static void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct; /* GPIO Ports Clock Enable */ __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(LEDOUT_GPIO_Port, LEDOUT_Pin, GPIO_PIN_RESET); /*Configure GPIO pin : LEDOUT_Pin */ GPIO_InitStruct.Pin = LEDOUT_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(LEDOUT_GPIO_Port, &GPIO_InitStruct); /*Configure GPIO pin : BUTN_Pin */ GPIO_InitStruct.Pin = BUTN_Pin; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(BUTN_GPIO_Port, &GPIO_InitStruct); } /* USER CODE BEGIN 4 */ /* USER CODE END 4 */ /** * @brief This function is executed in case of error occurrence. * @param file: The file name as string. * @param line: The line in file as a number. * @retval None */ void _Error_Handler(char *file, int line) { /* USER CODE BEGIN Error_Handler_Debug */ /* User can add his own implementation to report the HAL error return state */ while(1) { if(HAL_GPIO_ReadPin(BUTN_GPIO_Port,BUTN_Pin)==0) //=> DETECTS Button is Pressed { HAL_GPIO_WritePin(LEDOUT_GPIO_Port,LEDOUT_Pin,1); //To make output high when button pressesd } else { HAL_GPIO_WritePin(LEDOUT_GPIO_Port,LEDOUT_Pin,0); //To make output Low when button de pressed } } /* 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(uint8_t* 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 */
درود بر شما
آیا این آموزش ها در مورد stm32 را ادامه میدهید ؟اخه روش شما خوبه
سلام عزیز
خوشحالیم که از آموزش ها رضایت دارید
در منوی سایت میتوانید تمام مطالب مربوط به آموزش STM32 را مشاهده کنید یا از دوره آموزش STM32 استفاده کنید.
سلام سوالم اینه وقتی میخوام کلا چیزی بنویسم توس کیل فقط ?????? مینویسه باید چیکار کنم؟
سلام رشته با فرمت uint_8 رو میشه به رشته با فرمت char تبدیل کرد اگه کسی راهنماییم کنه ممنون میشم
سلام خسته نباشید
من وقتی تو کیوب تغییرات رو اعمال میکنم و جنریت رو میزنم، قسمت اوپن پروجکت نمیاد که فایل رو به کیل منتقل کنه فقط اوپن فولدر میاد که اونم تو کیل باز نمیشه
باید چیکار کنم؟
سلام.
من یک پروگرمر st-link تهیه کردم که متاسفانه مثل اینکه فیکه و به صورت خودکار آپدیت نمیشه…
می خواستم ببینم آیا راهی هست که بشه به صورت آفلاین آپدیتش کرد؟
بعد اینکه من از Blue pill برای آموزش استفاده می کنم، آیا بدون پروگرمر st-link میشه با keil , stmcubeIde برنامه نوشت و روی میکرو ریخت؟
سلام وقت بخیر من تازه می خوام وارد حوزه میکروکنترلر های arm بشم میخواستم بدونم که برای یاد گرفتن arm بهتره از نرم افزار keil استفاده کنم یا stm32 cube ide
سلام
اگر تازه وارد هستید آردوینو بهتر هست
میتونید دوره آموزش stm32 ما رو مشاهده کنید
سلام در صورتی که بخوایم با هربار فشردن کلید مدل چشمک زدن عوض بشه میشه کمی توضیح بدین ؟
سلام عزیز
برای یادگیری برنامه نویسی STM32 میتونید دوره آموزش STM32 رو مشاهده کنید
سلام و درود خدمت استاد عزیز
جسارتا میخواستم ببینم شما پروژه هم قبول میکنید (فقط برنامه نویسی) یا خیر ؟
سلام عزیز، خیر
سلام مهندس جان وقت بخیر بنده برای تکمیل پروژه ای نیاز مند برنامه نویس کیل هستم در صورتی که امکان دارد به ایمیل بنده پیام بدهید تا با شما تماس بگیرم
سلام وقت بخير
چند وقتي هست با آرم کار ميکنم و مشکل اين رو دارم که ميخوام با ليبل کار کنم و از اصطلاحات بلند برنامه نويسي در آرم استفاده نکنم ، من در نرم افزار کيوب تعريفهام رو انجام دادم و براي هر پين يک ليبل تعريف کردم حالا انتظار دارم که در نرم افزار کيل اين بصورت همون لبلها يي که تعريف کردم برنامه نيس کنم نه يک اصطلاح بلند و طولاني رو بايد چکار کنم؟
اين برنامه ايي هست که با دو کليد يک پين فعال و غير فعال ميشه.
if(HAL_GPIO_ReadPin(KEY_UP_GPIO_Port, KEY_UP_Pin) == 0) //up
HAL_GPIO_WritePin(LED_Bliking_GPIO_Port, LED_Bliking_Pin, GPIO_PIN_SET);
if(HAL_GPIO_ReadPin(KEY_DOWN_GPIO_Port, KEY_DOWN_Pin) == 0 ) // down
HAL_GPIO_WritePin(LED_Bliking_GPIO_Port, LED_Bliking_Pin, GPIO_PIN_RESET);
حالا بجاي اين ميخوام اينجوري بشه
if(KEY_UP_Pin== 0) //up
LED_Bliking=1;
if(KEY_DOWN_Pin== 0 ) // down
LED_Bliking=0;
ميتوني کمکم کنيد ؟
سلام.ممنون بابت تدریس
من کد رو ریختم روی میکرو ولی وقتی مدارو میبندم کار نمیکنه.مشکل از کجا میتونه باشه؟هیچ خطایی هم دریافت نکردم.
سلام جناب، یک کد ساده مثل ال ای دی چشمک زن رو استفاده کنید ببینید عمل میکنه یا خیر.
سلام جناب من وقتی با cube mx در بخش code generation وارد میشم یه پیعامی میده که میگه برنامه شما کامل نیست
سلام جناب، ارور کامل رو بفرمایید.
سلام
روز بخیر
برای اینکه بعدا بخوام پروژم رو تو دانشگاه بدون لپ تاپ اجرا کنم،فقط به تغذیه برد احتیاج دارم دیگه؟
و اینکه این 3.3 ولت رو با چی تامین کنم و چند آمپر هست؟
ممنونم
سلام حناب. بله فقط به تغذیه نیاز داره. در مورد آمپر که بستگی به پروژتون داره و در کل زیاد فکرتون رو درگیرش نکنید مگر اینکه قطعه پر مصرفی دارید مثل موتور ها و … در مورد ولتاژ هم بستگی به خودتون داره دیگه میتونید از آی سی های رگولاتور استفاده کنید.