Lập trình STM32F103C8 bằng Keil uVision & STM32CubeMX

Lập trình STM32F103C8 bằng Keil uVision & STM32CubeMX

Bộ vi điều khiển STM32 sử dụng kiến trúc ARM Cortex M đang dần trở nên phổ biến và được sử dụng trong nhiều ứng dụng vì tính năng, chi phí và hiệu suất của nó. Chúng tôi đã lập trình STM32F103C8 bằng Arduino IDE trong các hướng dẫn trước đây của chúng tôi. Lập trình STM32 với Arduino IDE rất đơn giản, vì có rất nhiều thư viện có sẵn cho các cảm biến khác nhau để thực hiện bất kỳ tác vụ nào, chúng ta chỉ cần thêm các thư viện đó vào chương trình. Đây là một thủ tục dễ dàng và bạn có thể không cần tìm hiểu sâu về bộ xử lý ARM. Bây giờ chúng ta đang bước vào cấp độ lập trình tiếp theo gọi là lập trình ARM. Bằng cách này, chúng tôi có thể không chỉ cải thiện cấu trúc code mà còn có thể tiết kiệm dung lượng bộ nhớ bằng cách không sử dụng các thư viện không cần thiết.

STMicroelectronics đã giới thiệu một công cụ có tên STM32Cube MX , tạo code cơ bản theo các thiết bị ngoại vi và board STM32 được chọn. Vì vậy, chúng ta không cần phải lo lắng về việc code hóa cho các trình điều khiển và thiết bị ngoại vi cơ bản. Hơn nữa code được tạo này có thể được sử dụng trong Keil uVision để chỉnh sửa theo yêu cầu. Và cuối cùng, code được ghi vào STM32 bằng lập trình ST-Link từ STMicroelectronics.

Trong hướng dẫn này, chúng ta sẽ tìm hiểu cách lập trình STM32F103C8 bằng Keil uVision & STM32CubeMX bằng cách thực hiện một dự án đơn giản là giao tiếp với một nút ấn và LED với board STM32F103C8 Blue Pill . Chúng tôi sẽ tạo code bằng STM32Cube MX sau đó chỉnh sửa và tải code lên STM32F103C8 bằng Keil uVision. Trước khi đi vào chi tiết, trước tiên chúng ta sẽ tìm hiểu về lập trình viên ST-LINK và công cụ phần mềm STM32CubeMX.

ST-LINK V2

ST-LINK / V2 là một trình gỡ lỗi trong mạch và lập trình cho các họ vi điều khiển STM8 và STM32. Chúng tôi có thể tải code lên STM32F103C8 và các bộ vi điều khiển STM8 & STM32 khác bằng ST-LINK này. Các giao diện mô-đun dây đơn (SWIM) và JTAG / gỡ lỗi dây nối tiếp (SWD) được sử dụng để giao tiếp với bất kỳ vi điều khiển STM8 hoặc STM32 nào trên board ứng dụng. Vì các ứng dụng STM32 sử dụng giao diện USB có tốc độ đầy đủ để giao tiếp với các môi trường phát triển tích hợp Atollic, IAR, Keil hoặc TASKING, vì vậy chúng tôi có thể sử dụng phần cứng này để lập trình bộ vi điều khiển STM 8 & STM32.

Trên đây là hình ảnh của ST-LINK V2 dongle từ STMicroelectronics hỗ trợ đầy đủ giao diện gỡ lỗi STM32 SWD, giao diện 4 dây đơn giản (bao gồm cả nguồn), nhanh và ổn định. Nó có nhiều màu sắc. Thân máy được làm từ hợp kim nhôm. Nó có LED màu xanh lam vì nó được sử dụng để quan sát trạng thái hoạt động của ST-LINK. Tên chân được đánh dấu rõ ràng trên vỏ như chúng ta có thể thấy trong hình trên. Nó có thể được giao tiếp với phần mềm Keil nơi chương trình có thể được flash vào bộ vi điều khiển STM32. Vì vậy, hãy theo dõi hướng dẫn này để biết cách lập trình ST-LINK này để lập trình vi điều khiển STM32 . Hình ảnh bên dưới hiển thị các chân của mô-đun ST-LINK V2.

Lưu ý: Khi kết nối ST-Link với máy tính lần đầu tiên. Cần cài đặt trình điều khiển thiết bị. Trình điều khiển thiết bị có thể được tìm thấy trong liên kết này theo hệ điều hành của bạn.

