PWM控制参数寄存器结构图
备注:
- 标志位
PWM_CFG_ENALWAYS和PWM_CFG_ONESHOT的优先级顺序是en always高于one shot - 标志位
PWM_CFG_ZEROCMP必须置1 -
PWM占空比的计算比较复杂:
左对齐脉宽占空比中央对齐脉宽占空比
寄存器 PWM0_REG(PWM_S)、PWM0_REG(PWM_CMP0)~PWM0_REG(PWM_CMP3)
// 计数器
PWM0_REG(PWM_COUNT) = 0;
// CFG控制字
PWM0_REG(PWM_CFG) = 0;
PWM0_REG(PWM_CFG) = (PWM_CFG_ENALWAYS) | (PWM_CFG_ZEROCMP) | (PWM_CFG_DEGLITCH);
int main (void)
{
// 115200 Baud Rate at (65 / 2) MHz
//UART0_REG(UART_REG_DIV) = 282;
//UART0_REG(UART_REG_TXCTRL) = UART_TXEN;
//UART0_REG(UART_REG_RXCTRL) = UART_RXEN;
// Wait a bit because we were changing the GPIOs
volatile int i=0;
while(i < 10000){i++;}
//_puts(sifive_msg);
//_puts(welcome_msg);
uint16_t r=0x3F;
uint16_t g=0;
uint16_t b=0;
// Set up RGB PWM
PWM0_REG(PWM_CFG) = 0;
PWM0_REG(PWM_CFG) = (PWM_CFG_ENALWAYS) | (PWM_CFG_ZEROCMP) | (PWM_CFG_DEGLITCH);
PWM0_REG(PWM_COUNT) = 0;
// The LEDs are intentionally left somewhat dim.
PWM0_REG(PWM_CMP0) = 0xFE;
while(1){
volatile uint64_t * now = (volatile uint64_t*)(CLINT_CTRL_ADDR + CLINT_MTIME);
volatile uint64_t then = *now + 400;
while (*now < then) { }
if(r > 0 && b == 0){
r--;
g++;
}
if(g > 0 && r == 0){
g--;
b++;
}
if(b > 0 && g == 0){
r++;
b--;
}
PWM0_REG(PWM_CMP1) = 0xFF - (r >> 2);
PWM0_REG(PWM_CMP2) = 0xFF - (g >> 2);
PWM0_REG(PWM_CMP3) = 0xFF - (b >> 2);
}// While (1)
}
// See LICENSE for license details.
#ifndef _SIFIVE_PWM_H
#define _SIFIVE_PWM_H
/* Register offsets */
#define PWM_CFG 0x00
#define PWM_COUNT 0x08
#define PWM_S 0x10
#define PWM_CMP0 0x20
#define PWM_CMP1 0x24
#define PWM_CMP2 0x28
#define PWM_CMP3 0x2C
/* Constants */
#define PWM_CFG_SCALE 0x0000000F // 4bit掩码
#define PWM_CFG_STICKY 0x00000100
#define PWM_CFG_ZEROCMP 0x00000200
#define PWM_CFG_DEGLITCH 0x00000400
#define PWM_CFG_ENALWAYS 0x00001000
#define PWM_CFG_ONESHOT 0x00002000
#define PWM_CFG_CMP0CENTER 0x00010000
#define PWM_CFG_CMP1CENTER 0x00020000
#define PWM_CFG_CMP2CENTER 0x00040000
#define PWM_CFG_CMP3CENTER 0x00080000
#define PWM_CFG_CMP0GANG 0x01000000
#define PWM_CFG_CMP1GANG 0x02000000
#define PWM_CFG_CMP2GANG 0x04000000
#define PWM_CFG_CMP3GANG 0x08000000
#define PWM_CFG_CMP0IP 0x10000000
#define PWM_CFG_CMP1IP 0x20000000
#define PWM_CFG_CMP2IP 0x40000000
#define PWM_CFG_CMP3IP 0x80000000
#endif /* _SIFIVE_PWM_H */
scale 缩放倍率
A value of
0in pwmscale indicates no scaling, and pwms would then be equal to the low 16 bits of pwmcount. The maximum value of15in pwmscale corresponds to dividing the clock rate by 2^15, so for an input bus clock of 16 MHz, the LSB of pwms will increment at 488.3 Hz.
摘录自
https://sifive.cdn.prismic.io/sifive%2F4d063bf8-3ae6-4db6-9843-ee9076ebadf7_fe310-g000.pdf