#include "main.h"
#include <stdio.h>
#include <string.h>
/* =========================================================
HANDLES
========================================================= */
ADC_HandleTypeDef hadc1;
TIM_HandleTypeDef htim2;
UART_HandleTypeDef huart1;
/* =========================================================
FUNCTION PROTOTYPES
========================================================= */
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_ADC1_Init(void);
static void MX_TIM2_Init(void);
static void MX_USART1_UART_Init(void);
void Error_Handler(void);
int main(void)
{
/* HAL initialization */
HAL_Init();
/* Configure system clock */
SystemClock_Config();
/* Initialize peripherals */
MX_GPIO_Init();
MX_ADC1_Init();
MX_TIM2_Init();
MX_USART1_UART_Init();
/* =====================================================
VARIABLES
===================================================== */
char msg[100];
uint32_t adc_value = 0;
GPIO_PinState current_status;
GPIO_PinState last_status = GPIO_PIN_RESET;
/* =====================================================
START PWM
===================================================== */
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
/*
* Initial PWM duty cycle = 0
*/
__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, 0);
/* =====================================================
SEND START MESSAGE
===================================================== */
sprintf(msg, "System Started\r\n");
HAL_UART_Transmit(
&huart1,
(uint8_t *)msg,
strlen(msg),
100
);
/* =====================================================
MAIN LOOP
===================================================== */
while (1)
{
/* =================================================
1. READ PIR SENSOR
PA1
================================================= */
current_status =
HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1);
/* =================================================
2. CHECK PIR STATUS CHANGE
================================================= */
if (current_status != last_status)
{
if (current_status == GPIO_PIN_SET)
{
/*
* PIR HIGH
* Motion detected
*/
sprintf(
msg,
"ALERT: Motion Detected!\r\n"
);
}
else
{
/*
* PIR LOW
* No motion
*/
sprintf(
msg,
"STATUS: Area Clear.\r\n"
);
}
/* Send message through UART */
HAL_UART_Transmit(
&huart1,
(uint8_t *)msg,
strlen(msg),
100
);
/* Update previous state */
last_status = current_status;
}
/* =================================================
3. READ ADC
PA5 = ADC1_IN5
================================================= */
HAL_ADC_Start(&hadc1);
if (HAL_ADC_PollForConversion(
&hadc1,
100) == HAL_OK)
{
adc_value =
HAL_ADC_GetValue(&hadc1);
}
HAL_ADC_Stop(&hadc1);
/* =================================================
4. ADC VALUE → PWM
================================================= */
/*
* ADC:
*
* 0 → 0
* 4095 → 4095
*
* PWM:
*
* 0 → 0%
* 4095 → 100%
*/
__HAL_TIM_SET_COMPARE(
&htim2,
TIM_CHANNEL_1,
adc_value
);
/* =================================================
5. SMALL DELAY
================================================= */
HAL_Delay(100);
}
}
/* =========================================================
SYSTEM CLOCK CONFIGURATION
========================================================= */
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/* HSE + PLL */
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;
/* PLL */
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();
}
/* Clock configuration */
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();
}
}
/* =========================================================
ADC1 CONFIGURATION
PA5 = ADC1_IN5
========================================================= */
static void MX_ADC1_Init(void)
{
ADC_ChannelConfTypeDef sConfig = {0};
/* ADC instance */
hadc1.Instance = ADC1;
/* ADC configuration */
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;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
Error_Handler();
}
/* =====================================================
PA5 = ADC CHANNEL 5
===================================================== */
sConfig.Channel =
ADC_CHANNEL_5;
sConfig.Rank =
ADC_REGULAR_RANK_1;
sConfig.SamplingTime =
ADC_SAMPLETIME_239CYCLES_5;
if (HAL_ADC_ConfigChannel(
&hadc1,
&sConfig) != HAL_OK)
{
Error_Handler();
}
}
/* =========================================================
TIM2 PWM CONFIGURATION
PA0 = TIM2_CH1
========================================================= */
static void MX_TIM2_Init(void)
{
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_OC_InitTypeDef sConfigOC = {0};
/* Timer instance */
htim2.Instance = TIM2;
/*
* Timer clock = 72 MHz
*
* Prescaler = 17
*
* Timer frequency:
*
* 72 MHz / (17 + 1)
*
* = 4 MHz
*
* ARR = 4095
*
* PWM frequency:
*
* 4 MHz / 4096
*
* ≈ 976.56 Hz
*/
htim2.Init.Prescaler = 17;
htim2.Init.CounterMode =
TIM_COUNTERMODE_UP;
htim2.Init.Period = 4095;
htim2.Init.ClockDivision =
TIM_CLOCKDIVISION_DIV1;
htim2.Init.AutoReloadPreload =
TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
{
Error_Handler();
}
/* Internal clock */
sClockSourceConfig.ClockSource =
TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(
&htim2,
&sClockSourceConfig) != HAL_OK)
{
Error_Handler();
}
/* PWM initialization */
if (HAL_TIM_PWM_Init(&htim2) != HAL_OK)
{
Error_Handler();
}
/* =====================================================
PWM CHANNEL 1
===================================================== */
sConfigOC.OCMode =
TIM_OCMODE_PWM1;
sConfigOC.Pulse =
0;
sConfigOC.OCPolarity =
TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode =
TIM_OCFAST_DISABLE;
if (HAL_TIM_PWM_ConfigChannel(
&htim2,
&sConfigOC,
TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
}
/* =========================================================
USART1 CONFIGURATION
========================================================= */
static void MX_USART1_UART_Init(void)
{
huart1.Instance = USART1;
huart1.Init.BaudRate =
9600;
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();
}
}
/* =========================================================
GPIO CONFIGURATION
========================================================= */
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* Enable GPIOA clock */
__HAL_RCC_GPIOA_CLK_ENABLE();
/* =====================================================
PA1 = PIR SENSOR
===================================================== */
GPIO_InitStruct.Pin =
GPIO_PIN_1;
GPIO_InitStruct.Mode =
GPIO_MODE_INPUT;
GPIO_InitStruct.Pull =
GPIO_NOPULL;
GPIO_InitStruct.Speed =
GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(
GPIOA,
&GPIO_InitStruct
);
/* =====================================================
PA5 = ADC INPUT
===================================================== */
GPIO_InitStruct.Pin =
GPIO_PIN_5;
GPIO_InitStruct.Mode =
GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull =
GPIO_NOPULL;
HAL_GPIO_Init(
GPIOA,
&GPIO_InitStruct
);
/* =====================================================
PA0 = TIM2_CH1 PWM OUTPUT
===================================================== */
GPIO_InitStruct.Pin =
GPIO_PIN_0;
GPIO_InitStruct.Mode =
GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull =
GPIO_NOPULL;
GPIO_InitStruct.Speed =
GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(
GPIOA,
&GPIO_InitStruct
);
}
/* =========================================================
ERROR HANDLER
========================================================= */
void Error_Handler(void)
{
__disable_irq();
while (1)
{
}
}Loading
stm32-bluepill
stm32-bluepill