질문게시판 > 답변 : ATMEGA128 노래 속도

인기검색어 > 아두이노 센서 ATMEGA128

최신글 질문게시판 동영상강좌 가입하기

▼ BASIC4MCU 후원업체 신제품 정보 ▼

▲ BASIC4MCU 후원업체 신제품 정보 ▲

BASIC4MCU > 질문게시판

답변 : ATMEGA128 노래 속도

페이지 정보

작성자 master 작성일19-12-14 20:54 조회4,056회 댓글0건

본문

 

// DateTime : 2019-12-14 오후 8:54:18
// by Ok-Hyun Park
//
#include <io.h>
//
typedef enum{
  la_0,lasharp_0,si_0,do_1,dosharp_1,re_1,resharp_1,mi_1,fa_1,fasharp_1,sol_1,solsharp_1,la_1,lasharp_1,
  si_1,do_2,dosharp_2,re_2,resharp_2,mi_2,fa_2,fasharp_2,sol_2,solsharp_2,la_2,lasharp_2,si_2,do_3,dosharp_3,
  re_3,resharp_3,mi_3,fa_3,fasharp_3,sol_3,solsharp_3,la_3,lasharp_3,si_3,rest
}melody_code;
//
typedef struct{
  melody_code     tone;
  float           leng;
}MUSIC_CODE;
//
#define LENGTH  39
//
flash MUSIC_CODE musicCode1[]={
  { do_2,1},{ do_2,0.5},{ do_2,0.5},{ do_2,1},{ do_2,1},//곰세마리가
  { mi_2,1},{ sol_2,0.5},{ sol_2,0.5},{ mi_2,1},{ do_2,1},//한 집에 있어
  { sol_2,0.5},{ sol_2,0.5},{ mi_2,1},{ sol_2,0.5},{ sol_2,0.5},{ mi_2,1},{ do_2,1},{ do_2,1},{ do_2,2},// 아빠곰 엄마곰 애기곰
  { sol_2,1},{ sol_2,1},{ mi_2,1},{ do_2,1},{ sol_2,1},{ sol_2,1},{ sol_2,2},//아빠곰은 뚱뚱해
  { sol_2,1},{ sol_2,1},{ mi_2,1},{ do_2,1},{ sol_2,1},{ sol_2,1},{ sol_2,2},//엄마곰은 날씬해
  { sol_2,1},{ sol_2,1},{ mi_2,1},{ do_2,1},{ sol_2,0.5},{ sol_2,0.5},{ sol_2,0.5},{ la_2,0.5},{ sol_2,2},//애기곰은 너무귀여워
  { do_3,1},{ sol_2,1},{ do_3,1},{ sol_2,1},{ mi_2,1},{ re_2,1},{ do_2,2//으쓱 으쓱 잘한다
  { 0,0}
};
int a=0;
int baseToneStep[8]={0,2,3,5,7,8,10,12};
//
#define LA_FREQ  110.
#define MULTIPLICATION_FACTOR   1.059463
//
unsigned int cs[8]={0,1,8,32,64,128,256,1024};
//
unsigned char  tccr0_set[LENGTH]; // tone을 만들기 위한 TCCR0 값
unsigned char  ocr0_set[LENGTH];  // tone을 만들기 위한 OCR0 값
unsigned char  i;
unsigned int   us;
unsigned long  time10Millisec;
unsigned char  fndDispHoldVal[4]={ 1,2,3,4};
unsigned char  fndHexCode[16]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x27,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};
//
interrupt[TIM1_COMPA]void Timer1A_cmp_isr(void){++time10Millisec; }
//
void StartTimer(){
  time10Millisec=0TCNT1=0TIFR=(1<<OCF1A); TIMSK|=(1<<OCIE1A); TCCR1B|=(1<<CS10); TCCR1B|=(1<<CS11);
}
//
void StopTimer(){ TIMSK&=~(1<<OCIE1A); TCCR1B&=~(1<<CS10); TCCR1B&=~(1<<CS11); }
//
void RestartTimer(){ TIMSK|=(1<<OCIE1A); TCCR1B|=(1<<CS10); TCCR1B|=(1<<CS11); }
//---------------------------------------------------------
//    음계 ‘라’로 부터 3 옥타브에 걸친 음의 tone을 만들기 위하여 필요한
//    타이머 0의 clock selection 필드 값과 OCR0 값을 미리 준비해 둠
//---------------------------------------------------------
void MakeTone(){
  float   reqFreq,num,freq,reqClksint     i,j,steps;
  reqFreq=LA_FREQ// ‘라’ 음의 기준 주파수로 부터 시작함.
  for(i=0i<LENGTHi++){ // 24개 tone
    reqFreq=LA_FREQ;
    // 기준 주파수로 부터 몇 단계 떨어져 있는가?
    steps=i;
    // tone의 주파수 계산
    for(j=0j<stepsj++)
    reqFreq*=MULTIPLICATION_FACTOR;
    freq=reqFreq*2// toggle 함에 따라서 카운터 주파수는 2배가 되어야 함
    // 한 개의 주기에 16MHz 클럭이 몇 개가 있느가?
    reqClks=(16.0E6/freq);
    // 가능한 최대 크기의 OCR0 값을 만들 수 있도록 clock selection 선택
    for(j=1j<8j++){ // 각 prescale 에 대해
      num=reqClks /((float)cs[j]);
      if(num<=256.){ tccr0_set[i]=j|0b00011000ocr0_set[i]=((unsigned char)num)-1break; } // CTC 모드에서 toggle 출력 // TCCR0 값 찾기 // OCR0 값 찾기
    }
  }
}
//---------------------------------------------------------
//    실제 음 tone을 만들기 위하여,TCCR0와 OCR0 에 갓을 써 넣음
//---------------------------------------------------------/
void SetTone(unsigned char n){ TCCR0=tccr0_set[n]; OCR0=ocr0_set[n]; DDRB.4=1; } // 부저에 연결된 핀을 출력으로
//---------------------------------------------------------
//    100 millisec 마다 CTC 인터럽트가 발생하도록 함.
//---------------------------------------------------------/
void InitTimer3(){
  TCCR3B=(1<<WGM32)|(1<<CS31);        // CTC mode // 1/8
  OCR3AH=19999>>8OCR3AL=19999&0xFF// OCR3A=19999
  ETIFR=(1<<OCF3A);                   // ETIFR의 OCF3A(비교일치 flag)을 클리어시킴
  ETIMSK|=(1<<OCIE3A);                // 비교 일치 인터럽트 enable
}
//
void ReSetTimer3(int a){
  switch(a){
    case 0OCR3AH=19999>>8OCR3AL=19999&0xFFbreak;
    case 1OCR3AH9999>>8OCR3AL9999&0xFFbreak;
    case 2OCR3AH6666>>8OCR3AL6666&0xFFbreak;
  }
}
//---------------------------------------------------------
//    타이머 3의 ISR,100 millisec 마다,시간변수 increment
//---------------------------------------------------------
unsigned char timer3Flag;
unsigned int  remainCnt;
int           seq;
//
interrupt[TIM3_COMPA]void Timer3A_cmp_isr(void){ timer3Flag++; } // 100 msec interval
//---------------------------------------------------------
//    SW1 누르면 플레이 시작
//---------------------------------------------------------
interrupt[EXT_INT4]void ext4_isr(){
  if(++a>2)a=0;
  if(a==0){ PORTA=0xC2;  }
  if(a==1){ PORTA=0x92remainCnt=1seq=0StartTimer(); DDRB.4=1; }
  if(a==2){ PORTA=0xA2; }
  ReSetTimer3(a);
}
//---------------------------------------------------------
//    SW2 누르면 중단
//---------------------------------------------------------
interrupt[EXT_INT5]void ext5_isr(){
  if(++a>3)a=0;
  if(a==0){ PORTA=0x92; }
  if(a==1){ PORTA=0x94; }
  if(a==2){ remainCnt=0PORTA=0x98DDRB.4=0StopTimer();    }
  if(a==3){ remainCnt=1PORTA=0x91DDRB.4=1RestartTimer(); }
}
//
void InitTimer1(){ TCCR1A=0TCCR1B=(1<<WGM12); OCR1A=24999; }
//
#define T2_OCR 16000000.*0.005/1024.
//
void Timer2Init(){ TCCR2=(1<<WGM21)|(1<<CS22)|(1<<CS20); OCR2=(unsigned char)(T2_OCR)-1TIMSK|=0x80; }
//
void InitFnd(){ DDRC=0xFFDDRG|=0x0FTimer2Init(); }
//
unsigned char fndOnVal[4]={0x01,0x02,0x04,0x08};
//
interrupt[TIM2_COMP]void Timer2_cmp_isr(void){
  static unsigned char currFndPos=0;
  PORTG=0x00;
  PORTC=fndDispHoldVal[currFndPos];
  if(currFndPos==1)PORTC|=0x80;
  PORTG=fndOnVal[currFndPos];
  currFndPos=(++currFndPos)%4;
}
//
void main(){
  DDRA=0xFF;
  InitFnd();
  MakeTone();
  InitTimer1();
  InitTimer3();
  EICRB=0x0A// falling edge에서 인터럽트 발생
  EIMSK=0x30// SW1,SW2 인터럽트 enable
  SREG|=0x80// 전체 인터럽트 enable
  while(1){
    if(timer3Flag){ timer3Flag=0// every 100 millisec
      if(remainCnt){
        if     (remainCnt==10){ DDRB.4=0; } // 끝나기 0.1 sec 전에 음 제거
        else if(remainCnt== 1){
          if(musicCode1[seq].leng!=0.0){
            SetTone(musicCode1[seq].tone);
            remainCnt=(unsigned int)(musicCode1[seq].leng*100.);
            ++seq;
          }
        }
      }
      --remainCnt;
      us=time10Millisec;
      for(i=0i<4i++){ fndDispHoldVal[i]=fndHexCode[us%10]; us=us/10; }
    }
  }
}

 

