대표적으로는 부저(Buzzer)에서 사용

부저같은 경우는 펄스 폭을 ARR의 50%로만 유지하면 문제없음

  • while문으로 계속 실시간으로 바꾸다보면 갑자기 PWM신호의 출력이 없어져버리는 현상 : 펄스의 주기를 실시간으로 바꾸려면 ARR가 아닌 prescaler 을 통해 변경해야함

[기존]

84000000 / 168 / 1000 = 500 Hz 200 Hz 사이의 간격으로 하기위해서는

84000000 / 168 (고정) / x = 200 ⇒ x : 2500

PWM 출력이 갑자기 사라지는 (출력이 아예 없음) 경우가 있기 때문에 ARRegister 가 아닌 prescaler 레지스터를 접근하면서 실시간으로 변경해주면 됨

  • psc를 바꾸나 arr을 바꾸나 pwm 주기가 변하는 것은 똑같음 ⇒ ARR값의 의미만 조금 다를 뿐

'FW > STM32' 카테고리의 다른 글

06-2_PWM : PWM 신호이용 Application  (0) 2023.02.21
06-1_PWM : Timer 을 이용한 PWM  (1) 2023.02.21
05_EXTI (외부인터럽트)  (3) 2023.02.21
04_Timer_Interrupt  (1) 2023.02.21
03_Character_LCD  (1) 2023.02.21

 

1. 서브모터

[CubeMX]
TIM10 2채널 중 1번 채널 사용

 

pwm의 주기를 20ms로 만드는 방법 : 타이머의 주기 (168000000 / 내가 만들고자하는 pwm 펄스의 주기 (20ms의 경우 50 Hz이므로 50) ⇒ 결과값을 각 prescaler x Counter Period 의 형태로 만들어주기 ex) 168000000 / 50 =3360000 = 336 x 10000 ⇒ prescaler : 336 -1 , AAR(Counter Period) : 10000 - 1

[TrueStudio]

따라서, AAR은 10000이므로 만 번의 단계가 있는 것이고, 각 단계가 펄스 폭을 갖게될텐데 PWM 펄스의 폭을 구하려면 20ms을 10000단계로 나누면 → 1단계당 0.002, 우리가 원하는 것은 0.2이기 때문에 100을 곱해야함 ⇒ 펄스 폭은 100ms가 됨

0.2 ms (펄스폭 : 100) ⇒ cw 끝으로 이동 3ms (펄스폭 : 1500) ⇒ ccs 끝으로 이동

따라서 0.2ms~3ms 사이로 펄스 폭을 설정하면 그 사이에서 서브모터 컨트롤 가능

 

 

 

 

2. 부저 Buzzer

 

  • 능동형 : 전원을 인가하면 정해져있는 주파수에 비프음이 계속 나오는 부저
  • 수동형 passive : 입력된 신호의 주파수에 따라서 비프음이 나오는 부저

 

  • 펄스폭은 소리와 상관이 없지만 너무 작으면 비프음이 안들리는 경우가 있기 때문에 적절히 넣어준다

[CubeMX]

TIM2 4ch 중 1번 채널 사용

 

 

 

음계를 찍을 수도 있음

 

 

3. DC 모터

 

brushed DC모터 : 두 개의 핀, 각 핀이 순방향으로 전류가 흐르면 정회전, 역방향으로 전류가 흐르면 역방향 | 모터를 동작시키기 위해 PWM신호를 바로 모터로 연결하면 모터에서는 전력을 많이 소모하기 때문에 Pin 손상 또는 chip 이 죽을 수 있음 ⇒ 전력을 많이 소모하는 장치들은 장치에 드라이버를 달아서 사용함

입력 핀 2개 : STM에서 PWM 신호 연결

출력 핀 2개 : 모터로 연결

 

 

[CubeMX]

TIM5 4ch 중 1, 4번 채널 사용

'FW > STM32' 카테고리의 다른 글

06-3_PWM : 실시간 주기변경  (1) 2023.02.21
06-1_PWM : Timer 을 이용한 PWM  (1) 2023.02.21
05_EXTI (외부인터럽트)  (3) 2023.02.21
04_Timer_Interrupt  (1) 2023.02.21
03_Character_LCD  (1) 2023.02.21
  • 한 주기 내에서 펄스의 폭을 변경하면서 어떤 장치를 구동시킴
  • 요즘 사용되는 곳 : LED의 밝기나 모터의 회전 속도, 서브모터의 각도 등을 제어함
  • PWM : 펄스의 주기 + 한 주기 내에서의 펄스 폭 + 전압 레벨(MCU의 동작 전압) 로 정의

