STM32-초음파센서 인터럽트

하만(Harman) 세미콘 반도체 설계 과정/ARM Architecture 이해 및 RTOS 활용

STM32-초음파센서 인터럽트

semicon_circuitdesigner 2024. 7. 11. 11:09
728x90

[2024.07.11.목] 인천인력개발원


초음파센서 제어 절차
  • 10us TTL 신호로 Trigger
  • 송신기는 8개 40kHz 버스트 신호 송신
  • 수신기는 반향신호 수신(High 레벨 신호의 지속시간을 측정)
  • 지속시간과 음속을 활용하여 거리 계산
  • Trigger 신호로부터 Echo 신호가 감지되기까지의 충분한 대기시간이 필요(60ms~) -> 16.6Hz

 

거리가 1m 이상 -> 노래 정상속도

거리가 0.5m~1m -> 노래 1.5배속

거리가 0.5m 이하 -> 노래 2배속

 

While 문 실행 내용을 인터럽트로 변경하기
  • 아래와 같이 While문으로 동작 실행 시 오류가 나면 무한 루프에 빠질 수 있다. 이를 방지하기 위해 Echo의 동작을 Interrupt로 설정하여 해결한다.

 

1. Test004-US의 ioc파일에서 PB4 핀을 GPIO_EXTI4로 변경

 

2. Core-NVIC에서 EXTI line4 Interrupt 체크

 

3. System Core - GPIO 탭에서 PB4의 인터럽트가 언제 실행될 지 설정할 수 있다.

 - External Interrupt Mode with Rising/Falling edge trigger detection으로 설정

 

4. Code Generation 후 main.c에서 Pin 설정 확인

echo pin이 rising과 falling에서 작동하도록 정상적으로 설정되었다

 

5. Test004-US - Core - Src - stm32f4xx_it.c파일에서 HAL_GPIO_EXTI_IRQHandler에 Ctrl+클릭

 

6. weak void HAL~ 복사해서 main.c에 붙여넣고 코드 작성

 

7. 위 코드는 다음과 같이 요약할 수 있다.

  • 위 코드의 t1인 부분에서의 시간은 tt로 측정되며, 이 값을 ts에 대입한다.
  • 이후 t2인 부분에서 시간은 tt로 측정된다.
  • 이 순간의 tt값에서 ts를 빼면 t2 - t1과 같은 값이 나오게 된다.

8. 위 코드에서 거리를 계산하여 전역변수 dist에 저장했으므로, 이를 출력하는 아래의 코드에서 출력하는 값을 바꿔준다,

 

9. 숫자가 바뀌지 않고 0으로 고정되는 오류 발생

  • 트리거 신호를 발생시키는 getdist()함수를 사용하지 않아 트리거가 발생되지 않고, 이로 인해  0으로부터 값이 변하지 않음

10. 위 오류를 해결하기 위해 트리거 인터럽트 만들기

10 - 1. Test004-US.ioc에서 Timers 탭 - TIM3를 선택 - Clock Source를 Internal Clock으로

 

10 - 2. Trigger 신호의 주기를 66ms(15Hz)로 하기 위해 계산하여 PSC와 ARR 설정

 - CLK_Freq./Update event = (PSC*ARR) 이므로, 84MHz / 15 = 5,600,000 = (560*10000)

 

10 - 3. NVIC Settings 탭에서 TIM3 global Interrupt 활성화

 

10-4. Code Generation 후 stm32f4xx_it.c 파일을 열어 HAL_TIM_IRQHandler에 Ctrl+좌클릭

 

10-5. 아래 함수를 복사하여 main.c에 붙여넣고 ISR 작성

 

10-6. 인터럽트 시작 함수 설정 후 실행

 

11. 작동 확인(while 구문 내의 microdelay 함수를 HAL_Delay로 바꿔야 함 - microdelay 내의 값이 overflow가 되어 값이 제대로 입력되지 않아 작동하지 않는 오류 수정)

 

Trigger 신호를 PWM으로 생성

 

1. "Test004-US-intr"프로젝트 만들기

2. 기존의 Test004-US 프로젝트와 동일하게 핀 설정

  • PB5를 GPIO_Output, PB4를 GPIO_EXTI4 으로 설정 후 각각 Trig, Echo로 라벨링

 

3. Code Generate

4. Test004-US - Src 폴더 내의 main.c와 myLib.c를 복사해서 현재 프로젝트에 붙여넣기

덮어쓰기 진행: Yes To All

 

5. 타이머 인터럽트 설정하기 위해 ioc파일에서 내용 수정

 

6. ioc 파일의 System Core - NVIC 탭에서 다음과 같이 체크

 

7. GPIO에서 Echo 인터럽트의 동작 시기 변경

 

8. Project - Properties 에서 아래 Use float with~~ 설정 체크 후 Run 및 동작 확인

 

9. Teraterm에서 커서를 표시하지 않기(cursor off) 위해 코드 사용: \033[?25l

  • printf 내에서 사용하는 명령어
     - cursur on: \033[?25h
     - 글자 크기를 더 크게 출력: \033[#3
     - 글자 크기를 더 작게 출력: \033[#4

커서를 지워서 출력하는 경우

 

10.Test004-US-GPIO.ioc에서 타이머 변경: TIM3 disable

 

11. System Core - NVIC에서 EXTI line4 interrrupt disable

 

12. PB3를 GPIO_Input으로 변경 후 SWO로 라벨링

 

13. Code Generation -> 수정된 포트 설정에 대해 코드를 수정해준다.

 

. Test004-US의 Project Name을 Test004-US-GPIO로 변경 후 main.c에서 다음 부분 삭제

15. 다음의 코드 수정


PWM을 이용한 초음파 센서 거리 측정


1. Test004-US-PWM으로 프로젝트 생성

2. .ioc 파일에서 PB5, PB4 핀 설정

 

3. 라벨링

 

4. TIM5에 Internal Clock 인가 후 값 설정

 

5. TIM3에 Internal Clock 인가 후 값 설정

 

6. TIM3로 PWM 을 공급하기 위해 CH2에 모드 인가

 

7. Channel2에 Pulse 값 인가

 

8. NVIC에서 EXTI line4 interrupt 활성화

 

9. GPIO에서 PB4에 대해 인터럽트 작동 모드 변경

 

10. Code Generation

 

11. 코드 작성: 타이머5를 시작하는 코드와 타이머3으로 PWM을 시작하는 코드

 

12. Echo에 대한 ISR 작성

  • stm32f4xx_it.c 열기
  • 아래 코드 찾아 ctrl+클릭 후
    void EXTI4_IRQHandler(void)
  • 아래 코드를 복사하여 붙여넣고 코드 작성
    void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
  • 현재 tim5의 카운터 값을 te에 저장하고, GPIO Pin의 값이 Echo Pin의 값과 같다면 현재의 값을 ts에 저장 (rising edge의 값)
  • 현재의 GPIO Pin의 값이 Echo Pin과 같지 않다면 현재의 시간에서 rising edge의 시간을 빼서 거리를 계산

 

13. 프린트 기능 코드 작성

728x90
반응형