本帖最后由 mingxiangjun 于 2024-7-14 14:28 编辑
基础任务:呼吸灯 一、说明 之前有讲CYW20829是48MHz M33(Bluetooth)+96MHz M33(Application)双核,其中timer能产生周期波形,有规律陡变;而pwm是有规律渐变,适合电机启动(逐渐上升)或停止(逐渐下降),本节尝试用pwm模块达到呼吸灯的效果。如果在50%周期移动电平占空比就能让能量渐高渐低。于是可以参考例程HAL_TCPWM_Timer和HAL_PWM_Square_Wave。
二、配置 通过点击Device Configuration图形化操作类似ST的STM32CubeMX,但它没有Generate Code按钮,直接点击保存会自动生成代码并放到工程bsps\TARGET_APP_CYW920829M2EVK-02\config\GeneratedSource目录下。 CYW20829有2个32bit TCPWM,7个16bit TCPWM;此次用16位tcpwm定时器0,不妨让其产生1ms脉冲,所以96MHz/Presacle*(Period+1)=1ms,可以让prescale=32,period=2999: LED2(P5.2)当目标IO,查看原理图IO高点亮,故在Device Configuration里配成初始0,互联矩阵只有16bit TCPWM5和32bit TCPWM1能连,配成16bit TCPWM5,一定注意配置项有红圈代表有错误,修改配置成绿圈才行: 于是配置TCPWM5,勾选即可: 此时在右边Code Preview标签页可以查看自动产生的代码或按上文所述在工程目录下查看。
三、编码 参考例程HAL_TCPWM_Timer和HAL_PWM_Square_Wave,两者一“杂交”就能得到答案。由于前面自动生产代码已经有初始化过配置外设,所以例程的初始化动作要去掉,如删掉cyhal_timer_init和cyhal_timer_set_frequency,取而代之cyhal_timer_init_cfg;pwm亦然,去掉cyhal_pwm_init,取而代之cyhal_timer_init_cfg,接口参数有变化,分别查看cyhal_timer.h和cyhal_pwm.h,同时把这些配置属性应用到对象上,故要先新建定时器和pwm对象: #include "cy_tcpwm_counter.h"
cyhal_timer_t timer_obj;//定时器对象
cyhal_pwm_t pwm_obj;//pwm对象
cy_rslt_t result;
#define TIMER_INT_PRIORITY (3u)
int cnt=0;//计数器
然后就是timer和pwm对象的初始化: //result = cyhal_timer_init(&timer_obj, NC, NULL);
if (CY_RSLT_SUCCESS == result)
{
//result = cyhal_timer_configure(&timer_obj, &timer_cfg);
result = cyhal_timer_init_cfg(&timer_obj,&tcpwm_0_group_1_cnt_0_hal_config);
}
if (result != CY_RSLT_SUCCESS)
{
CY_ASSERT(0);
}
//if (CY_RSLT_SUCCESS == result)
//{
// result =cyhal_timer_set_frequency(&timer_obj, 10000u);
//}
/* register timer interrupt and enable */
if (CY_RSLT_SUCCESS == result)
{
/* Assign the ISR to execute on timer interrupt */
cyhal_timer_register_callback(&timer_obj,isr_timer, NULL);
/* Set the event on which timer interrupt occurs and enable it */
cyhal_timer_enable_event(&timer_obj, CYHAL_TIMER_IRQ_TERMINAL_COUNT,
TIMER_INT_PRIORITY, true);
/* Start the timer with the configured settings */
result = cyhal_timer_start(&timer_obj);
}
/* Initialize the PWM */
//result = cyhal_pwm_init(&pwm_obj, CYBSP_USER_LED1, NULL);
result = cyhal_pwm_init_cfg(&pwm_obj,&tcpwm_0_group_1_cnt_5_hal_config);
if (result != CY_RSLT_SUCCESS)
{
CY_ASSERT(0);
}
/* Start the PWM */
result = cyhal_pwm_start(&pwm_obj);
if (result != CY_RSLT_SUCCESS)
{
CY_ASSERT(0);
}
/* Enable global interrupts */
__enable_irq();
然后就是isr部分: static void isr_timer(void* callback_arg, cyhal_timer_event_t event) //1ms
{
(void)callback_arg;
(void)event;
if(cnt<1000)
cnt++;
else
{
//cyhal_gpio_toggle(CYBSP_USER_LED1);
//printf("Toggle \n");
cnt=0;
}
if(cnt<500)
result = cyhal_pwm_set_duty_cycle(&pwm_obj, cnt/5,10000u);//stronger
else
result = cyhal_pwm_set_duty_cycle(&pwm_obj, (1000-cnt)/5,10000u);//weaker
}
四、效果 产生Pwm波形如图:
|