STM32CubeMX

Công cụ STM32CubeMX là một phần của STMicroelectronics STMCube. Công cụ phần mềm này giúp cho việc phát triển dễ dàng bằng cách giảm giai đoạn phát triển, thời gian và chi phí. STM32Cube bao gồm STM32CubeMX là một công cụ cấu hình phần mềm đồ họa cho phép tạo code C bằng cách sử dụng trình hướng dẫn đồ họa. Code đó có thể được sử dụng trong các môi trường phát triển khác nhau như keil uVision, GCC, IAR, v.v. Bạn có thể tải xuống công cụ này từ liên kết sau .

STM32CubeMX có các tính năng sau

  • Chân gỡ lỗi
  • Trợ giúp thiết lập xung
  • Một nguồn
  • Một tiện ích thực hiện cấu hình ngoại vi MCU như chân GPIO, USART, v.v.
  • Một tiện ích thực hiện cấu hình ngoại vi MCU cho các ngăn xếp phần mềm trung gian như USB, TCP / IP, v.v.

Những phần cần thiết

  1. Phần cứng
  • Board STM32F103C8 màu xanh
  • ST-LINK V2
  • Nút nhấn
  • LED
  • Breadboard
  • Dây dẫn
  1. Phần mềm
  • Công cụ tạo code STM32CubeMX ( Liên kết)
  • Keil uVision 5 ( liên kết )
  • Trình điều khiển cho ST-Link V2 ( liên kết )

 Sơ đồ mạch và kết nối

Dưới đây là sơ đồ mạch để kết nối một ED với boardSTM32 chỉ bằng một nút nhấn.

Kết nối giữa ST-LINK V2 & STM32F103C8

Ở đây, board STM32 Blue Pill được cấp nguồn từ ST-LINK được nối với cổng USB của máy tính. Vì vậy, chúng ta không cần phải cấp nguồn cho STM32 riêng biệt. Board dưới đây cho thấy kết nối giữa board ST-Link và board Blue Pill.

STM32F103C8

ST-Link V2

GND

GND

SWCLK

SWCLK

SWDIO

SWDIO

3V3

3,3V

LED & Nút ấn

LED được sử dụng để biểu thị đầu ra từ board Blue Pill khi nhấn nút ấn. Cực dương của LED được nối với chân PC13 của board Blue Pill và cực âm được nối đất.

Một nút ấn được kết nối để cung cấp đầu vào cho chân PA1 của board Blue Pill. Chúng ta cũng phải sử dụng điện trở có giá trị 10k vì chân có thể nổi mà không có bất kỳ đầu vào nào khi nút được nhả ra. Một đầu của nút ấn được nối với đất và đầu kia nối đến chân PA1 và đầu còn lại của điện trở 10k cũng được nối với nguồn 3,3V của board Blue Pill.

Tạo và ghi chương trình vào STM32 bằng Keil uVision và ST-Link

Bước 1: – Trước tiên hãy cài đặt tất cả các trình điều khiển thiết bị cho ST-LINK V2, công cụ phần mềm STM32Cube MX & Keil uVision và cài đặt các gói cần thiết cho STM32F103C8.

 

Bước 2: – Bước thứ hai là Open >> STM32Cube MX

 

Bước 3: – Sau đó bấm vào New Project

Bước 4: – search & select nhập STM32F103C8

Bước 5: – Bây giờ bản phác thảo chân ra của STM32F103C8 xuất hiện, ở đây chúng ta có thể đặt cấu hình chân. Chúng ta cũng có thể chọn chân trong phần thiết bị ngoại vi theo dự án của chúng ta.

Bước 6: – Bạn cũng có thể nhấp trực tiếp vào code chân và một danh sách xuất hiện, bây giờ chọn cấu hình chân yêu cầu.

Bước 7: – Đối với dự án của chúng tôi, chúng tôi đã chọn PA1 là GPIO INPUT, PC13 làm GPIO OUTPUT & SYS gỡ lỗi là SERIAL WIRE, ở đây chỉ có chúng tôi kết nối các chân ST-LINK SWCLK & SWDIO. Các chân được chọn và cấu hình xuất hiện trong khung màu XANH LỤC . Bạn có thể tham khảo hình dưới đây.

Bước 8: – Tiếp theo trong tab Configuration, chọn GPIO để đặt cấu hình chân GPIO cho các chân chúng tôi đã chọn.

