이전 4번 게시글 코드를 이용해, LED 만 부저로 바꿔 연결하여 구현합니다.
Key가 눌리면, 도->레->미->...->도로 변경과 동시에 'do','re'와 같이 어떤 음으로 바뀌는지 uart 시리얼 포트로 출력합니다.
음계 말고 이하 동일입니다.
음계 설정 하기
HCLK : 168000000Hz
1.Timer 9의 PSC,ARR,CCR1 설정
ARR값을 계속 변경하며 사용하니,
PSC로 식을 만들기 간단하도록 500000으로 스케일링 할 것입니다.
-예를 들어 계이름 '도'(523Hz)를 만든다면.
1) 168000000/(PSC+1)=500000, PSC=>336-1
2) 500000/(ARR+1)=523, ARR=>956-1
=>식으로 여러 음 번갈아 넣으려면
ARR=500000/((해당음의 Hz)-1);
으로 코드 작성합니다.
- CCR은 항상 50%로 합니다. ARR/2
-

계이름을 참고해 int buzzerHZ[8]={130,146,164,174,195,220,246,261};
도레미파솔라시도 리스트를 만들어 사용합니다.
Key가 눌리면, 도->레->미->...->도로 변경과 동시에 'do','re'와 같이 어떤 음으로 바뀌는지 uart 시리얼 포트로 출력합니다.
void USART3_Init(void)
{
RCC->AHB1ENR |= 1<<3;// GPIOD 클럭 활성화
RCC->APB1ENR |= 1<<18;//USART3
//PD8,9핀 Alternative Function으로 설정
GPIOD->MODER &= ~((0x3 << (2 * 8)) | (0x3 << (2 * 9)));
GPIOD->MODER |= ((0x2 << (2 * 8)) | (0x2 << (2 * 9)));
//MUX AFR uart tx,rx핀으로 설정
GPIOD->AFR[1]&= ~(0xf<<4 | 0xf<<0);//MUX PD8,9(AFRH 8~15)
GPIOD->AFR[1] |= (0x7<<4 | 0x7<<0);//uart3(AF7)
//uart 레지스터 설정
USART3->CR1 = (1<<13 | 1<<3 | 1<<2);//UE,TE,RE
USART3->BRR = (22 << 4) | 13; //115200bps,42MHZ =356
}
void UART3_Send(char c){
while(!(USART3->SR>>7 & 0x1));
USART3->DR=c;
}
void UART3_Print(const char* str){
while(*str){
UART3_Send(*str++);
}
}
void EXTI_KEY_Init(void){
RCC->AHB1ENR |= (0x1 << 2); // GPIOC
GPIOC->MODER &= ~(0x3 << (2 * 13)); // PC13: 입력 모드
RCC->APB2ENR |= (1<<14);//SYSCFG
SYSCFG->EXTICR[3]&= ~(0xF <<4);
SYSCFG->EXTICR[3]|=(0x2<<4);//SYSCFG_EXTICR4(Port C)
EXTI->IMR |=(1<<13); //line13인터럽트 마스크
EXTI->RTSR |=(1<<13);//Rising edge
EXTI->PR = (1<<13);//pending (인터럽트 플래그 리셋.)
NVIC->ISER[1]|=0x1<<8;
}
int cnt=0;
int id_cnt=0;
//int ledtime[4]={20000, 10000, 5000, 2500};//1 0.5 0.25 0.125
int buzzerHZ[8]={130,146,164,174,195,220,246,261};
char msg[100];
char* HZname[8]={"do","re","mi","pa","sol","ra","si","do"};
//523:도,130:도
void EXTI15_10_IRQHandler(void)
{
if(EXTI->PR & (0x1<<13)){
EXTI->PR = (0x1<<13);//pending bit 클리어
++cnt;
if(cnt%5==0){
// TIM9->ARR=ledtime[(++id_cnt)%4]-1;
TIM9->ARR=50000/(buzzerHZ[(++id_cnt)%8])-1;
TIM9->CCR1=(TIM9->ARR+1)/2;
sprintf(msg,"%s\r\n",HZname[id_cnt%8]);
UART3_Print(msg);
}}
}
void TIM9_Init(void){
RCC->AHB1ENR |= 1<<4;//GPIOE PE5
GPIOE->MODER &= ~(0x3<<(5*2));
GPIOE->MODER |= (0x2<<(5*2));//AF
GPIOE->AFR[0] &= ~(0xf<<20);//MUX PE5
GPIOE->AFR[0] |= (0x3<<20);//AF3
RCC->APB2ENR |= 1<<16;//TIM9 clock
TIM9->CR1= 0x0<<0;
TIM9->PSC=336-1;//50000
TIM9->ARR=956-1;//523
TIM9->CCR1 = (TIM9->ARR)/2; // duty : 50%
TIM9->CCMR1 |= 0x6<<4;//pwm 1 mode
TIM9->CCER|=0x1;//output channel1
// 타이머 시작
TIM9->CR1 |= (1 << 0);
}
int main(void)
{
HAL_Init();
EXTI_KEY_Init();
USART3_Init();
TIM9_Init();
SystemClock_Config();
while (1);
}
'Cortex-M' 카테고리의 다른 글
| 펌웨어 기본 동작 구현4-TIM9 PWM 출력으로 LED ON/OFF, 키 누른 회수에 따라 LED 주기 변경 (0) | 2025.05.25 |
|---|---|
| 펌웨어 기본 동작 구현 3 - 시리얼 포트로 문자열 입출력, LED 주기 변경 | Nucleo-STMF429ZI (0) | 2025.05.25 |
| 펌웨어 기본 동작 구현2- Timer활용하여 1초 주기로 LED토글 (0) | 2025.05.25 |
| 펌웨어 기본 동작 구현1- Key 입력 시 눌린 순서 번호+문장 UART출력 | STM32CubeIDE ,STM32F429ZI (0) | 2025.05.25 |
| TIM9 구조와 활용, 익셉션(인터럽트)활용, PWM 파형 출력 (로직 애널라이저) (0) | 2025.05.25 |














)























































































