ARM-3 Timer
2023. 4. 10. 09:47ㆍARM
Timer를 사용해서 delay_us()함수를 만든다.
현재 시스템 클록이 84Mhz로 설정되어 있으므로 타이머 클록을 1Mhz로 분주하러면 분주비를 84로 나누어준다
1Mhz의 주기는 1us이므로 간단하게 delayus를 만들 수 있다.
- 분주비를 84로 분주해서 1Mhz의 주파수 생성
- TIM CH1을 input capture direct mode(상승에지, 하강에지 모두 설정)
- NVIC 설정(모두 켜짐)
다음 핀맵을 설정해준다. PA8은 타이머핀, PC5은 OUTPUT으로 설정해준다.
//main.c
HAL_TIM_IC_Start_IT(&htim1, TIM_CHANNEL_1); //INPUT_CAPTURE START, 상승에지에서 하강에지까지의 펄수 수를 카운트
void delay_us(unsigned long us)
{
//AVR : TCNT = 0;
__HAL_TIM_SET_COUNTER(&htim1, 0); //clear timer 1
while(!(__HAL_TIM_GET_COUNTER(&htim1) > us));
}
//딜레이 함수 만들어줌, 50ms 이상은 딜레이할 수 없음
/*
* UltraSonic.c
*
* Created on: Apr 6, 2023
* Author: jiwon
*/
#include "UltraSonic.h"
// /home/jiwon/STM32CubeIDE/workspace_1.12.0/20230406_1_ULTRASONIC/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c
// 초음파센서의 ECHO핀의 상승, 하강엣지 발생시 콜백 함수 실행
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
static uint8_t is_first_capture = 0; //상승엣지 0 하강엣지 1
if(htim->Instance == TIM1)
{
if(is_first_capture == 0)
{
__HAL_TIM_SET_COUNTER(htim, 0);
is_first_capture = 1;
}
else if(is_first_capture == 1)
{
is_first_capture = 0;
distance = (HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1));
inputCaptureFinishFlag = 1; //초음파 측정완료
}
}
}
void ultraSonicMain()
{
if(timer_11_ultrasonic >= 1000)
{
timer_11_ultrasonic = 0;
make_Trigger();
}
if(inputCaptureFinishFlag)
{
inputCaptureFinishFlag = 0;
distance = distance/2 * 0.034; //1us에 0.034 이동
printf("distance : %dcm\n", distance);
}
}
void make_Trigger()
{
HAL_GPIO_WritePin(ULTRASONIC_TRIG1_GPIO_Port, ULTRASONIC_TRIG1_Pin, 0);
delay_us(2);
HAL_GPIO_WritePin(ULTRASONIC_TRIG1_GPIO_Port, ULTRASONIC_TRIG1_Pin, 1);
delay_us(15);
HAL_GPIO_WritePin(ULTRASONIC_TRIG1_GPIO_Port, ULTRASONIC_TRIG1_Pin, 0);
}
초음파 센서에서 거리 측정을 시작하면 Echo핀이 1이 되고, 측정을 마치면 Echo핀이 0이된다. 이를 Timer1의 Input Capture Interrupt를 이용해 Echo신호의 길이(음파가 되돌아온 시간) 을 측정한뒤 1초마다 거리로 바꾸어 시리얼 통신으로 보내준다.
작동이 잘 되는 모습을 볼 수 있다.
20230406_1_ULTRASONIC.zip
6.53MB

Echo핀을 오실로스코프로 찍어보았다. 현재 7cm가 측정되고 있고, 펄스 폭이 400us이므로 얼추 맞는것을 볼 수 있다.