[AIROC™ 蓝牙] 【英飞凌CYW20829测评】第2篇 呼吸灯实验

[复制链接]
 楼主| 小宏121 发表于 2024-7-16 23:46 | 显示全部楼层 |阅读模式
<
本帖最后由 小宏121 于 2024-7-17 23:52 编辑

先简单说下MTB和官方例程的用法

新建一个自己的文件夹myproject用于放置自己工程



复制一个官方的empty_app例程到myproject路径下


如果MTB有提示要输入 make getlibs,则在MTB终端里输入即可


复制后,这里添加新的工程


等待MTB将新的工程加载完成

这里可以对该工程的配置



比如配置GPIO


配置后的代码可以在右边看到预览


这里可以打开配置后的文件路径


这个文件夹里有配置的代码


这是刚刚配置的代码文件

这是刚刚配置的GPIO代码

熟悉了MTB的简单应用后,下面我复制官方例程的TCPWM例程 "HAL_PWM_Square_Wave",在这基础上实现彩虹呼吸灯的效果
注意的是开发板的LED是低电平点亮灯,高电平灭灯,所以占空比越大灯越暗。

  1. /*******************************************************************************
  2. * File Name:   main.c
  3. *
  4. * Description: This is the source code for the PWM square wave code example
  5. *              for ModusToolbox.
  6. *
  7. * Related Document: See README.md
  8. *
  9. ********************************************************************************
  10. * Copyright 2019-2024, Cypress Semiconductor Corporation (an Infineon company) or
  11. * an affiliate of Cypress Semiconductor Corporation.  All rights reserved.
  12. *
  13. * This software, including source code, documentation and related
  14. * materials ("Software") is owned by Cypress Semiconductor Corporation
  15. * or one of its affiliates ("Cypress") and is protected by and subject to
  16. * worldwide patent protection (United States and foreign),
  17. * United States copyright laws and international treaty provisions.
  18. * Therefore, you may use this Software only as provided in the license
  19. * agreement accompanying the software package from which you
  20. * obtained this Software ("EULA").
  21. * If no EULA applies, Cypress hereby grants you a personal, non-exclusive,
  22. * non-transferable license to copy, modify, and compile the Software
  23. * source code solely for use in connection with Cypress's
  24. * integrated circuit products.  Any reproduction, modification, translation,
  25. * compilation, or representation of this Software except as specified
  26. * above is prohibited without the express written permission of Cypress.
  27. *
  28. * Disclaimer: THIS SOFTWARE IS PROVIDED AS-IS, WITH NO WARRANTY OF ANY KIND,
  29. * EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, NONINFRINGEMENT, IMPLIED
  30. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Cypress
  31. * reserves the right to make changes to the Software without notice. Cypress
  32. * does not assume any liability arising out of the application or use of the
  33. * Software or any product or circuit described in the Software. Cypress does
  34. * not authorize its products for use in any products where a malfunction or
  35. * failure of the Cypress product may reasonably be expected to result in
  36. * significant property damage, injury or death ("High Risk Product"). By
  37. * including Cypress's product in a High Risk Product, the manufacturer
  38. * of such system or application assumes all risk of such use and in doing
  39. * so agrees to indemnify Cypress against all liability.
  40. *******************************************************************************/

  41. /*******************************************************************************
  42. * Header Files
  43. *******************************************************************************/
  44. #include "cybsp.h"
  45. #include "cyhal.h"
  46. #include "cy_retarget_io.h"
  47. #include <inttypes.h>


  48. /*******************************************************************************
  49. * Macros
  50. *******************************************************************************/
  51. /* PWM Frequency = 2Hz */
  52. #define PWM_FREQUENCY (20000u)
  53. /* PWM Duty-cycle = 50% */
  54. #define PWM_DUTY_CYCLE (50.0f)

  55. #define RGB_LED_R_CHANNEL 1
  56. #define RGB_LED_G_CHANNEL 2
  57. #define RGB_LED_B_CHANNEL 3
  58. #define PWM_PERIOD 1000 // PWM周期
  59. #define MAX_DUTY_CYCLE 1000 // 最大占空比
  60. #define MIN_DUTY_CYCLE 100 // 最小占空比
  61. #define BREATHING_PERIOD_MS 6000 // 呼吸周期
  62. #define RAINBOW_STEPS 500 // 彩虹渐变细腻程度

  63. #define CYBSP_USER_LED_R (P0_2)
  64. #define CYBSP_USER_LED_G (P0_3)
  65. #define CYBSP_USER_LED_B (P0_4)

  66. // 呼吸模式枚举
  67. typedef enum {
  68.     CHASE_BREATHING,       // 追逐呼吸模式
  69.     SYNC_BREATHING,        // 同步呼吸模式
  70.     HEARTBEAT_DIALOGUE     // 心跳对话模式
  71. } breathing_pattern_t;

  72. // 当前模式
  73. breathing_pattern_t current_pattern = HEARTBEAT_DIALOGUE;

  74. /*******************************************************************************
  75. * Function Prototypes
  76. *******************************************************************************/


  77. /*******************************************************************************
  78. * Function Definitions
  79. *******************************************************************************/

  80. /*******************************************************************************
  81. * Function Name: handle_error
  82. ********************************************************************************
  83. * Summary:
  84. *  User defined error handling function.
  85. *
  86. * Parameters:
  87. *  status - status for evaluation.
  88. *
  89. * Return:
  90. *  void
  91. *
  92. *******************************************************************************/
  93. void handle_error(cy_rslt_t status)
  94. {
  95.     if (CY_RSLT_SUCCESS != status)
  96.     {
  97.         /* Halt the CPU while debugging */
  98.         CY_ASSERT(0);
  99.     }
  100. }


  101. /*******************************************************************************
  102. * Function Name: check_status
  103. ********************************************************************************
  104. * Summary:
  105. *  Prints the message and waits forever when an error occurs.
  106. *
  107. * Parameters:
  108. *  message - message to print if status is non-zero.
  109. *  status - status for evaluation.
  110. *
  111. * Return:
  112. *  void
  113. *
  114. *******************************************************************************/
  115. void check_status(char *message, cy_rslt_t status)
  116. {
  117.     if (CY_RSLT_SUCCESS != status)
  118.     {
  119.         printf("\r\n=====================================================\r\n");
  120.         printf("\nFAIL: %s\r\n", message);
  121.         printf("Error Code: 0x%08" PRIX32 "\n", status);
  122.         printf("\r\n=====================================================\r\n");

  123.         while(true);
  124.     }
  125. }


  126. void SetPWM(cyhal_pwm_t *timer_obj, uint16_t channel, uint16_t duty_cycle)
  127. {
  128.     float f_duty_cycle = 0.0f;
  129. //    printf("duty_cycle=%d\n", duty_cycle);
  130.     if (channel == RGB_LED_R_CHANNEL || channel == RGB_LED_G_CHANNEL || channel == RGB_LED_B_CHANNEL)
  131.     {
  132.         if (duty_cycle > 1000) duty_cycle = 1000; // 限制占空比最大值

  133.         duty_cycle = 1000 - duty_cycle;
  134.         f_duty_cycle = (float)duty_cycle/10;
  135.         cyhal_pwm_set_duty_cycle(timer_obj, (float)duty_cycle/10, PWM_FREQUENCY);
  136.     }
  137. }

  138. // 当前色彩阶段
  139. static uint16_t rainbowStep = 0;
  140. cyhal_pwm_t pwm_led_r_control;
  141. cyhal_pwm_t pwm_led_g_control;
  142. cyhal_pwm_t pwm_led_b_control;

  143. void SetRGBDutyCycle(float rFraction, float gFraction, float bFraction) {
  144.     // 将颜色分量映射到占空比
  145.     int redDuty = (int)(MAX_DUTY_CYCLE * rFraction);
  146.     int greenDuty = (int)(MAX_DUTY_CYCLE * gFraction);
  147.     int blueDuty = (int)(MAX_DUTY_CYCLE * bFraction);

  148.     // 设置RGB LED的占空比
  149.     SetPWM(&pwm_led_r_control, RGB_LED_R_CHANNEL, redDuty);
  150.     SetPWM(&pwm_led_g_control, RGB_LED_G_CHANNEL, greenDuty);
  151.     SetPWM(&pwm_led_b_control, RGB_LED_B_CHANNEL, blueDuty);
  152. }

  153. void RainbowBreathing(void) {
  154.     static uint16_t breathingCounter = 0;
  155.     static bool directionUp = true; // 控制呼吸方向

  156.     // 计算呼吸效果的当前位置
  157.     uint16_t dutyCycle = MIN_DUTY_CYCLE + (MAX_DUTY_CYCLE - MIN_DUTY_CYCLE) * (breathingCounter % (BREATHING_PERIOD_MS / 10)) / (BREATHING_PERIOD_MS / 10);

  158.     // 计算当前的彩虹颜色
  159.     float hueFraction = rainbowStep / (float)RAINBOW_STEPS;
  160.     while (hueFraction > 1.0f) hueFraction -= 1.0f; // 确保在0到1之间

  161.     // 根据当前色彩阶段设置RGB LED的色彩
  162.     float r, g, b;
  163.     if (hueFraction < 1.0f / 3.0f) {
  164.         r = 1.0f;
  165.         g = hueFraction / (1.0f / 3.0f);
  166.         b = 0;
  167.     } else if (hueFraction < 2.0f / 3.0f) {
  168.         r = 1.0f - (hueFraction - 1.0f / 3.0f) * 3.0f;
  169.         g = 1.0f;
  170.         b = 0;
  171.     } else {
  172.         r = 0;
  173.         g = 1.0f - (hueFraction - 2.0f / 3.0f) * 3.0f;
  174.         b = 1.0f;
  175.     }

  176.     // 应用呼吸效果
  177.     r *= dutyCycle / (float)MAX_DUTY_CYCLE;
  178.     g *= dutyCycle / (float)MAX_DUTY_CYCLE;
  179.     b *= dutyCycle / (float)MAX_DUTY_CYCLE;

  180.     // 防止生成过于明亮的白色光
  181.     float maxBrightness = 0.5f * dutyCycle / (float)MAX_DUTY_CYCLE; // 设定最大亮度系数,避免达到最亮
  182.     if (r + g + b > maxBrightness) { // 如果总亮度超过限制
  183.         float scale = maxBrightness / (r + g + b); // 计算缩放因子
  184.         r *= scale;
  185.         g *= scale;
  186.         b *= scale; // 缩放各颜色通道的亮度
  187.     }

  188.     SetRGBDutyCycle(r, g, b);

  189.     // 更新rainbowStep以实现颜色移动
  190.     rainbowStep = (rainbowStep + 1) % RAINBOW_STEPS;

  191.     // 呼吸效果递增或递减计数器
  192.     if (directionUp) {
  193.         if (breathingCounter >= BREATHING_PERIOD_MS / 10 - 1) {
  194.             directionUp = false;
  195.         } else {
  196.             breathingCounter++;
  197.         }
  198.     } else {
  199.         if (breathingCounter <= 0) {
  200.             directionUp = true;
  201.         } else {
  202.             breathingCounter--;
  203.         }
  204.     }
  205. }

  206. int main(void)
  207. {
  208.     /* PWM object */
  209.     cyhal_pwm_t pwm_led_1_control;
  210.     cyhal_pwm_t pwm_led_2_control;

  211.     /* API return code */
  212.     cy_rslt_t result;

  213. #if defined(CY_DEVICE_SECURE)
  214.     cyhal_wdt_t wdt_obj;
  215.     /* Clear watchdog timer so that it doesn't trigger a reset */
  216.     result = cyhal_wdt_init(&wdt_obj, cyhal_wdt_get_max_timeout_ms());
  217.     CY_ASSERT(CY_RSLT_SUCCESS == result);
  218.     cyhal_wdt_free(&wdt_obj);
  219. #endif

  220.     /* Initialize the device and board peripherals */
  221.     result = cybsp_init();
  222.     handle_error(result);

  223.     /* Enable global interrupts */
  224.     __enable_irq();

  225.     /* Initialize the retarget-io to use the debug UART port */
  226.     result = cy_retarget_io_init(CYBSP_DEBUG_UART_TX, CYBSP_DEBUG_UART_RX,
  227.                                  CY_RETARGET_IO_BAUDRATE);
  228.     handle_error(result);


  229.     /* Initialize the PWM */
  230.     result = cyhal_pwm_init(&pwm_led_r_control, CYBSP_USER_LED_R, NULL);
  231.     check_status("API cyhal_pwm_init failed with error code", result);

  232.     result = cyhal_pwm_init(&pwm_led_g_control, CYBSP_USER_LED_G, NULL);
  233.     check_status("API cyhal_pwm_init failed with error code", result);

  234.     result = cyhal_pwm_init(&pwm_led_b_control, CYBSP_USER_LED_B, NULL);
  235.     check_status("API cyhal_pwm_init failed with error code", result);

  236.     /* Set the PWM output frequency and duty cycle */
  237.     result = cyhal_pwm_set_duty_cycle(&pwm_led_r_control, 100.0f,
  238.                                       PWM_FREQUENCY);
  239.     check_status("API cyhal_pwm_set_duty_cycle failed with error code", result);

  240.     result = cyhal_pwm_set_duty_cycle(&pwm_led_g_control, 100.0f,
  241.                                       PWM_FREQUENCY);
  242.     check_status("API cyhal_pwm_set_duty_cycle failed with error code", result);

  243.     result = cyhal_pwm_set_duty_cycle(&pwm_led_b_control, 100.0f,
  244.                                       PWM_FREQUENCY);
  245.     check_status("API cyhal_pwm_set_duty_cycle failed with error code", result);

  246.     /* Start the PWM */
  247.     result = cyhal_pwm_start(&pwm_led_r_control);
  248.     check_status("API cyhal_pwm_start failed with error code", result);

  249.     result = cyhal_pwm_start(&pwm_led_g_control);
  250.     check_status("API cyhal_pwm_start failed with error code", result);

  251.     result = cyhal_pwm_start(&pwm_led_b_control);
  252.     check_status("API cyhal_pwm_start failed with error code", result);
  253.     printf("PWM started successfully. Entering the sleep mode...\r\n");

  254.     while (1) {
  255.         RainbowBreathing();
  256.         Cy_SysLib_Delay(10); // 基于10ms的延时,调整以匹配系统时钟
  257.     }
  258. }


  259. /* [] END OF FILE */


这里放置GIF图效果

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
您需要登录后才可以回帖 登录 | 注册

本版积分规则

6

主题

21

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部