#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stm32l0xx_hal.h>
#define ADC_CHANNEL ADC_CHANNEL_6 // ADC channel corresponding to PA7 (A6)
// Define PWM period value
uint32_t period = 1000; // 1 kHz PWM frequency
// Timer handle and channel
TIM_HandleTypeDef htim2;
uint32_t channel = TIM_CHANNEL_1;
// LED pin configuration
GPIO_InitTypeDef led_pin;
// ADC handle
ADC_HandleTypeDef hadc;
// Function prototypes
void SystemClock_Config(void);
void Error_Handler(void);
int main(void)
{
// Initialize HAL
HAL_Init();
// Configure system clock
SystemClock_Config();
// Configure LED pin for A6 (PA7)
led_pin.Pin = GPIO_PIN_7;
led_pin.Mode = GPIO_MODE_AF_PP;
led_pin.Pull = GPIO_NOPULL;
led_pin.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &led_pin);
// Configure TIM2 for PWM
htim2.Instance = TIM2;
htim2.Init.Prescaler = 4; // Set prescaler for desired PWM frequency
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = period;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
HAL_TIM_PWM_Init(&htim2);
// Start PWM on channel 1
HAL_TIM_PWM_Start(&htim2, channel);
// Configure ADC
__HAL_RCC_ADC1_CLK_ENABLE();
hadc.Instance = ADC1;
hadc.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV4;
hadc.Init.Resolution = ADC_RESOLUTION12b;
hadc.Init.ScanConvMode = DISABLE;
hadc.Init.ContinuousConvMode = DISABLE;
hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
HAL_ADC_Init(&hadc);
// Configure PA7 (A6) as analog input
ADC_ChannelConfTypeDef sConfig;
sConfig.Channel = ADC_CHANNEL_6;
sConfig.Rank = 1;
hadc.Init.SamplingTime = ADC_SAMPLETIME_19CYCLES_5;
HAL_ADC_ConfigChannel(&hadc, &sConfig);
while (1)
{
uint16_t adc_value;
HAL_ADC_Start(&hadc);
HAL_ADC_PollForConversion(&hadc, HAL_MAX_DELAY);
adc_value = HAL_ADC_GetValue(&hadc);
// Map ADC value to duty cycle range (0 to period)
uint32_t duty_cycle = (adc_value * period) / 4095;
// Update PWM duty cycle
__HAL_TIM_SET_COMPARE(&htim2, channel, duty_cycle);
// Print ADC value for debugging
printf("ADC Value: %d\n", adc_value);
HAL_Delay(100);
}
return 0;
}
// System Clock Configuration
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
// Configure the main internal regulator output voltage
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
// Initializes the CPU, AHB, and APB busses clocks
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
// 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();
}
}
// Error Handler
void Error_Handler(void)
{
while (1)
{
// Error occurred, stay in an infinite loop
}
}
#ifdef USE_FULL_ASSERT
void assert_failed(uint8_t *file, uint32_t line)
{
// User can add their own implementation to report the file name and line number,
// ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line)
while (1)
{
}
}
#endif
Loading
st-nucleo-l031k6
st-nucleo-l031k6