먼저 클락 설정
PWM 파형을 만들어 내기 위한 TIM1 설정
TIM1은 APB2에서 클락소스를 공급받는다.
PSC와 ARR의 값을 위와 같이 설정해서 Frequency 를 50Hz로 맞춰줬다. 펄스폭은 소스코드 상에서 수정할거라 안건드렸다.
인풋캡처를 위한 TIM2 설정
TIM2은 APB1에서 클락소스를 공급받는다.
PSC를 90-1로 해서 1us 업카운터로 설정한다. 인풋캡처 채널은 하나는 Rising Edge 하나는 Falling Edge로 설정한다.
TIM2의 인터럽트 켜기
소스코드
/* USER CODE BEGIN PV */
int __io_putchar(int ch){
HAL_UART_Transmit(&huart3, &ch, 1, 1000);
return ch;
}
/* USER CODE END PV */
...
/* USER CODE BEGIN 0 */
uint32_t IC_Val1 = 0;
uint32_t IC_Val2 = 0;
float frequency = 0;
float dutyCycle = 0;
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1) // if the interrupt source is channel1
{
IC_Val1 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);
TIM2->CNT = 0;
}
if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2) // if the interrupt source is channel1
{
IC_Val2 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2);
dutyCycle = (float)IC_Val2/(float)IC_Val1 * 100;
frequency = 1000000 / (float)IC_Val1;
}
}
/* USER CODE END 0 */
...
/* USER CODE BEGIN 2 */
TIM1->CCR1 = 125;
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1);
HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_2);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
printf("Period: %.2fms, PulseWidth: %.2fms, DutyCycle: %.2f%%, Frequency: %.2fHz\r\n"
, (float)IC_Val1/1000, (float)IC_Val2/1000, dutyCycle, frequency);
HAL_Delay(1000);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
먼저 while문 위에서 TIM1의 CCR1 값을 125로 세팅해서 듀티비를 125/1000*100=12.5%로 맞춰줬다. 각자 PWM 과 IC 채널 1,2 인터럽트를 스타트한다.
인풋캡쳐 콜백함수 내에서 DutyCycle과 Frequency를 측정한뒤 while문 안에서 출력하는데 IC_Val1과 IC_Val2는 us 단위에서 ms 단위로 바꿔서 출력한다.
'임베디드 개발 > STM32 (ARM Cortex-M)' 카테고리의 다른 글
STM32 ] FreeRTOS + Semaphore ISR 사용 예제 (0) | 2022.08.08 |
---|---|
STM32 ] FreeRTOS 사용해보기 (1) | 2022.08.08 |
STM32 ] 자율주행 코드 짜기 - 프로젝트 준비과정 (6) (0) | 2022.07.25 |
STM32 ] SPI 통신 사용하기 (0) | 2022.07.24 |
STM32 ] TIMER OC (Output Compare 단자 출력) 사용 예제 (2) | 2022.07.21 |