Bước 9: – Tiếp theo trong hộp cấu hình chân này, chúng tôi có thể configure User Label  cho các chân chúng tôi đang sử dụng, đó là tên chân do người dùng xác định.

Bước 10: – Sau đó bấm vào Project >> Generate Code.

Bước 11: – Bây giờ hộp thoại cài đặt dự án xuất hiện. Trong hộp này, chọn tên và vị trí dự án của bạn và chọn môi trường phát triển. Chúng tôi đang sử dụng Keil, vì vậy hãy chọn MDK-ARMv5 làm IDE.

Bước 12: – Tiếp theo trong tab  Code Generator , chọn Copy only the necessary library files , sau đó bấm OK.

Bước 13: – Bây giờ hộp thoại tạo code xuất hiện. Chọn Open Project  để mở code dự án tự động được tạo trong Keil uvsion.

 

Bước 14: – Công cụ Keil uVision mở ra với code được tạo của chúng tôi trong STM32CubeMx với cùng tên dự án với thư viện cần thiết và code được định cấu hình cho các chân mà chúng tôi đã chọn.

Bước 15: – Bây giờ chúng ta chỉ cần thêm logic để thực hiện một số hành động tại đầu ra của LED (chân PC13) khi nhấn và nhả nút ở đầu vào GPIO (chân PA1). Vì vậy, chọn chương trình main.c để thêm code .

Bước 16: – Bây giờ thêm code trong vòng lặp while (1) , xem hình ảnh bên dưới nơi tôi đánh dấu phần đó để chạy code.

while (1) 
{ 
  if (HAL_GPIO_ReadPin (BUTN_GPIO_Port, BUTN_Pin) == 0) // => phát hiện nút được nhấn 
{           
    HAL_GPIO_WritePin (LEDOUT_GPIO_Port, LEDOUT_Pin, 1); // Để làm cao đầu ra khi nút pressesd 
} 

khác 
{ 
    HAL_GPIO_WritePin (LEDOUT_GPIO_Port, LEDOUT_Pin, 0); // Để tạo đầu ra Thấp khi nhấn nút 
} 
}

Bước 17: – Sau khi chỉnh sửa xong code, nhấp vào biểu tượng Options for Target  trong tab debug, chọn ST-LINK Debugger

Ngoài ra, nhấp vào nút Settings và sau đó trong tab  Flash Download, đánh dấu vào hộp chọn Reset and Run và nhấp vào ‘ok’.

Bước 18: – Bây giờ bấm vào biểu tượng Rebuild để xây dựng lại tất cả các tệp mục tiêu.

Bước 19: – Bây giờ bạn có thể cắm ST-LINK vào máy tính với các kết nối mạch đã sẵn sàng và nhấp vào biểu tượng DOWNLOAD hoặc nhấn F8 để flash STM32F103C8 với code bạn đã tạo và chỉnh sửa.

Bước 20: – Bạn có thể thấy dấu hiệu nhấp nháy ở dưới cùng của cửa sổ keil uVision.

 

Đầu ra của Board STM32 được lập trình của Keil

Bây giờ khi chúng ta nhấn nút ấn, LED bật và khi chúng ta nhả nó ra, LED sẽ tắt.

Chương trình

Phần chính mà chúng tôi đã thêm vào trong chương trình được tạo được hiển thị bên dưới. Code dưới đây cần được đưa vào while (1 ) của chương trình main.c được tạo bởi STM32CubeMX. Bạn có thể quay lại Bước 15 đến Bước 17 để tìm hiểu cách thêm nó vào chương trình main.c.

while (1) 
{ 
  if (HAL_GPIO_ReadPin (BUTN_GPIO_Port, BUTN_Pin) == 0) // => phát hiện nút được nhấn 
{           
    HAL_GPIO_WritePin (LEDOUT_GPIO_Port, LEDOUT_Pin, 1); // Để làm cao đầu ra khi nút pressesd 
} 

khác 
{ 
    HAL_GPIO_WritePin (LEDOUT_GPIO_Port, LEDOUT_Pin, 0); // Để tạo đầu ra Thấp khi nhấn nút 
} 
}

Toàn bộ quá trình tạo và tải lên dự án vào board STM32 cũng được giải thích trong Video được đưa ra ở cuối . Ngoài ra code hoàn chỉnh của tệp main.c được đưa ra dưới đây bao gồm cả code đã cho ở trên.

CODE:

  */

/* 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 */




/**

  * @}

  */




/**

  * @}

  */

VIDEO:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *