문제 설명
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 습관화 필요