地址:https://github.com/NordicSemiconductor/nrf51-pwm-library (已上传)
nrf_pwm_init函数 初始化PWM参数 设置输出pwm的gpio pin pwm周期 分频 分辨率等。
在示例pwm_example_sin中设置100分辨率,9分频,156hz的pwm频率 3路pwm在pin 8、9、10上 并占用默认设置的三个gpiote通道2,3,0
在函数中会初始化定时器TIMER2 16位精度 cc3为pwm分辨率 也就是pwm的一个周期 并设置快捷方式清零定时器 示例直接用MASK赋值
接着设置ppi 连接定时器compare0 compare1 compare2 到gpiote 2,3,0 compare3再连接到所有的gpiote
最后启用中断 开始定时器 注意这时所有Compare的值为0 而且gpiote的pin也没设置 所有不会有任何输出。
nrf_pwm_set_value函数 设置PWM值
void nrf_pwm_set_max_value(uint32_t max_value)
{
pwm_next_max_value = max_value;
PWM_TIMER->EVENTS_COMPARE[3] = 0;
PWM_TIMER->SHORTS = TIMER_SHORTS_COMPARE3_CLEAR_Msk | TIMER_SHORTS_COMPARE3_STOP_Msk;
if((PWM_TIMER->INTENSET & TIMER_INTENSET_COMPARE3_Msk) == 0)
{
PWM_TIMER->TASKS_STOP = 1;
PWM_TIMER->INTENSET = TIMER_INTENSET_COMPARE3_Msk;
}
PWM_TIMER->TASKS_START = 1;
}
首先设置compare3为0 并设置快捷方式加入停止定时器
接着设置Compare3的中断
PWM_IRQHandler 定时器中断
void PWM_IRQHandler(void)
{
static uint32_t i;
PWM_TIMER->EVENTS_COMPARE[3] = 0;
PWM_TIMER->INTENCLR = 0xFFFFFFFF;
PWM_TIMER->CC[3] = pwm_max_value = pwm_next_max_value;
for(i = 0; i < pwm_num_channels; i++)
{
if(pwm_next_value[i] == 0)
{
nrf_gpiote_unconfig(pwm_gpiote_channel[i]);
nrf_gpio_pin_write(pwm_io_ch[i], 0);
pwm_running[i] = 0;
}
else if (pwm_next_value[i] >= pwm_max_value)
{
nrf_gpiote_unconfig(pwm_gpiote_channel[i]);
nrf_gpio_pin_write(pwm_io_ch[i], 1);
pwm_running[i] = 0;
}
else
{
PWM_TIMER->CC[i] = pwm_next_value[i];
if(!pwm_running[i])
{
nrf_gpiote_task_config(pwm_gpiote_channel[i], pwm_io_ch[i], NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_HIGH);
pwm_running[i] = 1;
}
}
}
PWM_TIMER->SHORTS = TIMER_SHORTS_COMPARE3_CLEAR_Msk;
PWM_TIMER->TASKS_START = 1;
}
首先要清除中断设置
设置cc3 pwm最大值
设置三个通道的pwm值 也就是Time2的前三个通道 cc0 cc1 cc2的值
如果是第一次运行的话需要设置gpiote和pin 并设初值为高电平
最后快捷方式清零 启动定时器
总体和之前pwm电机的例子很像 只不过本例只在改变pwm时进入中断,少用一路compare,缺点是改pwm值会有延迟。