目录
BF7006支持6组PWM,PWM也是一个特殊的16位定时器。
1. 初始化
初始化前关掉PWM。PWM没有专门的位来控制PWM的启停,是通过选择时钟源来开关PWM的。
PWM_SC = 0;
1.1 时钟源选择
PWM的时钟源有2个:外部输入和系统时钟,为了程序简单,默认选择系统时钟,因为选择了时钟源即启动了PWM,所以时钟源在初始化结束后设置。
1.2 设置分频系数
通过寄存器PWM_SC的位0:2设置分频系数(1/2/4/8/16/32/64/128)。注意,这里默认选择的时钟源是系统时钟。
if(freq >= SystemCoreClock / 0x1000)
;
else if(freq >= SystemCoreClock / (2 * 0x1000))
PWM_SC |= 1;
else if(freq >= SystemCoreClock / (4 * 0x1000))
PWM_SC |= 2;
else if(freq >= SystemCoreClock / (8 * 0x1000))
PWM_SC |= 3;
else if(freq >= SystemCoreClock / (16 * 0x1000))
PWM_SC |= 4;
else if(freq >= SystemCoreClock / (32 * 0x100))
PWM_SC |= 5;
else if(freq >= SystemCoreClock / (64 * 0x1000))
PWM_SC |= 6;
else //if(freq >= SystemCoreClock / (128 * 0x1000))
PWM_SC |= 7;
这里设置保证计数最少0x1000。
1.3 设置频率
和定时器类似,通过寄存器PWM_MOD设置。
PWM_MOD = (SystemCoreClock >> (PWM_SC & 0x07)) / freq - 1;
1.4 设置PWM模式
实际这个定时器不仅仅是可以用于PWM,所以需要设置寄存器PWM_SC的位5为中央对齐模式以实现PWM功能。
PWM_SC |= (1 << 5);
这里默认选择中央对齐模式来实现PWM功能,实际上还可以通过设置这个为0,然后选择边缘对齐的方式实现。
1.5 通道电平极性设置
PWM_SC的位5和PWM_CxSC组合配置PWM的模式和极性(如下图红框的2种模式),这里默认设置为High-true脉冲。
uint32_t const *pwmCxSCGroup[HW_PWM_MAX] = {(uint32_t *)&PWM_C0SC, (uint32_t *)&PWM_C1SC, (uint32_t *)&PWM_C2SC, (uint32_t *)&PWM_C3SC, (uint32_t *)&PWM_C4SC, (uint32_t *)&PWM_C5SC};
*(volatile uint32_t *)pwmCxSCGroup[port] = 0x08;
1.6 设置占空比
通过设置寄存器PWM_CxV(记录输入捕获的计数值或配置输出比较的计数值)设置占空比。
uint32_t const *pwmCxVGroup[HW_PWM_MAX] = {(uint32_t *)&PWM_C0V, (uint32_t *)&PWM_C1V, (uint32_t *)&PWM_C2V, (uint32_t *)&PWM_C3V, (uint32_t *)&PWM_C4V, (uint32_t *)&PWM_C5V};
*(volatile uint32_t *)pwmCxVGroup[port] = (uint32_t)PWM_MOD * duty / 100;
2. 启动PWM
设置好时钟源后即启动PWM,系统时钟设置为默认时钟源。
PWM_SC |= (1 << 3); //Select system core clock and start
3. 初始化IO
6个PWM通道对应的IO分别是PD2,PD3,PD4,PD5, PD6,PD7,将对应的IO配置为输出即可。
例如开发板上有2个PWM口接到LED上,PD2对应PWM0:
GPIO_PTDD(GPIOD) |= 0x04; //Set GPIOD2 output
4. 实例
例如通道0设置为50KHz,40%的占空比。因为这里采用中央对齐的模式,所以设置的频率是50 * 2 = 100KHz。
pwmInit(HW_PWM_0, 1*100*1000, 40);
pwmStart();