SYD8821的PWM分为两个部分,一个是PWM_LED,这个是慢速的PWM,挂在32.768Khz的晶振上,用于驱动LED,另外一个是Fast PWM ,这个时钟的速度就能够调到很高,在驱动马达喇叭等都会有用处。
PWM_LED使用说明
在PWM_LED方面,SYD8821沿用了SYD8801的设计,请看:https://blog.csdn.net/chengdong1314/article/details/70241997
Syd8821的PWM模块支持三种模式:PWM、闪光、呼吸灯,他们的时序如下:
硬件接线图如下:
打开PWM_LED例程可看到主函数如下:
int main()
{
uint8_t *buff;
uint16_t buff_size=0;
__disable_irq();
//GPO
pad_mux_write(LED4, 0);
pad_mux_write(LED5, 0);
pad_mux_write(LED6, 0);
pad_mux_write(LED7, 0);
gpo_config(LED4,1);
gpo_config(LED5,1);
gpo_config(LED6,1);
gpo_config(LED7,1);
//GPI
pad_mux_write(KEY1, 0);
pad_mux_write(KEY2, 0);
pad_mux_write(KEY3, 0);
gpi_config(KEY1, PULL_UP);
gpi_config(KEY2, PULL_UP);
gpi_config(KEY3, PULL_UP);
// //uart 1
// pad_mux_write(4, 7);
// pad_mux_write(5, 7);
// uart_1_init(UART_RTS_CTS_DISABLE, UART_BAUD_115200);
// uart_write(1,"SYD8821 UART TEST", 18);
//uart 0
pad_mux_write(20, 7);
pad_mux_write(21, 7);
dbg_init();
dbg_printf("SYD8821 PWM TEST");
// Select External XO
sys_32k_clock_set(SYSTEM_32K_CLOCK_XO);
// Set MCU Clock 64M
sys_mcu_clock_set(MCU_CLOCK_64_MHZ);
pad_mux_write(0, 10); //设置GPIO0为PWM_LED模式
pad_mux_write(1, 10); //设置GPIO1为PWM_LED模式
pad_mux_write(2, 10); //设置GPIO2为PWM_LED模式
pwm_led_set_pwm(0,50,100); //PWM设置
pwm_led_set_flash(1, 4,10,10,8,127); //闪光灯设置
pwm_led_set_breath(2,0,100,100,10); //呼吸灯设置
pwm_led_start(0); //开启PWM0
pwm_led_start(1); //开启PWM1
pwm_led_start(2); //开启PWM2
__enable_irq();
while(1)
{
gpo_toggle(LED4);
delay_ms(100);
}
}
其中pwm_led_set_pwm的源码如下:
void pwm_led_set_pwm(uint32_t id, uint32_t start_high_period, uint32_t total_period)
{
pwm_led_mode[id] = PWM_LED_PWM_MODE;
PWM_LED_CTRL[id]->PWM_N = start_high_period;
PWM_LED_CTRL[id]->PWM_M = total_period;
}
其中PWM_N和PWM_N两个寄存器的意义看PWM的时序便知,前者为占空比,后者为周期,他们的单位都是1/32ms
pwm_led_set_flash的源码如下:
void pwm_led_set_flash(uint32_t id, uint32_t duty_kept_length, uint32_t duty_cycle_length,
uint32_t duty_cycle_count, uint32_t duty_cycle_end_delay, uint32_t duty_cycles_count)
{
PWM_LED_CTRL[id]->T1 = duty_kept_length;
PWM_LED_CTRL[id]->T2 = duty_cycle_length;
PWM_LED_CTRL[id]->N1 = duty_cycle_count;
PWM_LED_CTRL[id]->T3 = duty_cycle_end_delay;
PWM_LED_CTRL[id]->N2 = duty_cycles_count;
pwm_led_mode[id] = PWM_LED_FLASH_MODE;
}
闪烁模式比较复杂,请看时序对比寄存器的意义即可知变量的用途。
pwm_led_set_breath呼吸灯的设置源码如下:
void pwm_led_set_breath(uint32_t id, uint32_t min, uint32_t max, uint32_t period, uint32_t step)
{
PWM_LED_CTRL[id]->BR_TH_MAX = max;
PWM_LED_CTRL[id]->BR_TH_MIN = min;
PWM_LED_CTRL[id]->T4 = period;
PWM_LED_CTRL[id]->BR_SP = step;
pwm_led_mode[id] = PWM_LED_BREATH_MODE;
}
所谓呼吸灯就是可变占空比的PWM,从时序可知min代表最小的脉冲占空比,max是最大的脉冲占空比,period为周期,step为每个脉冲和上个脉冲增加的步调,单位也是1/32ms
测试PWM波形如下:
测试闪烁波形如下;
测试呼吸灯波形如下:
占空比从最小增加到最大:
然后占空比从最大慢慢减小到最小:
波形输入请看:https://download.csdn.net/download/chengdong1314/10304256
本节代码如下:https://download.csdn.net/download/chengdong1314/10304265
暂停、重启、停止
这里修改while1主循环如下:
while(1)
{
gpo_toggle(LED4);
if(!gpi_get_val(KEY1)){ //停止
pwm_led_stop(0);
pwm_led_stop(1);
pwm_led_stop(2);
dbg_printf("pwm_led_stop 0 1 2\r\n");
gpo_toggle(LED5);
}
if(!gpi_get_val(KEY2)){ //重启
pwm_led_resume(0);
pwm_led_resume(1);
pwm_led_resume(2);
dbg_printf("pwm_led_resume 0 1 2\r\n");
gpo_toggle(LED6);
}
if(!gpi_get_val(KEY3)){ //暂停
pwm_led_pause(0);
pwm_led_pause(1);
pwm_led_pause(2);
dbg_printf("pwm_led_pause 0 1 2\r\n");
gpo_toggle(LED7);
}
delay_ms(100);
}
按下相应的按键即可相应的控制PWM模块,这里按下KEY1后PWM将停止,因为这里没有开始的按键,所以不能够再启动了。