PWM
engineer4ever
2025. 8. 8. 10:20
2025. 8. 8. 10:20
|
MCU
|
STM32F103(ST)
|
|
IDE
|
Atollic(TrueSTUDIO), STM32CubeMX
|
|
목표
|
HAL driver를 사용하여 PWM으로 20KHz에 duty 50의 파형을 만든다.
|
1. STM32CubeMX : PWM 설정
- 'Pinout & Configuration' Tab으로 이동
1) TIM2 선택
2) Channel 1 : PWM Generation CH1 선택
3) Prescaler : 32-1
- 64MHz / 32 = 2,000,000 = 2MHz
4) Counter Period : 100-1
- 2,000,000 / 100 = 20,000 = 20KHz
5) PWM Generation Channel1 > Pulse : 50
- 20KHz에 duty 50인 파형 발생
2. ATOLLIC : main.c 수정
- HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1);
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_ADC1_Init();
MX_RTC_Init();
MX_USART1_UART_Init();
MX_TIM6_Init();
MX_TIM7_Init();
/* USER CODE BEGIN 2 */
HAL_ADC_Start_DMA(&hadc1,(uint16_t*)&(adc_val[0]),3);
HAL_TIM_Base_Start_IT (&htim6);
HAL_TIM_Base_Start_IT (&htim7);
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1);
/* USER CODE END 2 */
engineer4ever
2025. 4. 19. 11:44
2025. 4. 19. 11:44
|
MCU
|
STM32F746G DISCOVERY(ST)
|
|
IDE
|
Atollic(TrueSTUDIO), STM32CubeMX
|
|
목표
|
HAL driver를 사용하여 TIMER 다양한 mode를 사용하여 LED를 1Hz(1초에 한번 켜졌다 꺼졌다)로 ON-OFF 한다.
|
TIM2를 사용하는데 TIM2는 APB1 Timer clock = 100MHz
1. STM32CubeMX : TIMER Output Compare 설정
- 'Pinout & Configuration' Tab으로 이동
1) Timers - TIM2 선택
2) Channel1 : Output Compare No Output 선택
3) Prescaler : 50000-1
- 100MHz / 50,000 = 2,000 = 2KHz
4) Counter Period : 1000-1
- 2,000 / 1,000 = 2Hz, 0.5s 간격으로 TIM2 Interrupt 발생
5) Output Compare : 100
- OC count가 500이 될때 마다 TIM2 Output Compare Interrupt 발생
6) NVIC : TIM2 global interrupt Enabled
- ATOLLIC : main.c 수정
- HAL_TIM_Base_Start_IT, HAL_TIM_OC_Start_IT ; 인터럽트 시작을 위해 추가
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_GFXSIMULATOR_Init();
MX_USART1_UART_Init();
MX_RTC_Init();
MX_TIM6_Init();
MX_TIM2_Init();
/* USER CODE BEGIN 2 */
HAL_TIM_Base_Start_IT(&htim2);
HAL_TIM_OC_Start_IT(&htim2, TIM_CHANNEL_1);
/* USER CODE END 2 */
- HAL_TIM_PeriodElapsedCallback(), HAL_TIM_OC_DelayElapsedCallback() 작성
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance == htim2.Instance)
{
HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET);
}
}
void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance == htim2.Instance)
{
HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);
}
}
- 0.5s 마다 duty 10%로 LED 점멸
STM32F746 TIMER OC 테스트(LED 점멸)
2. STM32CubeMX : TIMER PWM 설정
- 'Pinout & Configuration' Tab으로 이동
1) TIM2 선택
2) Channel1 : PWM Generation No Output 선택
3) Prescaler : 50000-1
- 100MHz / 50,000 = 2,000 = 2KHz
4) Counter Period : 1000-1
- 2,000 / 1,000 = 2Hz, 0.5s 간격으로 TIM2 Interrupt 발생
5) Output Compare : 900
- Duty 90%
6) NVIC : TIM2 global interrupt Enabled
- GENERATE CODE 클릭
- ATOLLIC : main.c 수정
- HAL_TIM_PWM_Start ; 인터럽트 시작을 위해 추가
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_GFXSIMULATOR_Init();
MX_USART1_UART_Init();
MX_RTC_Init();
MX_TIM6_Init();
MX_TIM2_Init();
/* USER CODE BEGIN 2 */
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1);
HAL_TIM_PWM_Start_IT(&htim2, TIM_CHANNEL_1);
/* USER CODE END 2 */
- HAL_TIM_PWM_PulseFinishedCallback() 작성
- 0.5s 마다 인터럽트가 걸리는데, 인터럽트 걸릴때 마다 토글하게 되있으므로 1s 마다 LED 점멸
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance == htim2.Instance)
{
HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
}
}
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_GFXSIMULATOR_Init();
MX_USART1_UART_Init();
MX_RTC_Init();
MX_TIM6_Init();
MX_TIM2_Init();
/* USER CODE BEGIN 2 */
HAL_TIM_Base_Start_IT(&htim2);
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1);
HAL_TIM_PWM_Start_IT(&htim2, TIM_CHANNEL_1);
/* USER CODE END 2 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance == htim2.Instance)
{
HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET);
}
}
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance == htim2.Instance)
{
HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);
}
}
- 0.5s 마다 duty 90%로 LED 점멸
STM32F746 TIMER PWM 테스트(LED 점멸)