- /*******************************************************************************
- * File Name: main.c
- *
- * Description: This is the source code for the PWM square wave code example
- * for ModusToolbox.
- *
- * Related Document: See README.md
- *
- ********************************************************************************
- * Copyright 2019-2024, Cypress Semiconductor Corporation (an Infineon company) or
- * an affiliate of Cypress Semiconductor Corporation. All rights reserved.
- *
- * This software, including source code, documentation and related
- * materials ("Software") is owned by Cypress Semiconductor Corporation
- * or one of its affiliates ("Cypress") and is protected by and subject to
- * worldwide patent protection (United States and foreign),
- * United States copyright laws and international treaty provisions.
- * Therefore, you may use this Software only as provided in the license
- * agreement accompanying the software package from which you
- * obtained this Software ("EULA").
- * If no EULA applies, Cypress hereby grants you a personal, non-exclusive,
- * non-transferable license to copy, modify, and compile the Software
- * source code solely for use in connection with Cypress's
- * integrated circuit products. Any reproduction, modification, translation,
- * compilation, or representation of this Software except as specified
- * above is prohibited without the express written permission of Cypress.
- *
- * Disclaimer: THIS SOFTWARE IS PROVIDED AS-IS, WITH NO WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, NONINFRINGEMENT, IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Cypress
- * reserves the right to make changes to the Software without notice. Cypress
- * does not assume any liability arising out of the application or use of the
- * Software or any product or circuit described in the Software. Cypress does
- * not authorize its products for use in any products where a malfunction or
- * failure of the Cypress product may reasonably be expected to result in
- * significant property damage, injury or death ("High Risk Product"). By
- * including Cypress's product in a High Risk Product, the manufacturer
- * of such system or application assumes all risk of such use and in doing
- * so agrees to indemnify Cypress against all liability.
- *******************************************************************************/
- /*******************************************************************************
- * Header Files
- *******************************************************************************/
- #include "cybsp.h"
- #include "cyhal.h"
- #include "cy_retarget_io.h"
- #include <inttypes.h>
- /*******************************************************************************
- * Macros
- *******************************************************************************/
- /* PWM Frequency = 2Hz */
- #define PWM_FREQUENCY (20000u)
- /* PWM Duty-cycle = 50% */
- #define PWM_DUTY_CYCLE (50.0f)
- #define RGB_LED_R_CHANNEL 1
- #define RGB_LED_G_CHANNEL 2
- #define RGB_LED_B_CHANNEL 3
- #define PWM_PERIOD 1000 // PWM周期
- #define MAX_DUTY_CYCLE 1000 // 最大占空比
- #define MIN_DUTY_CYCLE 100 // 最小占空比
- #define BREATHING_PERIOD_MS 6000 // 呼吸周期
- #define RAINBOW_STEPS 500 // 彩虹渐变细腻程度
- #define CYBSP_USER_LED_R (P0_2)
- #define CYBSP_USER_LED_G (P0_3)
- #define CYBSP_USER_LED_B (P0_4)
- // 呼吸模式枚举
- typedef enum {
- CHASE_BREATHING, // 追逐呼吸模式
- SYNC_BREATHING, // 同步呼吸模式
- HEARTBEAT_DIALOGUE // 心跳对话模式
- } breathing_pattern_t;
- // 当前模式
- breathing_pattern_t current_pattern = HEARTBEAT_DIALOGUE;
- /*******************************************************************************
- * Function Prototypes
- *******************************************************************************/
- /*******************************************************************************
- * Function Definitions
- *******************************************************************************/
- /*******************************************************************************
- * Function Name: handle_error
- ********************************************************************************
- * Summary:
- * User defined error handling function.
- *
- * Parameters:
- * status - status for evaluation.
- *
- * Return:
- * void
- *
- *******************************************************************************/
- void handle_error(cy_rslt_t status)
- {
- if (CY_RSLT_SUCCESS != status)
- {
- /* Halt the CPU while debugging */
- CY_ASSERT(0);
- }
- }
- /*******************************************************************************
- * Function Name: check_status
- ********************************************************************************
- * Summary:
- * Prints the message and waits forever when an error occurs.
- *
- * Parameters:
- * message - message to print if status is non-zero.
- * status - status for evaluation.
- *
- * Return:
- * void
- *
- *******************************************************************************/
- void check_status(char *message, cy_rslt_t status)
- {
- if (CY_RSLT_SUCCESS != status)
- {
- printf("\r\n=====================================================\r\n");
- printf("\nFAIL: %s\r\n", message);
- printf("Error Code: 0x%08" PRIX32 "\n", status);
- printf("\r\n=====================================================\r\n");
- while(true);
- }
- }
- void SetPWM(cyhal_pwm_t *timer_obj, uint16_t channel, uint16_t duty_cycle)
- {
- float f_duty_cycle = 0.0f;
- // printf("duty_cycle=%d\n", duty_cycle);
- if (channel == RGB_LED_R_CHANNEL || channel == RGB_LED_G_CHANNEL || channel == RGB_LED_B_CHANNEL)
- {
- if (duty_cycle > 1000) duty_cycle = 1000; // 限制占空比最大值
- duty_cycle = 1000 - duty_cycle;
- f_duty_cycle = (float)duty_cycle/10;
- cyhal_pwm_set_duty_cycle(timer_obj, (float)duty_cycle/10, PWM_FREQUENCY);
- }
- }
- // 当前色彩阶段
- static uint16_t rainbowStep = 0;
- cyhal_pwm_t pwm_led_r_control;
- cyhal_pwm_t pwm_led_g_control;
- cyhal_pwm_t pwm_led_b_control;
- void SetRGBDutyCycle(float rFraction, float gFraction, float bFraction) {
- // 将颜色分量映射到占空比
- int redDuty = (int)(MAX_DUTY_CYCLE * rFraction);
- int greenDuty = (int)(MAX_DUTY_CYCLE * gFraction);
- int blueDuty = (int)(MAX_DUTY_CYCLE * bFraction);
- // 设置RGB LED的占空比
- SetPWM(&pwm_led_r_control, RGB_LED_R_CHANNEL, redDuty);
- SetPWM(&pwm_led_g_control, RGB_LED_G_CHANNEL, greenDuty);
- SetPWM(&pwm_led_b_control, RGB_LED_B_CHANNEL, blueDuty);
- }
- void RainbowBreathing(void) {
- static uint16_t breathingCounter = 0;
- static bool directionUp = true; // 控制呼吸方向
- // 计算呼吸效果的当前位置
- uint16_t dutyCycle = MIN_DUTY_CYCLE + (MAX_DUTY_CYCLE - MIN_DUTY_CYCLE) * (breathingCounter % (BREATHING_PERIOD_MS / 10)) / (BREATHING_PERIOD_MS / 10);
- // 计算当前的彩虹颜色
- float hueFraction = rainbowStep / (float)RAINBOW_STEPS;
- while (hueFraction > 1.0f) hueFraction -= 1.0f; // 确保在0到1之间
- // 根据当前色彩阶段设置RGB LED的色彩
- float r, g, b;
- if (hueFraction < 1.0f / 3.0f) {
- r = 1.0f;
- g = hueFraction / (1.0f / 3.0f);
- b = 0;
- } else if (hueFraction < 2.0f / 3.0f) {
- r = 1.0f - (hueFraction - 1.0f / 3.0f) * 3.0f;
- g = 1.0f;
- b = 0;
- } else {
- r = 0;
- g = 1.0f - (hueFraction - 2.0f / 3.0f) * 3.0f;
- b = 1.0f;
- }
- // 应用呼吸效果
- r *= dutyCycle / (float)MAX_DUTY_CYCLE;
- g *= dutyCycle / (float)MAX_DUTY_CYCLE;
- b *= dutyCycle / (float)MAX_DUTY_CYCLE;
- // 防止生成过于明亮的白色光
- float maxBrightness = 0.5f * dutyCycle / (float)MAX_DUTY_CYCLE; // 设定最大亮度系数,避免达到最亮
- if (r + g + b > maxBrightness) { // 如果总亮度超过限制
- float scale = maxBrightness / (r + g + b); // 计算缩放因子
- r *= scale;
- g *= scale;
- b *= scale; // 缩放各颜色通道的亮度
- }
- SetRGBDutyCycle(r, g, b);
- // 更新rainbowStep以实现颜色移动
- rainbowStep = (rainbowStep + 1) % RAINBOW_STEPS;
- // 呼吸效果递增或递减计数器
- if (directionUp) {
- if (breathingCounter >= BREATHING_PERIOD_MS / 10 - 1) {
- directionUp = false;
- } else {
- breathingCounter++;
- }
- } else {
- if (breathingCounter <= 0) {
- directionUp = true;
- } else {
- breathingCounter--;
- }
- }
- }
- int main(void)
- {
- /* PWM object */
- cyhal_pwm_t pwm_led_1_control;
- cyhal_pwm_t pwm_led_2_control;
- /* API return code */
- cy_rslt_t result;
- #if defined(CY_DEVICE_SECURE)
- cyhal_wdt_t wdt_obj;
- /* Clear watchdog timer so that it doesn't trigger a reset */
- result = cyhal_wdt_init(&wdt_obj, cyhal_wdt_get_max_timeout_ms());
- CY_ASSERT(CY_RSLT_SUCCESS == result);
- cyhal_wdt_free(&wdt_obj);
- #endif
- /* Initialize the device and board peripherals */
- result = cybsp_init();
- handle_error(result);
- /* Enable global interrupts */
- __enable_irq();
- /* Initialize the retarget-io to use the debug UART port */
- result = cy_retarget_io_init(CYBSP_DEBUG_UART_TX, CYBSP_DEBUG_UART_RX,
- CY_RETARGET_IO_BAUDRATE);
- handle_error(result);
- /* Initialize the PWM */
- result = cyhal_pwm_init(&pwm_led_r_control, CYBSP_USER_LED_R, NULL);
- check_status("API cyhal_pwm_init failed with error code", result);
- result = cyhal_pwm_init(&pwm_led_g_control, CYBSP_USER_LED_G, NULL);
- check_status("API cyhal_pwm_init failed with error code", result);
- result = cyhal_pwm_init(&pwm_led_b_control, CYBSP_USER_LED_B, NULL);
- check_status("API cyhal_pwm_init failed with error code", result);
- /* Set the PWM output frequency and duty cycle */
- result = cyhal_pwm_set_duty_cycle(&pwm_led_r_control, 100.0f,
- PWM_FREQUENCY);
- check_status("API cyhal_pwm_set_duty_cycle failed with error code", result);
- result = cyhal_pwm_set_duty_cycle(&pwm_led_g_control, 100.0f,
- PWM_FREQUENCY);
- check_status("API cyhal_pwm_set_duty_cycle failed with error code", result);
- result = cyhal_pwm_set_duty_cycle(&pwm_led_b_control, 100.0f,
- PWM_FREQUENCY);
- check_status("API cyhal_pwm_set_duty_cycle failed with error code", result);
- /* Start the PWM */
- result = cyhal_pwm_start(&pwm_led_r_control);
- check_status("API cyhal_pwm_start failed with error code", result);
- result = cyhal_pwm_start(&pwm_led_g_control);
- check_status("API cyhal_pwm_start failed with error code", result);
- result = cyhal_pwm_start(&pwm_led_b_control);
- check_status("API cyhal_pwm_start failed with error code", result);
- printf("PWM started successfully. Entering the sleep mode...\r\n");
- while (1) {
- RainbowBreathing();
- Cy_SysLib_Delay(10); // 基于10ms的延时,调整以匹配系统时钟
- }
- }
- /* [] END OF FILE */
这里放置GIF图效果