Home > Study > C Language > ARM System Programming > [ex44] #6 PWM 기반 LED 밝기 제어 및 멜로디 연주 통합 실습

[ex44] #6 PWM 기반 LED 밝기 제어 및 멜로디 연주 통합 실습
Study Language

문제 설명


PWM을 이용해 LED 밝기를 제어하고, 동시에 미리 정의된 음계 배열(song1)에 따라 부저로 음악을 연주하는 프로그램을 작성하라.

  • TIM4는 PWM 출력을 생성하며, UART로 입력된 값(1~9)에 따라 듀티비를 조절해 LED 밝기를 변경
  • 입력값 0이 들어오면 PWM 출력을 중단하여 LED를 끔
  • TIM3과 TIM2를 이용해 음계 주파수와 음표 길이에 따라 멜로디를 반복 재생
  • 연주되는 음은 UART를 통해 음계 이름으로 출력됨

정답 코드


#include "device_driver.h"

#define BASE  (500)

static void Buzzer_Beep(unsigned char tone, int duration)
{
   const static unsigned short tone_value[] = {
      261,277,293,311,329,349,369,391,415,440,466,493,
      523,554,587,622,659,698,739,783,830,880,932,987
   };

   TIM3_Out_Freq_Generation(tone_value[tone]);
   TIM2_Delay(duration - 20);
   TIM3_Out_Stop();
   TIM2_Delay(20);
}

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

void Main(void)
{
   Sys_Init();
   TIM4_Out_Init();
   TIM4_Out_Freq_Generation(1000, 0);
   TIM3_Out_Init();

   Uart1_Printf("HomeWork (Verilog 6)\n");

   char x;
   int i = 0;
   int state = 0;

   enum key {
      C1, C1_, D1, D1_, E1, F1, F1_, G1, G1_, A1, A1_, B1,
      C2, C2_, D2, D2_, E2, F2, F2_, G2, G2_, A2, A2_, B2
   };
   enum note { N16 = BASE/4, N8 = BASE/2, N4 = BASE, N2 = BASE*2, N1 = BASE*4 };

   const int song1[][2] = {
      {G1,N4},{G1,N4},{E1,N8},{F1,N8},{G1,N4},
      {A1,N4},{A1,N4},{G1,N2},{G1,N4},{C2,N4},
      {E2,N4},{D2,N8},{C2,N8},{D2,N2}
   };

   const char * note_name[] = {
      "C1", "C1#", "D1", "D1#", "E1", "F1", "F1#", "G1", "G1#", "A1", "A1#", "B1",
      "C2", "C2#", "D2", "D2#", "E2", "F2", "F2#", "G2", "G2#", "A2", "A2#", "B2"
   };

   for(;;)
   {
      if(i == sizeof(song1)/ sizeof(song1[0])){
         i = 0;
      }

      if(state == 0)
      {
         x = Uart1_Get_Pressed();
         if (x != 0)
         {
            Uart1_Printf("Input: %d\n", x - '0');
            if (x == '0') {
               TIM4->CCR3 = TIM4->ARR;
            } else {
               TIM4_Change_Duty_Rate(x - '0');
            }
         }
      }
      
      Uart1_Printf("%s ", note_name[song1[i][0]]);
      Buzzer_Beep(song1[i][0], song1[i][1]);
      i++;     
   }
}

메모


printf 내부의 \n 습관화 필요