레지스터 설정
PWM Mode Register
Register Name: PWM_MR
PREB = 1024
DIVB = 128
정도 하면 mck 가 48Mhz 임으로 0.043690667 마나 1번씩 가득찬다.
PWM Enable Register
Register Name: PWM_ENA
PWM_ENA = 0x01
CHID0 ,사용
PWM Interrupt Enable Register
Register Name: PWM_IER
PWM_IER = 0x01
CHID0 인터럽트 허용
PWM Channel Mode Register
Register Name: PWM_CMRx
CALG = 0 : 왼쪽정렬
CPOL = 0 : 출력은 0 에서 시작
PWM Channel Duty Cycle Register
Register Name: PWM_CDTYx
Only the first 16 bits (internal channel counter size) are significant.
- PWM_CDTYx 는 32bit 이지만 내부 카운터가 16bit 짜리라서 앞에 16bit 만 의미를 가진다.
PWM Channel Period Register
Register Name: PWM_CPRDx
Only the first 16 bits (internal channel counter size) are significant.
- PWM_CPRDx 는 32bit 이지만 내부 카운터가 16bit 짜리라서 앞에 16bit 만 의미를 가진다.
pin 설정
PWM0 는 Peripheral B 이다.
pin 예제를 보면 Line 20 ~ 23 번이 Peripheral B 를 사용하고 있다. 때문에 예시의 빨간 네모 안이 F 인 레지스터를 set 해주면 pin 출력 준비가 완료 된다.
PIO_PDR
PIO_ODR
PIO_IFDR
PIO_CODR
PIO_MDDR
PIO_PUDR
PIO_BSR
PIO_OWDR
#include <AT91SAM7S256.h>
#define BOARD_MCK 48000000
AT91S_PWMC* AT91PS_PWMC1 = (AT91S_PWMC*)0xFFFCC000;
AT91S_PWMC_CH* AT91PS_PWMC_CH0 = (AT91S_PWMC_CH*)0xFFFCC200;
void UTIL_Loop(unsigned int loop)
{
while (loop--);
}
void UTIL_WaitTimeInMs(unsigned int mck, unsigned int time_ms)
{
register unsigned int i = 0;
i = (mck / 1000) * time_ms;
i = i / 3;
UTIL_Loop(i);
}
void Pwm_Init(void)
{
*AT91C_PMC_PCER = 1 << AT91C_ID_PWMC; // PWM 장치에 클럭 공급
// pin setting
*AT91C_PIOA_PDR = 1;
*AT91C_PIOA_ODR = 1;
*AT91C_PIOA_IFDR = 1;
*AT91C_PIOA_CODR = 1;
*AT91C_PIOA_MDDR = 1;
*AT91C_PIOA_PPUDR = 1;
*AT91C_PIOA_ASR = 1;
*AT91C_PIOA_OWDR = 1;
// CLKA 를 200kHz로 설정 48Mhz / 8 / 30
*AT91C_PWMC_MR = (30 << 0) | (3 << 8);
AT91PS_PWMC_CH0->PWMC_CPRDR = 600;
// CLKA 클럭을 사용, left aligned, low level start, CUPD modify duty cycle
// clkA 사용 , 왼쪽 정렬, low level 시작 , duty update
*AT91C_PWMC_CH0_CMR = 11 & (~(0x1 << 8)) & (~(0x1 << 9)) & (~(0x1 << 10));
AT91PS_PWMC_CH0->PWMC_CDTYR = 2;
return;
}
int main(void)
{
//volatile unsigned int delay;
//int Num = 1;
Pwm_Init();
// pwm 시작
AT91PS_PWMC1->PWMC_ENA = 0x01;
while (1)
{
*AT91C_PWMC_CH0_CMR &= (~(0x1 << 10));
AT91PS_PWMC_CH0->PWMC_CDTYR = 2;
UTIL_WaitTimeInMs(BOARD_MCK, 10000);
*AT91C_PWMC_CH0_CMR &= (~(0x1 << 10));
AT91PS_PWMC_CH0->PWMC_CDTYR = 599;
}
return 0;
}
#include <AT91SAM7S256.h>
#define BOARD_MCK 48000000
// my pwm
AT91S_PWMC* AT91PS_PWMC1 = (AT91S_PWMC*)0xFFFCC000;
AT91S_PWMC_CH* AT91PS_PWMC_CH0 = (AT91S_PWMC_CH*)0xFFFCC200;
AT91S_PWMC_CH* AT91PS_PWMC_CH1 = (AT91S_PWMC_CH*)0xFFFCC220;
void UTIL_Loop(unsigned int loop)
{
while (loop--);
}
void UTIL_WaitTimeInMs(unsigned int mck, unsigned int time_ms)
{
register unsigned int i = 0;
i = (mck / 1000) * time_ms;
i = i / 3;
UTIL_Loop(i);
}
void Pwm_Init(void)
{
*AT91C_PMC_PCER = 1 << AT91C_ID_PWMC; // PWM 장치에 클럭 공급
// pin setting
*AT91C_PIOA_PDR = 1|(1<<1);
//*AT91C_PIOA_ODR = 1;
*AT91C_PIOA_IFDR = 1 | (1 << 1);
//*AT91C_PIOA_CODR = 1;
//*AT91C_PIOA_MDDR = 1;
*AT91C_PIOA_PPUDR = 1 | (1 << 1);
*AT91C_PIOA_ASR = 1| (1 << 1);
//*AT91C_PIOA_OWDR = 1;
// CLKA 를 200kHz로 설정 48Mhz / 8 / 30
*AT91C_PWMC_MR = (30 << 0) | (3 << 8);
// ch 0 설정
AT91PS_PWMC_CH0->PWMC_CPRDR = (unsigned short)600;
// CLKA 클럭을 사용, left aligned, low level start, CUPD modify duty cycle
// clkA 사용 , 왼쪽 정렬, low level 시작 , duty update
*AT91C_PWMC_CH0_CMR = 11 & (~(0x1 << 8)) & (~(0x1 << 9)) & (~(0x1 << 10));
AT91PS_PWMC_CH0->PWMC_CDTYR = (unsigned short)598;
// ch 1 설정
AT91PS_PWMC_CH1->PWMC_CPRDR = (unsigned short)600;
// CLKA 클럭을 사용, left aligned, low level start, CUPD modify duty cycle
// clkA 사용 , 왼쪽 정렬, low level 시작 , duty update
*AT91C_PWMC_CH1_CMR = 11 & (~(0x1 << 8)) & (~(0x1 << 9)) & (~(0x1 << 10));
AT91PS_PWMC_CH1->PWMC_CDTYR = (unsigned short)2;
return;
}
int main(void)
{
//volatile unsigned int delay;
//int Num = 1;
Pwm_Init();
// pwm 시작
AT91PS_PWMC1->PWMC_ENA = 0x01;
while (1)
{
//*AT91C_PWMC_CH0_CMR &= (~(0x1 << 10));
//AT91PS_PWMC_CH0->PWMC_CDTYR = 2;
//UTIL_WaitTimeInMs(BOARD_MCK, 1000);
//*AT91C_PWMC_CH0_CMR &= (~(0x1 << 10));
//AT91PS_PWMC_CH0->PWMC_CDTYR = 599;
//UTIL_WaitTimeInMs(BOARD_MCK, 1000);
}
return 0;
}
'공부,일 > Arm' 카테고리의 다른 글
jtag 사용하기 (0) | 2021.10.05 |
---|---|
GPIO 다루기 (0) | 2021.09.06 |
pwm datasheet 분석 (0) | 2021.09.06 |
mamory map & LED 켜기 (0) | 2021.09.06 |
uart (0) | 2021.09.02 |
댓글