Conectarea și programarea unei plăci ARM STM32F103C6
Acest proiect își propune să utilizeze microcontrolerul STM32F103C6 pentru a realiza două funcționalități de bază: aprinderea unui LED și trimiterea unui counter pe interfața de comunicație SPI. Vom folosi
placa de dezvoltare STM32F103C6 (cunoscuta și ca “Blue Pill”) și ST-Link v2 ca și programator și debugger pentru a implementa acest proiect.
STM32F103C6 este un microcontroller din seria STM32, produs de compania STMicroelectronics. Acesta face parte din familia STM32F1, care utilizează nucleul Cortex-M3 al companiei ARM. Microcontrollerul este folosit într-o varietate de aplicații, inclusiv în sisteme înglobate,automatizare industrială, dispozitive medicale și multe altele.
STM32F103C6 are un nucleu de procesor care rulează la 72 MHz, 32 KB de memorie flash pentru stocarea programelor și 10 KB de memorie RAM pentru date temporare.
Iată câteva caracteristici cheie ale STM32F103C6:
- Nucleu ARM Cortex-M3 pe 32 de biți la 72 MHz
- 32 KB memorie Flash
- 10 KB memorie RAM
- Două convertoare analog-digital pe 12 biți cu 10 canale
- Interfețe de comunicație precum SPI, I2C, USB și CAN
- Timere pentru generarea de semnale puls (PWM) și alte funcții de sincronizare
STM32F103C6 este un microcontroler popular utilizat într-o varietate de aplicații, inclusiv:
- Achiziție de date
- Controlul motorului
- Dispozitive industriale
- Prototipare electronică
Programare și debug
Pentru a programa un microcontroller STM32F103C6, există mai multe opțiuni și instrumente disponibile. Una dintre cele mai populare metode este să folosești un mediu de dezvoltare integrat (IDE) cum ar fi STM32CubeIDE . Iată o scurtă prezentare a procesului de programare folosind STM32CubeIDE:
- Instalare software: Descarcă și instalează STM32CubeIDE (bazat pe eclipse) de pe site-ul oficial al STMicroelectronics. Acest IDE este specializat în dezvoltarea de aplicații pentru microcontrolerele STM32.
- Creare unui proiect nou: Lansează STM32CubeIDE și creează un nou proiect pentru STM32F103C6. Alege modelul corect de microcontroller și configurațiile relevante pentru aplicația ta.
- Configurare pin: Utilizează configuratorul de pini integrat pentru a asigna funcțiile dorite la pinii microcontrollerului, cum ar fi UART, SPI, I2C, etc.
- Configurare periferice: Configurează perifericele necesare pentru aplicația ta, cum ar fi interfețe UART, SPI, I2C, timeri, etc., folosind instrumentele de configurare disponibile în STM32CubeIDE.
- Scrierea codului: Folosește editorul de cod pentru a scrie codul sursă în limbajul de programare C sau C++, care va controla comportamentul microcontrollerului.
- Compilare: Compilează codul sursă pentru a genera fișierele binare necesare pentru programarea microcontrollerului.
- Programare și depanare: Utilizează un programator de depanare, cum ar fi un programator ST-Link sau JTAG, pentru a încărca codul binar pe microcontroller și pentru a depana aplicația în timpul rulării.
- Testare și depanare: Rulează și testează aplicația pe microcontroller și depanează orice probleme care ar putea apărea.
Este important să consulți documentația oficială a STM32F103C6 și resursele de dezvoltare oferite de STMicroelectronics pentru a obține detalii precise și informații actualizate despre programarea acestui microcontroller.
Conectarea la ST-Link v2
STM32 – ST-Link v2
GND – GND
SCK – SWCLK
DIO – SWDIO
3V3 – 3V3
Configurarea proiectului
- Configurația LED-ului:
- Configurează pinul PC13 ca output în modulul GPIO și setează-l la HIGH pentru a aprinde LED-ul.
-
- Initializarea GPIO-ului se realizează în funcția generată automat
MX_GPIO_Init();
- Initializarea GPIO-ului se realizează în funcția generată automat
- Configurația SPI:
- Configurăm interfața SPI pentru a comunica cu un alt dispozitiv. Pinurile utilizate pentru SPI sunt PA5 (SCK), PA6 (MISO), PA7 (MOSI), și un pin pentru CS.
-
- Setăm parametrii SPI: frecvența ceasului, modul (de exemplu, SPI Mode 0), și direcția de comunicare (full-duplex).
- Initializarea SPI-ului se realizează în funcția generată automat
MX_SPI1_Init();
- Incrementarea și Trimiterea Counter-ului:
- Creăm o variabilă de tip integer care va servi drept counter.
- În bucla principală a programului, incrementăm counter-ul la fiecare iterație.
- Trimiterea valorii counter-ului prin SPI se poate realiza folosind funcții de transmitere de date, asigurându-ne că selectăm corect dispozitivul SPI înainte de trimiterea datelor (prin CS LOW) și apoi ridicăm CS la finalul transmisiei.
- Bucla Principală:
- În bucla principală, aprindem LED-ul pentru o perioadă scurtă de timp, incrementăm counter-ul, și trimitem valoarea counter-ului prin SPI.
- Se poate folosi o funcție de delay pentru a crea un interval între incrementări, oferind timp pentru alte operații sau pentru vizualizarea schimbărilor LED-ului.
Componente
- Placa Electronica de Dezvoltare STM32F103C8T6 ARM STM 32
- ST-LINK V2 Simulator Download Programmer STM32F103C8T6 ARM STM32 Minimum System Development Board STM32F401 STM32F411
- GY 521 MPU-6050 3 Axis Analog Gyroscope Sensors Module MPU6050 3 Axis Accelerometer Board for Arduino DIY
Schema electronică/sistem
Cod de test
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
* Copyright (c) 2024 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "adc.h"
#include "dma.h"
#include "spi.h"
#include "usart.h"
#include "gpio.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 */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
int counter =0;
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(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_SPI1_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_13);
HAL_Delay(1000);
counter++;
// Transmite counter-ul pe SPI (16-bit)
uint16_t dataToSend = counter;
// Chip select pe LOW pentru începutul transmisiei
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
// Transmitere pe SPI
HAL_SPI_Transmit(&hspi1, (uint8_t *)&dataToSend, 1, HAL_MAX_DELAY);
// Chip select pe HIGH pentru finalul transmisiei
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
// Așteaptă înainte de următoarea iterație
HAL_Delay(500); // Interval între incrementări și transmisii
}
/* USER CODE END 3 */
}
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
}
/* 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 */
__disable_irq();
while (1)
{
}
/* 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,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
Documentație proiect
- https://www.st.com/resource/it/datasheet/stm32f103c6.pdf
- https://www.bepat.de/2020/11/27/stm32f103c8-adc-dual-regular-simultaneous-mode/
- https://mischianti.org/stm32f103c6t6-high-resolution-pinout-and-specs/
- https://www.st.com/resource/it/datasheet/stm32f103c6.pdf
- https://mischianti.org/stm32f1-pinout-specs-and-arduino-ide-configuration-stm32duino-and-stmicroelectronics-1/
- https://electrosome.com/led-blink-stm32-arm-cortex-m-microcontroller-keil-ide/
- https://nicuflorica.blogspot.com/search?q=STM32
Mulțumesc pentru atenție!
Pentru întrebări și/sau consultanță tehnică vă stau la dispoziție pe blog mai jos în secțiunea de comentarii sau pe email simedruflorin@automatic-house.ro.
O zi plăcută tuturor !
[…] proiect realizează interfațarea între două microcontrolere,STM32F103C6 și ESP32, pentru a transfera date utilizând Protocolul de Interfață Serială (SPI). Datele sunt […]