이전 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);
으로 코드 작성합니다.

  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);

}

+ Recent posts