일반 MCU들처럼 STM 시리즈도 타이머를 이용해서 PWM신호를 만든다 ⇒ PWM신호의 주기나 펄스의 폭을 변경하기 쉽기 때문

PWM을 만들 때는 타이머 업데이트 인터럽트가 굳이 없어도 됨

한 주기 안에서 펄스의 폭을 조절할 수 있어야함 ⇒ Capture Compare Register 사용 CCRegister → 0 ~ AAR (Auto Reload Register) 값 까지

[사진 1]

Auto Reload Register 의 값에 따라 한 주기가 이루어짐, Capture Compare Register 의 값이 정해지면 해당 값 까지만 올라가다가 남은 주기는 low로 떨어져있고, 한 주기가 다시 시작 될 때 다시 올라감

 

즉, PWM 펄스의 주기는 AAR, Prescaler, Timer(APB1/APB2) 에 따라 정해짐

그 주기 안에서 PWM 펄스 폭은 Capture Compare Register 를 통해 설정

채널의 개수 - 각 채널에 대한 CCR도 1:1로 존재하기 때문에 CCR의 개수로도 볼 수 있으며, 그 CCR의 개수만큼 독립적으로 타이머를 제어할 수 있음

이전에는 Prescaler 와 AAR이 반비례하고, 최종 값만 일치하면 상관없다했는데, PWM에서는 이야기가 달라짐 CCR의 값이 너무 낮으면 불안정함, 어느 정도 값을 높여서 설정해주는 것이 좋음

 

 

=======================실습============================

CudeMX에서 변경한 사항 : 기존에 LED GPIO output 이던 부분을 TIM3, TIM4 ch로 변경

  1. MX_TIM3_Init

주기설정 부분 :

 

 

 

 

 

 

펄스폭설정 부분: 

 

위상 설정 : PWM 폭 형태(high/low)를 반전시켜서 출력할 수도 있음 옵션에 따라

1 또는 2 변경

[Code]

  • Drivers/Src/stm32f4xx_hal_tim.c
    1. HAL_TIM_PWM_Start() 함수를 main.c 에서 호출

[표 1]

 

 

[표 2]

각 타이머마다 PWM 출력채널로 사용할 수 있는 핀들이 정리되어있는 표

'FW > STM32' 카테고리의 다른 글

06-3_PWM : 실시간 주기변경  (1) 2023.02.21
06-2_PWM : PWM 신호이용 Application  (0) 2023.02.21
05_EXTI (외부인터럽트)  (3) 2023.02.21
04_Timer_Interrupt  (1) 2023.02.21
03_Character_LCD  (1) 2023.02.21

지난번에 스위치 눌러서 GPIO로 신호 전해서 인터럽트 시켰던 것은 폴링방식 (while문에 넣고 계속 예의주시하는 방식) 이었고 이번엔 외부 인터럽트 방식으로 진행

 

외부인터럽트도 GPIO로 신호 보냄 (외부인터럽트는 폴링방식에 비해 CPU의 클럭소모가 비교적 적음)

 

 

[표 1] 각 0번지 포트들은 외부인터럽트 0번을 발생시킴

 

 

[표 2] 0~4 번은 독립적으로 인터럽트 발생 (함수도 독립적으로 존재) 9_5와 15_10은 하나의 인터럽트함수만 호출이 됨 (나눠씀)

 

 

==============================실습=============================

이전에 스위치테스트(내부인터럽트/폴링방식)으로 할 때는 GPIO_Input으로 설정해 둔 핀들을 GPIO_EXTI으로 설정

  • stm32f4xx_it.c : EXTI3_IRQHandler / EXTI4_IRQHandler / EXTI15_10_IRQHandler ⇒ HAL_GPIO_EXTI_IRQHandler ⇒ HAL_GPIO_EXTI_Callback ⇒ 사용자 사용 (_weak)
  • RISING 인지, Falling인지, rising_falling(둘 다의 경우에 인터럽트 생기는 것) 인지에 따라 인터럽트 발생 시점을 설정할 수 있다. ex) rising_falling 의 경우 해당 GPIO 코드에 토글기능을 넣었다면 입력, 출력 시 모두 토글됨

 

'FW > STM32' 카테고리의 다른 글

