Home > Study > C Language > ARM System Programming > [ex45] #7 멜로디 반복 재생 및 UART 기반 LED PWM 제어 실습

[ex45] #7 멜로디 반복 재생 및 UART 기반 LED PWM 제어 실습
Study Language

문제 설명


부저를 통해 미리 정의된 멜로디(song1)를 반복 재생하고, UART 수신 인터럽트를 통해 LED 밝기를 실시간으로 제어하는 프로그램을 작성하라.

  • main 루프에서는 TIM3과 TIM2를 이용하여 음계 주파수 및 지속시간에 따라 멜로디를 재생
  • USART1 인터럽트에서 UART로 수신된 값(1~9)은 TIM4의 PWM 듀티비로 적용되어 LED 밝기를 조절
  • UART로 0이 입력되면 PWM 출력을 중단하여 LED를 끔
  • 멜로디 재생과 LED 제어는 독립적으로 동작

정답 코드


//stm32f10x_it.c 
void USART1_IRQHandler(void)
{
   unsigned char c = (unsigned char)USART1->DR;
   Uart1_Send_Byte(c);

   TIM4_Out_Init();

   static int timer_run = 0;

   int n = c - '0';

   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);
        }
   }
    NVIC_ClearPendingIRQ(37); 
}

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

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

   SCB->VTOR = 0x08003000;
   SCB->SHCSR = 0;
}

#define BASE  (500) //msec

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);
   TIM3_Out_Stop();
}

void Main(void)
{
   Sys_Init();

   // NVIC USART1 Pending clear
   NVIC_ClearPendingIRQ(37);
   // USART1 RX interrupt enable
   Macro_Set_Bit(USART1->CR1, 5);
   // NVIC USART1 interrupt enable
   NVIC_EnableIRQ(37);

   int i;

   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"};

   TIM3_Out_Init();

   Uart1_Printf("\nSong Play\n");

   for(;;)
   {
      for(i=0; i<(sizeof(song1)/sizeof(song1[0])); i++)
      {
         //Uart1_Printf("%s ", note_name[song1[i][0]]);
         Buzzer_Beep(song1[i][0], song1[i][1]);
      }
   }
}

메모


printf 내부의 \n 습관화 필요