본문 바로가기
코스웨어/15년 스마트컨트롤러

20150947-13번-박서연 일일업무일지 - PWM, 스피커

by 알 수 없는 사용자 2015. 9. 14.
728x90
반응형

2015-09-14


*ARM (PWM)


#PWM 소스

pwm.h

 #ifndef __PWM_H__


#define __PWM_H__ 

#define DIVA    0
#define DIVB    16
#define PREA    8
#define PREB    24

#define MAX_DUTY    800
#define DEF_DUTY    100

void PWM2_Init(void);
void Set_Duty(int iDuty);

#endif  //end __PWM_H__


pwm.c

 #include <AT91SAM7S256.h>

#include <pwm.h>

void PWM2_Init(void// p35 - B 모드 - PA25 - PWM2
{
  *AT91C_PMC_PCER = 1<<AT91C_ID_PWMC;  //Peripheral Clock Enable Register //p34 // 전원 공급
  *AT91C_PIOA_PPUDR = AT91C_PA25_PWM2;  //Pull-up Disable Register // 풀업 X
  *AT91C_PIOA_PDR = AT91C_PA25_PWM2;    //PIO Disable Register // I/O X
  *AT91C_PIOA_BSR = AT91C_PA25_PWM2;    //PIO Peripheral B Select Register // B모드 선택 
  *AT91C_PWMC_MR = (30 << DIVA) |(30 << DIVB) |(3 << PREA) |(3 << PREB); // MCK(48000000)/PRE(8)/DIV(30)
  // (PWMC_CH2) Channel Mode Register 
  //            CPRE-주파수  최종 선택 | CALG-삼각파/톱니파  | CPOL-duty cycle start 1/0 | CPD-period / duty cycle
  *AT91C_PWMC_CH2_CMR = AT91C_PWMC_CPRE_MCKA &(~AT91C_PWMC_CALG)&(~AT91C_PWMC_CPOL)&(~AT91C_PWMC_CPD);

  //아래부터 2015-09-14 소스 
  *AT91C_PWMC_CH2_CPRDR = MAX_DUTY;  // 최대 16bit
  *AT91C_PWMC_CH2_CDTYR = DEF_DUTY;  // 최대 16bit
  *AT91C_PWMC_ENA = AT91C_PWMC_CHID2;  //PWM Enable
  return;
}

void Set_Duty( int iDuty)
{
  if(MAX_DUTY < iDuty)
  {
    iDuty = MAX_DUTY;
  }
  else if0 > iDuty)
  {
    iDuty = 0;
  }
  
  *AT91C_PWMC_CH2_CUPDR = iDuty;//PWM Channel Update Register - 동작중 변경시 다음 타이밍에 넣어줌 
  return;
}


main.c

 #include <project.h>


int main(void)

  unsigned char ucKey;
  int iDuty = DEF_DUTY;

  PWM2_Init();
  DBGU_Init();
    
  while(1)
  {
  
    ucKey = DBGU_RX();
    

    if('-' == ucKey)
    {
      iDuty -= 10;
      
    }
    else if('+' == ucKey)
    {
      iDuty += 10;
      
    }

    if(iDuty >= MAX_DUTY)
    {
      iDuty = MAX_DUTY;
    }
    else if(iDuty < 0)
    {
      iDuty = 0;
    }

    Set_Duty(iDuty);
    
    
  }
  
   return 0;
}


dbgu.c 살짝 수정

 void DBGU_Init(void)

{
  //DBGU_Init_ISR();
  DBGU_Init_Polling();
}
//인터럽트 방식이 아닌 폴링방식으로 




- CDTY레지스터는 초기화 할때만 세팅 할 수 있다. 그러므로 값을 변경하고 싶을 때에는 CUPD레지스터를 통해서 그 값을 변경 해주어야만 한다. 그 이유는 우리가 실행중에 CDTY 값을 변경하게 되면 위의 그래프가 깨질 가능성이 있으므로 CUPD레지스터에 값을 넣어주고 다음 주기에 변경된 값으로 PWM이 동작하게 하는 원리이다.


결과



#스피커

- 스피커 원리


납땜 해놓을것! 

ATmega책 704쪽(음계 발생원리 등등.... 뒤쪽으로 이론부분 읽어두기)



728x90