### SPI Initialization and Transfer Example Source: https://context7.com/stmicroelectronics/stm32f1xx-hal-driver/llms.txt Demonstrates how to initialize the SPI peripheral in master mode and perform a blocking full-duplex transmit-receive operation. It also shows the setup for interrupt-driven transmit and DMA receive. ```APIDOC ## SPI Initialization and Transfer ### Description This example shows how to configure and use the SPI HAL driver for various transfer modes. ### Functions - `HAL_SPI_Init`: Initializes the SPI peripheral. - `HAL_SPI_TransmitReceive`: Performs a blocking full-duplex transmit and receive. - `HAL_SPI_Transmit_IT`: Initiates an interrupt-driven transmit. - `HAL_SPI_Receive_DMA`: Initiates a DMA-driven receive. - `HAL_SPI_GetError`: Retrieves the SPI error code. ### Example Usage ```c #include "stm32f1xx_hal.h" SPI_HandleTypeDef hspi1; uint8_t txBuf[4] = {0xAA, 0xBB, 0xCC, 0xDD}; uint8_t rxBuf[4]; void SPI_Example(void) { /* Configure SPI1 as Master, full-duplex, 8-bit, CPOL=Low, CPHA=1Edge */ hspi1.Instance = SPI1; hspi1.Init.Mode = SPI_MODE_MASTER; hspi1.Init.Direction = SPI_DIRECTION_2LINES; hspi1.Init.DataSize = SPI_DATASIZE_8BIT; hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; hspi1.Init.NSS = SPI_NSS_SOFT; hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16; /* 72/16 = 4.5 MHz */ hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; hspi1.Init.TIMode = SPI_TIMODE_DISABLE; hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; hspi1.Init.CRCPolynomial = 10; if (HAL_SPI_Init(&hspi1) != HAL_OK) { Error_Handler(); } /* Assert CS manually (NSS_SOFT) */ HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); /* --- Blocking full-duplex transfer --- */ HAL_StatusTypeDef st = HAL_SPI_TransmitReceive(&hspi1, txBuf, rxBuf, 4, 50); /* rxBuf now contains response bytes */ /* De-assert CS */ HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); if (st != HAL_OK) { uint32_t err = HAL_SPI_GetError(&hspi1); /* err may be HAL_SPI_ERROR_OVR, HAL_SPI_ERROR_MODF, etc. */ } /* --- Interrupt-driven transmit-only --- */ HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); HAL_SPI_Transmit_IT(&hspi1, txBuf, 4); /* HAL_SPI_TxCpltCallback() fires on completion */ /* --- DMA receive --- */ HAL_SPI_Receive_DMA(&hspi1, rxBuf, 4); /* HAL_SPI_RxCpltCallback() fires when DMA transfer finishes */ } void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi) { if (hspi->Instance == SPI1) { __HAL_RCC_SPI1_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); GPIO_InitTypeDef gpio = {0}; /* SCK PA5, MISO PA6, MOSI PA7 */ gpio.Pin = GPIO_PIN_5 | GPIO_PIN_7; gpio.Mode = GPIO_MODE_AF_PP; gpio.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOA, &gpio); gpio.Pin = GPIO_PIN_6; gpio.Mode = GPIO_MODE_INPUT; gpio.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA, &gpio); HAL_NVIC_SetPriority(SPI1_IRQn, 1, 0); HAL_NVIC_EnableIRQ(SPI1_IRQn); } } void SPI1_IRQHandler(void) { HAL_SPI_IRQHandler(&hspi1); } void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *h) { HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); } void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *h) { /* process rxBuf */ } void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *h) { /* handle error */ } ``` ``` -------------------------------- ### UART Initialization and Basic Communication Example Source: https://context7.com/stmicroelectronics/stm32f1xx-hal-driver/llms.txt Demonstrates how to initialize the UART peripheral, perform blocking transmit and receive operations, and use interrupt-driven transmission. ```APIDOC ## UART Initialization and Basic Communication Example ### Description This example shows the basic usage of the UART HAL driver, including initialization, blocking transmit, blocking receive, and interrupt-driven transmit. ### Functions - `HAL_UART_Init`: Initializes the UART peripheral. - `HAL_UART_Transmit`: Transmits data in blocking mode. - `HAL_UART_Receive`: Receives data in blocking mode. - `HAL_UART_Transmit_IT`: Transmits data using interrupts. ### Code Example ```c #include "stm32f1xx_hal.h" #include UART_HandleTypeDef huart1; uint8_t rxBuf[64]; void UART_Example(void) { /* Initialize USART1 at 115200 8N1 */ huart1.Instance = USART1; huart1.Init.BaudRate = 115200; huart1.Init.WordLength = UART_WORDLENGTH_8B; huart1.Init.StopBits = UART_STOPBITS_1; huart1.Init.Parity = UART_PARITY_NONE; huart1.Init.Mode = UART_MODE_TX_RX; huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart1.Init.OverSampling = UART_OVERSAMPLING_16; if (HAL_UART_Init(&huart1) != HAL_OK) { Error_Handler(); } /* --- Blocking transmit (max 100 ms timeout) --- */ const char *msg = "Hello STM32!\r\n"; HAL_StatusTypeDef status = HAL_UART_Transmit(&huart1, (const uint8_t *)msg, strlen(msg), 100); /* status == HAL_OK on success */ /* --- Blocking receive of 10 bytes --- */ uint8_t rxData[10]; status = HAL_UART_Receive(&huart1, rxData, 10, 500); if (status == HAL_TIMEOUT) { /* fewer than 10 bytes received within 500 ms */ } /* --- Interrupt-driven transmit --- */ const uint8_t itMsg[] = "IT mode\r\n"; HAL_UART_Transmit_IT(&huart1, itMsg, sizeof(itMsg) - 1); /* HAL_UART_TxCpltCallback() fires when complete */ } /* MspInit: configure GPIO and NVIC – called by HAL_UART_Init */ void HAL_UART_MspInit(UART_HandleTypeDef *huart) { if (huart->Instance == USART1) { __HAL_RCC_USART1_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); GPIO_InitTypeDef gpio = {0}; gpio.Pin = GPIO_PIN_9; /* TX */ gpio.Mode = GPIO_MODE_AF_PP; gpio.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOA, &gpio); gpio.Pin = GPIO_PIN_10; /* RX */ gpio.Mode = GPIO_MODE_INPUT; gpio.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA, &gpio); HAL_NVIC_SetPriority(USART1_IRQn, 1, 0); HAL_NVIC_EnableIRQ(USART1_IRQn); } } void USART1_IRQHandler(void) { HAL_UART_IRQHandler(&huart1); } /* Callbacks (override weak defaults) */ void HAL_UART_TxCpltCallback(UART_HandleTypeDef *h) { /* TX done */ } void HAL_UART_RxCpltCallback(UART_HandleTypeDef *h) { /* RX buffer full */ } void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *h, uint16_t Size) { /* Size bytes received (idle line detected or buffer full) */ /* Process rxBuf[0..Size-1], then re-arm: */ HAL_UARTEx_ReceiveToIdle_IT(h, rxBuf, sizeof(rxBuf)); } void HAL_UART_ErrorCallback(UART_HandleTypeDef *h) { uint32_t err = HAL_UART_GetError(h); /* HAL_UART_ERROR_ORE, etc. */ } ``` ``` -------------------------------- ### TIM PWM Generation Initialization and Usage Source: https://context7.com/stmicroelectronics/stm32f1xx-hal-driver/llms.txt Initializes and starts a TIM channel for PWM generation. This example configures a 1 kHz PWM signal with a 50% duty cycle and shows how to update the duty cycle at runtime. ```APIDOC ## HAL_TIM_PWM_Init ### Description Initializes the TIM PWM unit according to the specified parameters in the TIM_Base_InitTypeDef structure. ### Method `HAL_TIM_PWM_Init(TIM_HandleTypeDef *htim)` ### Parameters - **htim** (TIM_HandleTypeDef*) - Pointer to a TIM_HandleTypeDef structure that contains the configuration information for the TIM module. ``` ```APIDOC ## HAL_TIM_PWM_ConfigChannel ### Description Configure the TIMx in PWM mode. ### Method `HAL_TIM_PWM_ConfigChannel(TIM_HandleTypeDef *htim, TIM_OC_InitTypeDef *sConfig, uint32_t Channel)` ### Parameters - **htim** (TIM_HandleTypeDef*) - Pointer to a TIM_HandleTypeDef structure that contains the configuration information for the TIM module. - **sConfig** (TIM_OC_InitTypeDef*) - Pointer to a TIM_OC_InitTypeDef structure that contains the configuration information for the specified TIM Channel. - **Channel** (uint32_t) - Specifies the TIM Channel to be configured. This parameter can be one of the following values: TIM_CHANNEL_1, TIM_CHANNEL_2, TIM_CHANNEL_3, TIM_CHANNEL_4. ``` ```APIDOC ## HAL_TIM_PWM_Start ### Description Starts the TIM PWM signal generation in the specified channel. ### Method `HAL_TIM_PWM_Start(TIM_HandleTypeDef *htim, uint32_t Channel)` ### Parameters - **htim** (TIM_HandleTypeDef*) - Pointer to a TIM_HandleTypeDef structure that contains the configuration information for the TIM module. - **Channel** (uint32_t) - Specifies the TIM Channel to be configured. This parameter can be one of the following values: TIM_CHANNEL_1, TIM_CHANNEL_2, TIM_CHANNEL_3, TIM_CHANNEL_4. ``` ```APIDOC ## __HAL_TIM_SET_COMPARE ### Description Sets the TIMx capture compare register value. ### Method `__HAL_TIM_SET_COMPARE(htim, Channel, Compare)` ### Parameters - **htim** (TIM_HandleTypeDef*) - Pointer to a TIM_HandleTypeDef structure that contains the configuration information for the TIM module. - **Channel** (uint32_t) - Specifies the TIM Channel. This parameter can be one of the following values: TIM_CHANNEL_1, TIM_CHANNEL_2, TIM_CHANNEL_3, TIM_CHANNEL_4. - **Compare** (uint32_t) - The value to be written to the capture/compare register. ``` ```APIDOC ## __HAL_TIM_GET_COUNTER ### Description Gets the TIMx counter value. ### Method `__HAL_TIM_GET_COUNTER(htim)` ### Parameters - **htim** (TIM_HandleTypeDef*) - Pointer to a TIM_HandleTypeDef structure that contains the configuration information for the TIM module. ``` -------------------------------- ### TIM Input Capture Initialization and Usage Source: https://context7.com/stmicroelectronics/stm32f1xx-hal-driver/llms.txt Configures and starts a TIM channel for input capture to measure pulse width. This example shows how to set up the capture channel and retrieve the captured value. ```APIDOC ## HAL_TIM_IC_ConfigChannel ### Description Configures the TIMx channel to be used in Input Capture mode. ### Method `HAL_TIM_IC_ConfigChannel(TIM_HandleTypeDef *htim, TIM_IC_InitTypeDef *sICConfig, uint32_t Channel)` ### Parameters - **htim** (TIM_HandleTypeDef*) - Pointer to a TIM_HandleTypeDef structure that contains the configuration information for the TIM module. - **sICConfig** (TIM_IC_InitTypeDef*) - Pointer to a TIM_IC_InitTypeDef structure that contains configuration information for the TIM Input Capture. - **Channel** (uint32_t) - Specifies the TIM Channel to be configured. This parameter can be one of the following values: TIM_CHANNEL_1, TIM_CHANNEL_2, TIM_CHANNEL_3, TIM_CHANNEL_4. ``` ```APIDOC ## HAL_TIM_IC_Start_IT ### Description Starts the TIM Input Capture in interrupt mode. ### Method `HAL_TIM_IC_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel)` ### Parameters - **htim** (TIM_HandleTypeDef*) - Pointer to a TIM_HandleTypeDef structure that contains the configuration information for the TIM module. - **Channel** (uint32_t) - Specifies the TIM Channel to be configured. This parameter can be one of the following values: TIM_CHANNEL_1, TIM_CHANNEL_2, TIM_CHANNEL_3, TIM_CHANNEL_4. ``` ```APIDOC ## HAL_TIM_IC_CaptureCallback ### Description Input Capture callback. This function is called when a capture event occurs. ### Method `HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)` ### Parameters - **htim** (TIM_HandleTypeDef*) - Pointer to a TIM_HandleTypeDef structure that contains the configuration information for the TIM module. ``` ```APIDOC ## HAL_TIM_ReadCapturedValue ### Description Reads the TIMx captured value. ### Method `HAL_TIM_ReadCapturedValue(TIM_HandleTypeDef *htim, uint32_t Channel)` ### Parameters - **htim** (TIM_HandleTypeDef*) - Pointer to a TIM_HandleTypeDef structure that contains the configuration information for the TIM module. - **Channel** (uint32_t) - Specifies the TIM Channel. This parameter can be one of the following values: TIM_CHANNEL_1, TIM_CHANNEL_2, TIM_CHANNEL_3, TIM_CHANNEL_4. ### Returns The captured value. ``` -------------------------------- ### SPI Initialization and Transfer Example Source: https://context7.com/stmicroelectronics/stm32f1xx-hal-driver/llms.txt Configures SPI1 as a master and demonstrates blocking transmit-receive, interrupt-driven transmit, and DMA receive operations. Ensure CS is managed manually when using software NSS. ```c #include "stm32f1xx_hal.h" SPI_HandleTypeDef hspi1; uint8_t txBuf[4] = {0xAA, 0xBB, 0xCC, 0xDD}; uint8_t rxBuf[4]; void SPI_Example(void) { /* Configure SPI1 as Master, full-duplex, 8-bit, CPOL=Low, CPHA=1Edge */ hspi1.Instance = SPI1; hspi1.Init.Mode = SPI_MODE_MASTER; hspi1.Init.Direction = SPI_DIRECTION_2LINES; hspi1.Init.DataSize = SPI_DATASIZE_8BIT; hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; hspi1.Init.NSS = SPI_NSS_SOFT; hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16; /* 72/16 = 4.5 MHz */ hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; hspi1.Init.TIMode = SPI_TIMODE_DISABLE; hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; hspi1.Init.CRCPolynomial = 10; if (HAL_SPI_Init(&hspi1) != HAL_OK) { Error_Handler(); } /* Assert CS manually (NSS_SOFT) */ HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); /* --- Blocking full-duplex transfer --- */ HAL_StatusTypeDef st = HAL_SPI_TransmitReceive(&hspi1, txBuf, rxBuf, 4, 50); /* rxBuf now contains response bytes */ /* De-assert CS */ HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); if (st != HAL_OK) { uint32_t err = HAL_SPI_GetError(&hspi1); /* err may be HAL_SPI_ERROR_OVR, HAL_SPI_ERROR_MODF, etc. */ } /* --- Interrupt-driven transmit-only --- */ HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); HAL_SPI_Transmit_IT(&hspi1, txBuf, 4); /* HAL_SPI_TxCpltCallback() fires on completion */ /* --- DMA receive --- */ HAL_SPI_Receive_DMA(&hspi1, rxBuf, 4); /* HAL_SPI_RxCpltCallback() fires when DMA transfer finishes */ } ``` -------------------------------- ### Direct Memory-to-Memory DMA Copy Source: https://context7.com/stmicroelectronics/stm32f1xx-hal-driver/llms.txt Performs a memory-to-memory DMA transfer using DMA1 Channel 1. This example initializes the DMA, starts the transfer, polls for completion, and then deinitializes the DMA. ```c /* Direct memory-to-memory DMA copy */ void DMA_MemCopy_Example(void) { DMA_HandleTypeDef hdma_m2m; __HAL_RCC_DMA1_CLK_ENABLE(); hdma_m2m.Instance = DMA1_Channel1; hdma_m2m.Init.Direction = DMA_MEMORY_TO_MEMORY; hdma_m2m.Init.PeriphInc = DMA_PINC_ENABLE; hdma_m2m.Init.MemInc = DMA_MINC_ENABLE; hdma_m2m.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD; hdma_m2m.Init.MemDataAlignment = DMA_MDATAALIGN_WORD; hdma_m2m.Init.Mode = DMA_NORMAL; hdma_m2m.Init.Priority = DMA_PRIORITY_HIGH; HAL_DMA_Init(&hdma_m2m); uint32_t src[64], dst[64]; /* Start transfer, poll for completion */ HAL_DMA_Start(&hdma_m2m, (uint32_t)src, (uint32_t)dst, 64); HAL_DMA_PollForTransfer(&hdma_m2m, HAL_DMA_FULL_TRANSFER, 100); /* dst now contains a copy of src */ HAL_DMA_DeInit(&hdma_m2m); } ``` -------------------------------- ### TIM Base Timer Initialization and Usage Source: https://context7.com/stmicroelectronics/stm32f1xx-hal-driver/llms.txt Initializes and starts a TIM base timer to generate a 1 Hz interrupt. This example demonstrates setting up the prescaler and period for a specific frequency and handling the interrupt. ```APIDOC ## HAL_TIM_Base_Init ### Description Initializes the TIM Base unit according to the specified parameters in the TIM_Base_InitTypeDef structure. ### Method `HAL_TIM_Base_Init(TIM_HandleTypeDef *htim)` ### Parameters - **htim** (TIM_HandleTypeDef*) - Pointer to a TIM_HandleTypeDef structure that contains the configuration information for the TIM module. ``` ```APIDOC ## HAL_TIM_Base_Start_IT ### Description Starts the TIM Timer Base in interrupt mode. ### Method `HAL_TIM_Base_Start_IT(TIM_HandleTypeDef *htim)` ### Parameters - **htim** (TIM_HandleTypeDef*) - Pointer to a TIM_HandleTypeDef structure that contains the configuration information for the TIM module. ``` ```APIDOC ## HAL_TIM_PeriodElapsedCallback ### Description Period elapsed callback. This function is called when the timer period elapses. ### Method `HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)` ### Parameters - **htim** (TIM_HandleTypeDef*) - Pointer to a TIM_HandleTypeDef structure that contains the configuration information for the TIM module. ``` -------------------------------- ### Configure and Start PWM on TIM3 CH1 Source: https://context7.com/stmicroelectronics/stm32f1xx-hal-driver/llms.txt Sets up TIM3 Channel 1 for PWM generation with a 1 kHz frequency and 50% duty cycle. The duty cycle can be updated at runtime using __HAL_TIM_SET_COMPARE(). ```c #include "stm32f1xx_hal.h" TIM_HandleTypeDef htim3; /* --- PWM: 1 kHz, 50% duty cycle on TIM3 CH1 (PA6) --- */ void TIM_PWM_Example(void) { __HAL_RCC_TIM3_CLK_ENABLE(); htim3.Instance = TIM3; htim3.Init.Prescaler = 72 - 1; /* 72 MHz / 72 = 1 MHz */ htim3.Init.CounterMode = TIM_COUNTERMODE_UP; htim3.Init.Period = 1000 - 1; /* 1 MHz / 1000 = 1 kHz */ htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; if (HAL_TIM_PWM_Init(&htim3) != HAL_OK) Error_Handler(); TIM_OC_InitTypeDef sConfig = {0}; sConfig.OCMode = TIM_OCMODE_PWM1; sConfig.Pulse = 500; /* 500/1000 = 50% duty */ sConfig.OCPolarity = TIM_OCPOLARITY_HIGH; sConfig.OCFastMode = TIM_OCFAST_DISABLE; HAL_TIM_PWM_ConfigChannel(&htim3, &sConfig, TIM_CHANNEL_1); HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1); HAL_Delay(1000); /* Update duty cycle to 25% at runtime (no re-init needed) */ __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, 250); /* Read current counter value */ uint32_t cnt = __HAL_TIM_GET_COUNTER(&htim3); } ``` -------------------------------- ### HAL I2C New User Callbacks Source: https://github.com/stmicroelectronics/stm32f1xx-hal-driver/blob/master/Release_Notes.html New user callbacks for I2C operations, specifically HAL_I2C_ListenCpltCallback() and HAL_I2C_AddrCallback(), related to the repeated start feature. ```c HAL_I2C_ListenCpltCallback() HAl_I2C_AddrCallback() ``` -------------------------------- ### Configure GPIO Pins and Interrupts Source: https://context7.com/stmicroelectronics/stm32f1xx-hal-driver/llms.txt Initializes GPIO pins for output, input with pull-up, and external interrupts. Includes basic pin control functions and interrupt handling setup. Ensure the corresponding peripheral clock is enabled before initializing GPIO. ```c #include "stm32f1xx_hal.h" void GPIO_Example(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; /* --- Configure PA5 as push-pull output (LED) --- */ __HAL_RCC_GPIOA_CLK_ENABLE(); GPIO_InitStruct.Pin = GPIO_PIN_5; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* Set PA5 high */ HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET); HAL_Delay(500); /* Set PA5 low */ HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET); /* Toggle PA5 */ HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5); /* --- Configure PC13 as input with pull-up (button) --- */ __HAL_RCC_GPIOC_CLK_ENABLE(); GPIO_InitStruct.Pin = GPIO_PIN_13; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_PULLUP; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); GPIO_PinState state = HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13); /* state == GPIO_PIN_RESET when button pressed (active-low) */ /* --- Configure PB0 as external interrupt on rising edge --- */ __HAL_RCC_GPIOB_CLK_ENABLE(); GPIO_InitStruct.Pin = GPIO_PIN_0; GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING; GPIO_InitStruct.Pull = GPIO_PULLDOWN; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); HAL_NVIC_SetPriority(EXTI0_IRQn, 2, 0); HAL_NVIC_EnableIRQ(EXTI0_IRQn); /* Lock PA5 configuration to prevent accidental changes */ HAL_GPIO_LockPin(GPIOA, GPIO_PIN_5); } /* EXTI0 IRQ handler – call HAL handler which invokes the callback */ void EXTI0_IRQHandler(void) { HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0); } /* Callback – override the weak default */ void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { if (GPIO_Pin == GPIO_PIN_0) { HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5); /* toggle LED on button press */ } } ``` -------------------------------- ### HAL I2C Repeated Start APIs Source: https://github.com/stmicroelectronics/stm32f1xx-hal-driver/blob/master/Release_Notes.html New APIs introduced to support the I2C repeated start feature in interrupt mode for both master and slave sequential transmissions and receptions. ```c HAL_I2C_Master_Sequential_Transmit_IT() HAl_I2C_Master_Sequential_Receive_IT() HAl_I2C_Master_Abort_IT() HAl_I2C_Slave_Sequential_Transmit_IT() HAl_I2C_Slave_Sequential_Receive_IT() HAl_I2C_EnableListen_IT() HAl_I2C_DisableListen_IT() ``` -------------------------------- ### HAL Initialization and System Tick Functions Source: https://context7.com/stmicroelectronics/stm32f1xx-hal-driver/llms.txt This snippet demonstrates the usage of HAL_Init, HAL_DeInit, HAL_Delay, HAL_GetTick, HAL_SetTickFreq, HAL_GetHalVersion, HAL_GetDEVID, and HAL_GetUIDw0 for initializing the HAL, managing delays, and retrieving device information. ```APIDOC ## HAL Initialization and System Tick `HAL_Init` / `HAL_DeInit` / `HAL_Delay` / `HAL_GetTick` The HAL core module must be initialized once at startup via `HAL_Init()`, which configures the SysTick timer to generate a 1 ms time base, sets the NVIC priority grouping, and calls the weak `HAL_MspInit()` hook for board-level initialization. `HAL_Delay()` provides a blocking millisecond delay using the SysTick counter, and `HAL_GetTick()` returns the current tick value for non-blocking timeout calculations. ```c #include "stm32f1xx_hal.h" int main(void) { /* Initialize HAL: sets SysTick to 1 kHz, calls HAL_MspInit() */ if (HAL_Init() != HAL_OK) { /* Initialization error – hang or blink error LED */ while (1); } /* Configure system clock (done in SystemClock_Config) */ SystemClock_Config(); uint32_t start = HAL_GetTick(); /* millisecond timestamp */ HAL_Delay(500); /* blocking 500 ms delay */ uint32_t elapsed = HAL_GetTick() - start; /* elapsed ≈ 500 */ /* Change tick frequency to 100 Hz (10 ms resolution) */ HAL_SetTickFreq(HAL_TICK_FREQ_100HZ); /* Retrieve device identifiers */ uint32_t halVer = HAL_GetHalVersion(); /* e.g. 0x01010008 for v1.1.0.8 */ uint32_t devId = HAL_GetDEVID(); /* e.g. 0x0414 for STM32F10x High-density */ uint32_t uid0 = HAL_GetUIDw0(); /* Unique device ID word 0 */ /* Freeze TIM2 counter during debug breakpoints */ __HAL_DBGMCU_FREEZE_TIM2(); while (1) { /* application loop */ } } /* Weak MSP hook – override in user code for board-level init */ void HAL_MspInit(void) { __HAL_RCC_AFIO_CLK_ENABLE(); __HAL_RCC_PWR_CLK_ENABLE(); /* Disable JTAG, keep SWD */ __HAL_AFIO_REMAP_SWJ_NOJTAG(); } ``` ``` -------------------------------- ### DMA Initialization and Usage Source: https://context7.com/stmicroelectronics/stm32f1xx-hal-driver/llms.txt Demonstrates how to initialize a DMA channel for UART transmission and perform direct memory-to-memory copies. It also shows how to link DMA to peripheral handles and handle DMA interrupts. ```APIDOC ## HAL_DMA_Init / HAL_DMA_Start_IT / __HAL_LINKDMA ### Description The DMA HAL provides channel-level configuration for memory-to-peripheral, peripheral-to-memory, and memory-to-memory transfers. DMA handles are linked to peripheral handles using the `__HAL_LINKDMA()` macro, after which the peripheral's `_DMA` transfer functions manage the DMA channel automatically. Direct DMA usage (without a peripheral HAL) is possible via `HAL_DMA_Start()` and `HAL_DMA_PollForTransfer()`. ### Code Example: UART TX DMA Setup ```c #include "stm32f1xx_hal.h" DMA_HandleTypeDef hdma_usart1_tx; extern UART_HandleTypeDef huart1; void DMA_UART_TX_Setup(void) { __HAL_RCC_DMA1_CLK_ENABLE(); /* DMA1 Channel 4 = USART1 TX */ hdma_usart1_tx.Instance = DMA1_Channel4; hdma_usart1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH; hdma_usart1_tx.Init.PeriphInc = DMA_PINC_DISABLE; hdma_usart1_tx.Init.MemInc = DMA_MINC_ENABLE; hdma_usart1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; hdma_usart1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; hdma_usart1_tx.Init.Mode = DMA_NORMAL; hdma_usart1_tx.Init.Priority = DMA_PRIORITY_LOW; if (HAL_DMA_Init(&hdma_usart1_tx) != HAL_OK) Error_Handler(); /* Link DMA handle to UART TX handle */ __HAL_LINKDMA(&huart1, hdmatx, hdma_usart1_tx); HAL_NVIC_SetPriority(DMA1_Channel4_IRQn, 1, 0); HAL_NVIC_EnableIRQ(DMA1_Channel4_IRQn); } /* Now calling HAL_UART_Transmit_DMA() will use this DMA channel */ void DMA_Transfer_Example(void) { uint8_t bigBuffer[256]; /* fill bigBuffer ... */ /* DMA transfer: no CPU involvement during transfer */ HAL_UART_Transmit_DMA(&huart1, bigBuffer, sizeof(bigBuffer)); /* HAL_UART_TxCpltCallback() fires when DMA completes */ } ``` ### Code Example: Memory-to-Memory DMA Copy ```c void DMA_MemCopy_Example(void) { DMA_HandleTypeDef hdma_m2m; __HAL_RCC_DMA1_CLK_ENABLE(); hdma_m2m.Instance = DMA1_Channel1; hdma_m2m.Init.Direction = DMA_MEMORY_TO_MEMORY; hdma_m2m.Init.PeriphInc = DMA_PINC_ENABLE; hdma_m2m.Init.MemInc = DMA_MINC_ENABLE; hdma_m2m.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD; hdma_m2m.Init.MemDataAlignment = DMA_MDATAALIGN_WORD; hdma_m2m.Init.Mode = DMA_NORMAL; hdma_m2m.Init.Priority = DMA_PRIORITY_HIGH; HAL_DMA_Init(&hdma_m2m); uint32_t src[64], dst[64]; /* Start transfer, poll for completion */ HAL_DMA_Start(&hdma_m2m, (uint32_t)src, (uint32_t)dst, 64); HAL_DMA_PollForTransfer(&hdma_m2m, HAL_DMA_FULL_TRANSFER, 100); /* dst now contains a copy of src */ HAL_DMA_DeInit(&hdma_m2m); } void DMA1_Channel4_IRQHandler(void) { HAL_DMA_IRQHandler(&hdma_usart1_tx); } ``` ``` -------------------------------- ### Initialize HAL and System Tick Source: https://context7.com/stmicroelectronics/stm32f1xx-hal-driver/llms.txt Initializes the HAL library, configures the SysTick timer for a 1 ms time base, and provides functions for delays and tick retrieval. The HAL_MspInit hook must be overridden for board-level initialization. ```c #include "stm32f1xx_hal.h" int main(void) { /* Initialize HAL: sets SysTick to 1 kHz, calls HAL_MspInit() */ if (HAL_Init() != HAL_OK) { /* Initialization error – hang or blink error LED */ while (1); } /* Configure system clock (done in SystemClock_Config) */ SystemClock_Config(); uint32_t start = HAL_GetTick(); /* millisecond timestamp */ HAL_Delay(500); /* blocking 500 ms delay */ uint32_t elapsed = HAL_GetTick() - start; /* elapsed ≈ 500 */ /* Change tick frequency to 100 Hz (10 ms resolution) */ HAL_SetTickFreq(HAL_TICK_FREQ_100HZ); /* Retrieve device identifiers */ uint32_t halVer = HAL_GetHalVersion(); /* e.g. 0x01010008 for v1.1.0.8 */ uint32_t devId = HAL_GetDEVID(); /* e.g. 0x0414 for STM32F10x High-density */ uint32_t uid0 = HAL_GetUIDw0(); /* Unique device ID word 0 */ /* Freeze TIM2 counter during debug breakpoints */ __HAL_DBGMCU_FREEZE_TIM2(); while (1) { /* application loop */ } } /* Weak MSP hook – override in user code for board-level init */ void HAL_MspInit(void) { __HAL_RCC_AFIO_CLK_ENABLE(); __HAL_RCC_PWR_CLK_ENABLE(); /* Disable JTAG, keep SWD */ __HAL_AFIO_REMAP_SWJ_NOJTAG(); } ``` -------------------------------- ### ADC Polling Mode Conversion Source: https://context7.com/stmicroelectronics/stm32f1xx-hal-driver/llms.txt Starts an ADC conversion, polls for its completion, and retrieves the converted value. This method is suitable for simple, non-time-critical conversions. ```APIDOC ## HAL_ADC_Start / HAL_ADC_PollForConversion / HAL_ADC_GetValue ### Description Starts an ADC conversion, polls for its completion, and retrieves the converted value. This method is suitable for simple, non-time-critical conversions. ### Functions - `HAL_ADC_Start(ADC_HandleTypeDef *hadc)`: Starts ADC conversion. - `HAL_ADC_PollForConversion(ADC_HandleTypeDef *hadc, uint32_t Timeout)`: Polls for ADC conversion completion. - `HAL_ADC_GetValue(ADC_HandleTypeDef *hadc)`: Returns the ADC conversion result. ### Parameters #### HAL_ADC_Start - `hadc` (ADC_HandleTypeDef*): Pointer to an ADC_HandleTypeDef structure. #### HAL_ADC_PollForConversion - `hadc` (ADC_HandleTypeDef*): Pointer to an ADC_HandleTypeDef structure. - `Timeout` (uint32_t): Timeout duration in milliseconds. ### Request Example ```c HAL_ADC_Start(&hadc1); if (HAL_ADC_PollForConversion(&hadc1, 10) == HAL_OK) { uint32_t raw = HAL_ADC_GetValue(&hadc1); } HAL_ADC_Stop(&hadc1); ``` ### Response #### Success Response (HAL_OK) - `HAL_ADC_GetValue` returns a `uint32_t` representing the raw ADC value (0–4095 for 12-bit). ``` -------------------------------- ### Setup DMA for UART TX Transfer Source: https://context7.com/stmicroelectronics/stm32f1xx-hal-driver/llms.txt Configures DMA channel 4 for USART1 TX, linking it to the UART handle. Ensure the DMA interrupt is enabled and its priority is set. ```c #include "stm32f1xx_hal.h" DMA_HandleTypeDef hdma_usart1_tx; extern UART_HandleTypeDef huart1; void DMA_UART_TX_Setup(void) { __HAL_RCC_DMA1_CLK_ENABLE(); /* DMA1 Channel 4 = USART1 TX */ hdma_usart1_tx.Instance = DMA1_Channel4; hdma_usart1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH; hdma_usart1_tx.Init.PeriphInc = DMA_PINC_DISABLE; hdma_usart1_tx.Init.MemInc = DMA_MINC_ENABLE; hdma_usart1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; hdma_usart1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; hdma_usart1_tx.Init.Mode = DMA_NORMAL; hdma_usart1_tx.Init.Priority = DMA_PRIORITY_LOW; if (HAL_DMA_Init(&hdma_usart1_tx) != HAL_OK) Error_Handler(); /* Link DMA handle to UART TX handle */ __HAL_LINKDMA(&huart1, hdmatx, hdma_usart1_tx); HAL_NVIC_SetPriority(DMA1_Channel4_IRQn, 1, 0); HAL_NVIC_EnableIRQ(DMA1_Channel4_IRQn); } /* Now calling HAL_UART_Transmit_DMA() will use this DMA channel */ void DMA_Transfer_Example(void) { uint8_t bigBuffer[256]; /* fill bigBuffer ... */ /* DMA transfer: no CPU involvement during transfer */ HAL_UART_Transmit_DMA(&huart1, bigBuffer, sizeof(bigBuffer)); /* HAL_UART_TxCpltCallback() fires when DMA completes */ } void DMA1_Channel4_IRQHandler(void) { HAL_DMA_IRQHandler(&hdma_usart1_tx); } ``` -------------------------------- ### ADC Initialization and Configuration Source: https://context7.com/stmicroelectronics/stm32f1xx-hal-driver/llms.txt Initializes the ADC peripheral and configures a specific channel for conversion. This includes setting up scan mode, continuous conversion, data alignment, and external trigger source. ```APIDOC ## HAL_ADC_Init / HAL_ADC_ConfigChannel ### Description Initializes the ADC peripheral and configures a specific channel for conversion. This includes setting up scan mode, continuous conversion, data alignment, and external trigger source. ### Functions - `HAL_ADC_Init(ADC_HandleTypeDef *hadc)`: Initializes the ADC peripheral. - `HAL_ADC_ConfigChannel(ADC_HandleTypeDef *hadc, ADC_ChannelConfTypeDef *sConfig)`: Configures a specific ADC channel. ### Parameters #### HAL_ADC_Init - `hadc` (ADC_HandleTypeDef*): Pointer to an ADC_HandleTypeDef structure that contains the configuration information for the specified ADC module. #### HAL_ADC_ConfigChannel - `hadc` (ADC_HandleTypeDef*): Pointer to an ADC_HandleTypeDef structure. - `sConfig` (ADC_ChannelConfTypeDef*): Pointer to an ADC_ChannelConfTypeDef structure that contains the configuration information for the specified ADC channel. ### Example ```c ADC_HandleTypeDef hadc1; hadc1.Instance = ADC1; hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE; hadc1.Init.ContinuousConvMode = DISABLE; hadc1.Init.DiscontinuousConvMode = DISABLE; hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START; hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; hadc1.Init.NbrOfConversion = 1; HAL_ADC_Init(&hadc1); ADC_ChannelConfTypeDef sConfig = {0}; sConfig.Channel = ADC_CHANNEL_0; sConfig.Rank = ADC_REGULAR_RANK_1; sConfig.SamplingTime = ADC_SAMPLETIME_28CYCLES_5; HAL_ADC_ConfigChannel(&hadc1, &sConfig); ``` ``` -------------------------------- ### HAL I2C MspInit Configuration for DMA Source: https://github.com/stmicroelectronics/stm32f1xx-hal-driver/blob/master/Release_Notes.html Configuration steps for I2C IRQ in HAL_I2C_MspInit() function when using DMA error management. Requires enabling the I2C IRQ. ```c Configure and enable the I2C IRQ in HAL_I2C_MspInit() function ``` -------------------------------- ### ADC DMA Mode Conversion Source: https://context7.com/stmicroelectronics/stm32f1xx-hal-driver/llms.txt Starts a DMA transfer for ADC conversions, allowing continuous conversion of multiple channels into a buffer without CPU intervention. The `HAL_ADC_ConvCpltCallback` is called upon completion. ```APIDOC ## HAL_ADC_Start_DMA / HAL_ADC_ConvCpltCallback ### Description Starts a DMA transfer for ADC conversions, allowing continuous conversion of multiple channels into a buffer without CPU intervention. The `HAL_ADC_ConvCpltCallback` is called upon completion. ### Functions - `HAL_ADC_Start_DMA(ADC_HandleTypeDef *hadc, uint32_t *pData, uint32_t Length)`: Starts ADC conversion in DMA mode. - `HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)`: Callback function executed when DMA transfer is complete. ### Parameters #### HAL_ADC_Start_DMA - `hadc` (ADC_HandleTypeDef*): Pointer to an ADC_HandleTypeDef structure. - `pData` (uint32_t*): Pointer to the buffer that will store converted values. - `Length` (uint32_t): The number of conversions to be performed. ### Request Example ```c // Assuming hadc1 is already configured for scan mode and multiple channels uint32_t adcBuf[3]; HAL_ADC_Start_DMA(&hadc1, adcBuf, 3); // The HAL_ADC_ConvCpltCallback will be called when adcBuf is filled. void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc) { if (hadc->Instance == ADC1) { // Process data in adcBuf } } ``` ``` -------------------------------- ### GPIO Initialization and Control Functions Source: https://context7.com/stmicroelectronics/stm32f1xx-hal-driver/llms.txt Functions for initializing GPIO pins and controlling their state. HAL_GPIO_Init initializes a pin with specified parameters. HAL_GPIO_WritePin sets the pin state. HAL_GPIO_ReadPin reads the pin state. HAL_GPIO_TogglePin toggles the pin state. ```APIDOC ## GPIO – General Purpose Input/Output ### Functions - `HAL_GPIO_Init`: Initializes a GPIO pin with the specified configuration (`GPIO_InitTypeDef`). - `HAL_GPIO_WritePin`: Sets the state of a GPIO pin (SET or RESET). - `HAL_GPIO_ReadPin`: Reads the current state of a GPIO pin. - `HAL_GPIO_TogglePin`: Toggles the state of a GPIO pin. - `HAL_GPIO_LockPin`: Locks the configuration of a pin to prevent accidental changes. ### Initialization Structure (`GPIO_InitTypeDef`) - `Pin`: Specifies the GPIO pins to be configured (e.g., `GPIO_PIN_0`, `GPIO_PIN_15`). - `Mode`: Configures the pin mode (e.g., `GPIO_MODE_OUTPUT_PP`, `GPIO_MODE_INPUT`, `GPIO_MODE_IT_RISING`). - `Pull`: Configures the pin pull-up/pull-down state (e.g., `GPIO_NOPULL`, `GPIO_PULLUP`, `GPIO_PULLDOWN`). - `Speed`: Configures the output speed of the pin (e.g., `GPIO_SPEED_FREQ_LOW`). ### External Interrupts - Configure pins for external interrupts using modes like `GPIO_MODE_IT_RISING`, `GPIO_MODE_IT_FALLING`, or `GPIO_MODE_IT_RISING_FALLING`. - Use `HAL_NVIC_SetPriority` and `HAL_NVIC_EnableIRQ` to configure interrupt priorities and enable them. - Implement `EXTI[n]_IRQHandler` and `HAL_GPIO_EXTI_Callback` for interrupt handling. ``` -------------------------------- ### HAL_I2C_Init Source: https://context7.com/stmicroelectronics/stm32f1xx-hal-driver/llms.txt Initializes the I2C peripheral. This function configures the I2C peripheral with the specified parameters, including clock speed, addressing mode, and other control settings. ```APIDOC ## HAL_I2C_Init ### Description Initializes the I2C peripheral based on the configuration in the `I2C_HandleTypeDef` structure. ### Parameters - **hi2c** (*I2C_HandleTypeDef*): Pointer to an I2C_HandleTypeDef structure that contains the configuration information for the specified I2C module. ``` -------------------------------- ### I2C MSP Initialization and IRQ Handlers Source: https://context7.com/stmicroelectronics/stm32f1xx-hal-driver/llms.txt Configures the microcontroller-specific peripherals (MSP) for I2C1, enabling clocks for I2C1 and GPIOB, and setting up the SCL and SDA pins in alternate function open-drain mode. Also configures and enables the I2C1 event and error interrupts. ```c void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c) { if (hi2c->Instance == I2C1) { __HAL_RCC_I2C1_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); GPIO_InitTypeDef gpio = {0}; gpio.Pin = GPIO_PIN_6 | GPIO_PIN_7; /* SCL, SDA */ gpio.Mode = GPIO_MODE_AF_OD; gpio.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOB, &gpio); HAL_NVIC_SetPriority(I2C1_EV_IRQn, 1, 0); HAL_NVIC_EnableIRQ(I2C1_EV_IRQn); HAL_NVIC_SetPriority(I2C1_ER_IRQn, 1, 0); HAL_NVIC_EnableIRQ(I2C1_ER_IRQn); } } void I2C1_EV_IRQHandler(void) { HAL_I2C_EV_IRQHandler(&hi2c1); } void I2C1_ER_IRQHandler(void) { HAL_I2C_ER_IRQHandler(&hi2c1); } ```