//
void ReSetTimer3(int a){
  switch(a){
    case 0OCR3AH=19999>>8OCR3AL=19999&0xFFbreak;
    case 1OCR3AH9999>>8OCR3AL9999&0xFFbreak;
    case 2OCR3AH6666>>8OCR3AL6666&0xFFbreak;
  }
}

 

  • BASIC4MCU 작성글 SNS에 공유하기
  • 페이스북으로 보내기
  • 트위터로 보내기
  • 구글플러스로 보내기
  • 카카오톡으로 보내기

댓글 : 0

조회수 : 4,056

등록된 댓글이 없습니다.

게시물 검색

BASIC4MCU > 질문게시판 목록

제목 날짜
공지 MCU, AVR, 아두이노 등 전자공학에 관련된 질문은… 스태프  19-01-15
공지 사이트 이용 안내 댓글[25] master  17-10-29
질문 아두이노 센서값 출력 질문입니다! 아궁2 새글 22-06-24
질문 ATmega128, ATmega28 RS232통신 첨부파일Moon4201 새글 22-06-24
질문 서보모터, 온습도센서 코드 질문 댓글[2] 첨부파일kshdlfaldfh  22-06-22
답변 답변 : 서보모터, 온습도센서 코드 질문 댓글[15] master  22-06-22
질문 steppermulti5 질문 응애  22-06-21
답변 답변 : steppermulti5 질문 댓글[1] master  22-06-22
질문 atmega128 avr usart 질문 snoflak  22-06-21
답변 답변 : atmega128 avr usart 질문 댓글[5] master  22-06-21
질문 사용자 정의 함수 변환 하는 방법 댓글[2] 첨부파일da0800  22-06-21
질문 atmega128 댓글[1] 양의노래  22-06-20
질문 아두이노 동시동작 재질문 댓글[9] 첨부파일죠르디  22-06-20
질문 초음파센서로 dc모터 제어하기 댓글[1] 첨부파일난쟁2  22-06-20
질문 아두이노 동시동작 댓글[7] 죠르디  22-06-19
질문 ATMEGA128 UART,FND 연동 질문 JMOD  22-06-19
답변 답변 : ATMEGA128 UART,FND 연동 질문 댓글[1] master  22-06-20
질문 atmeg128 질문이요 댓글[1] 첨부파일공대생er  22-06-18
질문 atmega128 초음파 센서로 신호등 시간초 늘리기 서동씨  22-06-18
답변 답변 : atmega128 초음파 센서로 신호등 시간초… 댓글[1] master  22-06-18
질문 atmega128 댓글[2] 망경이  22-06-18
질문 앱인벤터 이용해서 수동 자동 할라고하는데 ..잘안됩니다… 댓글[1] 따랑해영  22-06-18
답변 질문 : 앱인벤터 이용해서 수동 자동 할라고하는데 ..… 댓글[1] 첨부파일따랑해영  22-06-19
답변 질문 : 앱인벤터 이용해서 수동 자동 할라고하는데 .… 첨부파일따랑해영  22-06-19
질문 서보모터와 초음파센서 댓글[1] 브링미히어  22-06-17
질문 LCD 도와주세요 ㅜㅠㅠㅠ 댓글[2] 첨부파일dentist22  22-06-17
질문 안녕하세요 atmega128 질문드리고 싶습니다. (자… 댓글[3] dlcldl  22-06-17
질문 아두이노 delay를 millis로 바꾸고 싶습니다. 슨슨슨모  22-06-16
답변 답변 : 아두이노 delay를 millis로 바꾸고 싶… master  22-06-17
질문 아두이노 LCD 시계 첨부파일dentist22  22-06-16
게시물 검색


Privacy Policy
MCU BASIC ⓒ 2017
PC버전