range는 0x20(32)가 기본이고 32bit까지 사용가능(int)
"PWM_RNG1의 값이 32보다 적다면, 처음 PWM_RNG의 첫번째 비트가 잘려진 비트가 전송되어진다. 만약 32를 넘는 경우 초과된 0 비트는 데이터의 끝에서 부터 붙여진다. 기본값은 32이다."
If the value in PWM_RNGi is less than 32, only the first PWM_RNGi bits are sent resulting in a truncation. If it is larger than 32 excess zero bits are padded at the end of data. Default value for this register is 32.
번역하려고 해도 무슨 의미인지 모르겠네 -_-
32 미만은 LSB가 0으로 보내진다는건가? (즉, 짝수로만 셋팅가능?)
그리고 32 이상은 초과된 0비트에 대해서 끝으로 부터 붙는다는건.. 32 이상에 대해서는 32의 배수로만 적용이 가능하거나 승수로만 가능하다는건가? (예를들어 36이라던가 이런식은 설정 불가)
그리고 클럭은... 기본이 100MHz 이지만 다양하게 들어올 수 있다 정도?
음.. range는 그냥 넣고.. 하드웨어적으로 자르고
클럭은.. int로 받지만 실제로는 12비트만 사용이 가능하고(즉,, 0~4095)
기본값 내용이 없는지라..
void pwmSetRange (unsigned int range) { if ((wiringPiMode == WPI_MODE_PINS) || (wiringPiMode == WPI_MODE_PHYS) || (wiringPiMode == WPI_MODE_GPIO)) { *(pwm + PWM0_RANGE) = range ; delayMicroseconds (10) ; *(pwm + PWM1_RANGE) = range ; delayMicroseconds (10) ; } }
void pwmSetClock (int divisor) { uint32_t pwm_control ; divisor &= 4095 ;
if ((wiringPiMode == WPI_MODE_PINS) || (wiringPiMode == WPI_MODE_PHYS) || (wiringPiMode == WPI_MODE_GPIO)) { if (wiringPiDebug) printf ("Setting to: %d. Current: 0x%08X\n", divisor, *(clk + PWMCLK_DIV)) ;
pwm_control = *(pwm + PWM_CONTROL) ; // preserve PWM_CONTROL
// We need to stop PWM prior to stopping PWM clock in MS mode otherwise BUSY // stays high.
*(pwm + PWM_CONTROL) = 0 ; // Stop PWM
// Stop PWM clock before changing divisor. The delay after this does need to // this big (95uS occasionally fails, 100uS OK), it's almost as though the BUSY // flag is not working properly in balanced mode. Without the delay when DIV is // adjusted the clock sometimes switches to very slow, once slow further DIV // adjustments do nothing and it's difficult to get out of this mode.
*(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x01 ; // Stop PWM Clock delayMicroseconds (110) ; // prevents clock going sloooow
while ((*(clk + PWMCLK_CNTL) & 0x80) != 0) // Wait for clock to be !BUSY delayMicroseconds (1) ;
*(clk + PWMCLK_DIV) = BCM_PASSWORD | (divisor << 12) ;
*(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x11 ; // Start PWM clock *(pwm + PWM_CONTROL) = pwm_control ; // restore PWM_CONTROL
if (wiringPiDebug) printf ("Set to: %d. Now : 0x%08X\n", divisor, *(clk + PWMCLK_DIV)) ; } } |
[링크 : http://www.farnell.com/datasheets/1521578.pdf]
2015/10/16 - [개소리 왈왈/라즈베리 파이(rpi)] - bcm2835 pwm 데이터시트
2015/10/16 - [개소리 왈왈/라즈베리 파이(rpi)] - wiringpi pwm 라이브러리 분석?
2015/10/14 - [개소리 왈왈/라즈베리 파이(rpi)] - 라즈베리 파이 GPIO 유틸 PWM
The Raspberry Pi PWM clock has a base frequency of 19.2 MHz. This frequency, divided by the argument to pwmSetClock(), is the frequency at which the PWM counter is incremented. When the counter reaches a value equal to the specified range, it resets to zero. While the counter is less than the specified duty cycle, the output is high, otherwise the output is low.
This means, if you want to set the PWM to have a specific frequency, you can use the following relationship:
pwmFrequency in Hz = 19.2e6 Hz / pwmClock / pwmRange.
pwmSetClock(1); -> 2.342kHz
pwmSetClock(2); -> 4.81MHz
pwmSetClock(3); -> 3.19MHz
pwmSetClock(4); -> 2.398MHz
pwmSetClock(5); -> 1.919MHz
pwmSetClock(6); -> 1.6MHz
pwmSetClock(7); -> 1.3MHz
pwmSetClock(8); -> 1.2MHz
pwmSetClock(9); -> 1.067MHz
pwmSetClock(10); -> 959kHz
pwmSetClock(11); -> 871kHz
pwmSetClock(20); -> 480kHz
pwmSetClock(200); -> 48kHz
pwmSetClock(500); -> 19kHz
pwmSetClock(1000); -> 9.59kHz
pwmSetClock(2000); -> 4.802kHz
pwmSetClock(4000); -> 2.401kHz
pwmSetClock(5000); -> 10.58kHz
[링크 : http://raspberrypi.stackexchange.com/questions/4906/control-hardware-pwm-frequency]
음.. pwmc에 100 넣으면 1/100 으로 DIV 되서 1Mhz 로 작동해야 하는데.. 위에 실험은 출력이 달라서 그럴려나?
#define PWMCTL (*(volatile uint32_t *)0x2020c000)
#define PWMSTA (*(volatile uint32_t *)0x2020c004)
#define PWMDMAC (*(volatile uint32_t *)0x2020c008)
#define PWMRNG1 (*(volatile uint32_t *)0x2020c010)
#define PWMDAT1 (*(volatile uint32_t *)0x2020c014)
#define PWMFIF1 (*(volatile uint32_t *)0x2020c018)
#define PWMRNG2 (*(volatile uint32_t *)0x2020c020)
#define PWMDAT2 (*(volatile uint32_t *)0x2020c024)
#define CM_PWMCTL (*(volatile uint32_t *)0x201010a0)
#define CM_PWMDIV (*(volatile uint32_t *)0x201010a4)
[링크 : https://www.raspberrypi.org/forums/viewtopic.php?t=37770]