06-2_PWM : PWM 신호이용 Application  (0) 2023.02.21
06-1_PWM : Timer 을 이용한 PWM  (1) 2023.02.21
04_Timer_Interrupt  (1) 2023.02.21
03_Character_LCD  (1) 2023.02.21
02_UART  (0) 2023.02.21

  • 타이머 : 시간재기
  • 마이크로프로세서 / 디지털 시스템 : 시간을 측정하기위해 클럭을 카운트하는 방식
  • STM : 몇가지 레지스터 설정 + 타이머 활성화 = 타이머에 클럭 공급 ⇒ 클럭이 들어올때마다 카운트레지스터( 클럭을 세는 레지스터) 가 자동으로 증가 그러다가 내가 설정한 특정한 값이 되면 업데이트 인터럽트 발생 ⇒ 업데이트 인터럽트가 발생 시 : 카운트 레지스터 초기화 ⇒ 0부터 다시 시작해서 특정한 값까지 증가

 

  • 타이머의 기본 동작 TCNT : 카운트 레지스터 / 레지스터가 몇 비트 짜리냐에 따라 세는 양이 달라짐

AutoReload Register 안에 특정 값 넣으면 그 값에 다다를때마다 업데이트 인터럽트 발생

 

STM32F407 의 시스템동작클럭 (HCLK) : 168MHz

 

위 단어들은 (APB, AHB) → AMBA라는 단어를 통해 찾아보기

⇒ 데이터가 오고가는 버스의 구조에 대한 설명

[중요] APB1 / APB2 를 사용하느냐에 따라 타이머 동작 클럭이 달라짐

<PWM 할 때는 이 값들의 영향이 커지는데>

ex) APB1 의 경우 1주기가 증가하는데에 소요되는 시간 : 1/84000000(s) ⇒ 속도가 너무 빠름 ⇒ 업데이트 인터럽트가 자주 걸림 ⇒ 그렇게 좋지만은않음

⇒ 따라서, 자주걸리는 것 보다 천천히, 여유있게 걸리는 게 좋음 ⇒ prescaler : 타이머에 공급하는 입력 클럭의 속도를 조절하는 분주기 / 최대 16비트 (65535)

ex) APB1 (84,000,000) 일 경우

  1. prescaler = 10000 , ARR (AutoReload) = 8400 으로 설정해서 업데이트 인터럽트가 1초에 한 번 발생하는 것과
  2. prescaler = 20000 , ARR (AutoReload) = 4200 으로 설정해서 업데이트 인터럽트가 1초에 한 번 발생하는 것은 결과적으로 같으며, 크게 상관없음

⇒ 적절히 prescaler와 ARR을 조절하여 사용하면 됨

==============================실습===============================

위 표 중에서 TIM7 사용

 

  • prescaler = 10000 , ARR (AutoReload) = 8400 인데 설정할 경우에는 -1 한 값으로 설정
  • counter mode 는 up, down 이 있는데 default 는 up, TIM7는 up mode만 지원

[주요 추가사항 및 부분]

  • main.c : MX_TIM7_Init
  • stm32f4xx_it.c : TIM7_IRQHandler → HAL_TIM_IRQHandler → HAL_TIM_PeriodElapsedCallback → 사용자 사용
  • delay와 interrupt는 다름 : delay는 1초 간 다른것도 못하고 기다리는데, 인터럽트는 다른 일 수행 중에 1초에 한 번씩 순간적으로 인터럽트 발생 및 처리

'FW > STM32' 카테고리의 다른 글

06-1_PWM : Timer 을 이용한 PWM  (1) 2023.02.21
05_EXTI (외부인터럽트)  (3) 2023.02.21
03_Character_LCD  (1) 2023.02.21
02_UART  (0) 2023.02.21
01_GPIO  (0) 2023.02.21

캐릭터 LCD 는 어떤 것을 사용하든 사용자 정의 라이브러리 틀(?)이 거의 동일함

⇒ 사용자 정의 라이브러리에서 입맛에 맞게 변경하여 사용

사용자정의라이브러리파일 : CLCD.c, CLCD.h

GPIO Output : E0, E1, E2 / E4, E5, E6, E7

'FW > STM32' 카테고리의 다른 글

06-1_PWM : Timer 을 이용한 PWM  (1) 2023.02.21
05_EXTI (외부인터럽트)  (3) 2023.02.21
04_Timer_Interrupt  (1) 2023.02.21
02_UART  (0) 2023.02.21
01_GPIO  (0) 2023.02.21

+ Recent posts