Home > Study > C Language > ARM System Programming > [ex43] #5 UART 입력 기반 PWM LED 밝기 제어 실습

[ex43] #5 UART 입력 기반 PWM LED 밝기 제어 실습
Study Language

문제 설명


TIM4 타이머를 이용하여 PWM 신호를 생성하고, UART로 입력된 숫자(0~9)에 따라 LED 밝기를 제어하는 프로그램을 작성하라.

  • TIM4 채널을 사용하여 PWM 파형 출력
  • 입력값 1~9는 듀티비로 적용되어 LED 밝기를 변경
  • 입력값 0은 PWM 출력을 정지시켜 LED를 끔
  • UART 입력을 통해 사용자와 상호작용하며, 현재 입력값을 UART로 다시 출력함

정답 코드


// timer.c
#define TIM4_FREQ            (1000000)             // 1MHz
#define TIM4_TICK           (1000000/TIM4_FREQ)   // usec
#define TIME4_PLS_OF_1ms     (1000/TIM4_TICK)


void TIM4_Out_Init(void)
{
   Macro_Set_Bit(RCC->APB1ENR, 2); // tim4
   Macro_Set_Bit(RCC->APB2ENR, 3); // b port

   Macro_Write_Block(GPIOB->CRH, 0xF, 0xE, 0); //1110 open drain
   Macro_Write_Block(TIM4->CCMR2, 0xFF, 0x68, 0);

   TIM4->CCER = (0<<9)|(1<<8);
}

void TIM4_Out_PWM_Generation(unsigned int freq, unsigned int duty)
{
   // Down Counter, Repeat Mode
   TIM4->CR1 = (1<<4)|(0<<3);

   // Timer 주파수가 TIM4_FREQ가 되도록 PSC 설정
   TIM4->PSC = (unsigned int)((TIMXCLK / (double)TIM4_FREQ) + 0.5) - 1; // 1KHz

   // 요청한 주파수가 되도록 ARR 설정
   TIM4->ARR = (int)((double)TIM4_FREQ/freq + 0.5) - 1;

   // Duty Rate 50%가 되도록 CCR3 설정
   TIM4->CCR3 = (int)(TIM4->ARR * (duty / 10.));

   // Manual Update(UG 발생)
   Macro_Set_Bit(TIM4->EGR, 0);

   // Timer Start
   Macro_Set_Bit(TIM4->CR1, 0);
}

void TIM4_Out_Stop(void)
{
   Macro_Clear_Bit(TIM4->CR1, 0);
}

void TIM4_Change_Duty(unsigned int duty)
{
   TIM4->CCR3 = (int)(TIM4->ARR * (duty / 10.));
}

// main.c
#include "device_driver.h"

static void Sys_Init(void)
{
   Clock_Init();
   LED_Init();
   Uart_Init(115200);
   Key_Poll_Init();
}
void Main(void)
{
   Sys_Init();
   TIM4_Out_Init();

   char x;
   int timer_run = 0;

   TIM4_Out_PWM_Generation(1000, 0);
   
   for(;;)
   {
      x = Uart1_Get_Pressed();
      if (x != 0)
      {
         int n = x - '0';
         Uart1_Printf("%d", n);

         if (n == 0)
         {
            TIM4_Out_Stop();
            timer_run = 0;
         }
         else
         {
            if (timer_run == 0)
            {
               TIM4_Out_PWM_Generation(1000, n);
               timer_run = 1;
            }
            else
                {
                    TIM4_Change_Duty(n);
                }
         }
      }
   }
}

메모


printf 내부의 \n 습관화 필요