本帖最后由 南来之风 于 2024-7-20 15:50 编辑
开发板上有两个用户LED,丝印分别是USER LED1和USER LED2,电路原理图如下:
本次实验计划使用PWM内部连接到USER LED2,实现呼吸灯效果;在定时器内通过GPIO正常驱动USER LED1,周期2s。
接着通过BSP Configurators -> Device Configurator 4.20进行外设配置和引脚等配置界面。
配置USER LED2内部连接到TCPWM信号:
时钟分配:
PWM参数配置:
点击SAVE后,自动检测配置是否有错误,如果没有错误,自动生成代码。
const cy_stc_tcpwm_pwm_config_t tcpwm_0_group_1_cnt_5_config =
{
.pwmMode = CY_TCPWM_PWM_MODE_PWM,
.clockPrescaler = CY_TCPWM_PWM_PRESCALER_DIVBY_1,
.pwmAlignment = CY_TCPWM_PWM_LEFT_ALIGN,
.deadTimeClocks = 0,
.runMode = CY_TCPWM_PWM_CONTINUOUS,
.period0 = 32768,
.period1 = 32768,
.enablePeriodSwap = false,
.compare0 = 16384,
.compare1 = 16384,
.enableCompareSwap = false,
.interruptSources = (CY_TCPWM_INT_ON_TC & 0U) | (CY_TCPWM_INT_ON_CC0 & 0U) | (CY_TCPWM_INT_ON_CC1 & 0U),
.invertPWMOut = CY_TCPWM_PWM_INVERT_DISABLE,
.invertPWMOutN = CY_TCPWM_PWM_INVERT_DISABLE,
.killMode = CY_TCPWM_PWM_STOP_ON_KILL,
.swapInputMode = tcpwm_0_group_1_cnt_5_INPUT_DISABLED & 0x3U,
.swapInput = CY_TCPWM_INPUT_0,
.reloadInputMode = tcpwm_0_group_1_cnt_5_INPUT_DISABLED & 0x3U,
.reloadInput = CY_TCPWM_INPUT_0,
.startInputMode = tcpwm_0_group_1_cnt_5_INPUT_DISABLED & 0x3U,
.startInput = CY_TCPWM_INPUT_0,
.killInputMode = tcpwm_0_group_1_cnt_5_INPUT_DISABLED & 0x3U,
.killInput = CY_TCPWM_INPUT_0,
.countInputMode = tcpwm_0_group_1_cnt_5_INPUT_DISABLED & 0x3U,
.countInput = CY_TCPWM_INPUT_1,
.swapOverflowUnderflow = false,
.immediateKill = false,
.tapsEnabled = 45,
.compare2 = 16384,
.compare3 = 16384,
.enableCompare1Swap = false,
.compare0MatchUp = true,
.compare0MatchDown = false,
.compare1MatchUp = true,
.compare1MatchDown = false,
.kill1InputMode = tcpwm_0_group_1_cnt_5_INPUT_DISABLED & 0x3U,
.kill1Input = CY_TCPWM_INPUT_0,
.pwmOnDisable = CY_TCPWM_PWM_OUTPUT_HIGHZ,
.trigger0Event = CY_TCPWM_CNT_TRIGGER_ON_DISABLED,
.trigger1Event = CY_TCPWM_CNT_TRIGGER_ON_DISABLED,
.reloadLineSelect = false,
.line_out_sel = CY_TCPWM_OUTPUT_PWM_SIGNAL,
.linecompl_out_sel = CY_TCPWM_OUTPUT_INVERTED_PWM_SIGNAL,
.line_out_sel_buff = CY_TCPWM_OUTPUT_PWM_SIGNAL,
.linecompl_out_sel_buff = CY_TCPWM_OUTPUT_INVERTED_PWM_SIGNAL,
.deadTimeClocks_linecompl_out = 0,
#if defined (CY_IP_MXS40TCPWM)
.hrpwm_enable = false,
.hrpwm_input_freq = CY_TCPWM_HRPWM_FREQ_80MHZ_OR_100MHZ,
.kill_line_polarity = CY_TCPWM_LINEOUT_AND_LINECMPOUT_IS_LOW,
.deadTimeClocksBuff = 0,
.deadTimeClocksBuff_linecompl_out = 0,
.buffer_swap_enable = false,
.glitch_filter_enable = false,
.gf_depth = CY_GLITCH_FILTER_DEPTH_SUPPORT_VALUE_0,
.dithering_mode = CY_TCPWM_DITHERING_DISABLE,
.period_dithering_value = 128,
.duty_dithering_value = 128,
.limiter = CY_TCPWM_DITHERING_LIMITER_7,
#endif /* defined (CY_IP_MXS40TCPWM) */
};
接下来在主函数中进行相关初始化与应用程序编写:
首先是定时器设定为1ms一次中断
void timer_init(void)
{
cy_rslt_t result;
const cyhal_timer_cfg_t led_blink_timer_cfg =
{
.compare_value = 0, /* Timer compare value, not used */
.period = LED_BLINK_TIMER_PERIOD, /* Defines the timer period */
.direction = CYHAL_TIMER_DIR_UP, /* Timer counts up */
.is_compare = false, /* Don't use compare mode */
.is_continuous = true, /* Run timer indefinitely */
.value = 0 /* Initial value of counter */
};
/* Initialize the timer object. Does not use input pin ('pin' is NC) and
* does not use a pre-configured clock source ('clk' is NULL). */
result = cyhal_timer_init(&led_blink_timer, NC, NULL);
/* timer init failed. Stop program execution */
if (result != CY_RSLT_SUCCESS)
{
CY_ASSERT(0);
}
/* Configure timer period and operation mode such as count direction,
duration */
cyhal_timer_configure(&led_blink_timer, &led_blink_timer_cfg);
/* Set the frequency of timer's clock source */
cyhal_timer_set_frequency(&led_blink_timer, LED_BLINK_TIMER_CLOCK_HZ);
/* Assign the ISR to execute on timer interrupt */
cyhal_timer_register_callback(&led_blink_timer, isr_timer, NULL);
/* Set the event on which timer interrupt occurs and enable it */
cyhal_timer_enable_event(&led_blink_timer, CYHAL_TIMER_IRQ_TERMINAL_COUNT,
7, true);
/* Start the timer with the configured settings */
cyhal_timer_start(&led_blink_timer);
}
接下来进行pwm初始化:
static void isr_timer(void* callback_arg, cyhal_timer_event_t event)
{
(void)callback_arg;
(void)event;
if(timer_count > 0)
timer_count -= 1;
if(timer_count == 0)
{
timer_count = 2000;
cyhal_gpio_toggle(CYBSP_USER_LED1);
}
if(timer_count < 1000)
{
cyhal_pwm_set_duty_cycle(&pwm_led2_control,timer_count/10.0,10000);
}
else {
cyhal_pwm_set_duty_cycle(&pwm_led2_control, (2000-timer_count)/10.0,10000);
}
}
最终效果如下:
|
此文章已获得独家原创/原创奖标签,著作权归21ic所有,未经允许禁止转载。
|