[活动专区] 【杰发科技AC7802x测评】8. PWM驱动LED

[复制链接]
1037|0
 楼主| hehung 发表于 2023-6-17 22:13 | 显示全部楼层 |阅读模式
本帖最后由 hehung 于 2023-6-19 13:52 编辑

#申请原创# #技术资源#
前言

本文将测试AC7802X的PWM功能,使用PWM驱动LED1与LED2周期性明暗变化。

PWM原理比较简单,就不做详细介绍,本文通过控制占空比的方式控制LED明暗变化。

1 硬件连接

查看原理图可知,LED是支持PWM功能的。LED1连接到了PA2,LED2连接到了PA3。

1686982959433.png

查看数据手册,可以直到PA2和PA3都是支持PEM复用功能的,所以可以使用PWM来驱动LED1和LED2。

- PA2连接到了PWM_CH1引脚,复用功能为1
- PA3连接到了PWM_CH0引脚,复用功能为1

1686983088367.png

2 软件开发

需要先打开PWM功能选项,如下图所示:

1687010019238.png

2.2 PWM初始化

新建了app_pwm.c,实现了PWM初始化功能。

初始化了最大的周期数值为10000;初始占空比为0,禁用中断功能。

app_pwm.c文件

  1. /*
  2. @hehung
  3. 2023-6-17
  4. email: 1398660197@qq.com
  5. wechat: hehung95
  6. reproduced and please indicate the source @hehung
  7. */

  8. #include <stdbool.h>
  9. #include "ac780x_gpio.h"
  10. #include "ac780x_pwm.h"
  11. #include <string.h>

  12. #include "app_pwm.h"


  13. void Pwm_Init(void)
  14. {
  15.     PWM_ConfigType config;
  16.     PWM_ModulationConfigType pwmConfig;
  17.     PWM_IndependentChConfig independentChConfig[2];

  18.     memset(&config, 0U, sizeof(config));
  19.     memset(&pwmConfig, 0U, sizeof(pwmConfig));
  20.     memset(&independentChConfig, 0U, sizeof(independentChConfig));

  21.     GPIO_SetFunc(GPIOA, GPIO_PIN2, GPIO_FUN1); /* PA2--PWM2_CH1.*/
  22.     GPIO_SetFunc(GPIOA, GPIO_PIN3, GPIO_FUN1); /* PA3--PWM2_CH0.*/

  23.     /*
  24.     边沿对齐PWM模式:
  25.     周期=(MCVR-CNTIN+1)*PWM计数器时钟周期
  26.     脉宽=(CHnV-CNTIN+1)*PWM计数器时钟周期
  27.     中心对齐PWM模式:
  28.     周期=2*(MCVR-CNTIN)*PWM计数器时钟周期
  29.     脉宽=2*(CHnV-CNTIN)*PWM计数器时钟周期
  30.     */
  31.     independentChConfig[0].channel = PWM_CH_0;                         /*独立输出通道选择 */
  32.     independentChConfig[0].chValue = 0;                             /*通道channel值,决定占空比 */
  33.     independentChConfig[0].levelMode = PWM_HIGH_TRUE;                  /*输出PWM高有效,可配置高有效或低有效 */
  34.     independentChConfig[0].polarity = PWM_OUTPUT_POLARITY_ACTIVE_HIGH; /*通道输出极性配置为高有效,PWM Mask后输出为低电平 */
  35.     independentChConfig[0].interruptEn = ENABLE;                       /*通道匹配中断使能位 */
  36.     independentChConfig[0].initLevel = PWM_LOW_LEVEL;                  /*通道初始电平输出配置,该配置受initChOutputEn控制,决定PMM计数器未工作前PWM口的输出电平 */
  37.     independentChConfig[0].triggerEn = DISABLE;                        /*通道匹配触发使能位,在通道值匹配时可产生触发信号用于其他模块的触发信号 */

  38.     independentChConfig[1].channel = PWM_CH_1;                         /*独立输出通道选择 */
  39.     independentChConfig[1].chValue = 0;                             /*通道channel值,决定占空比 */
  40.     independentChConfig[1].levelMode = PWM_HIGH_TRUE;                  /*输出PWM高有效,可配置高有效或低有效 */
  41.     independentChConfig[1].polarity = PWM_OUTPUT_POLARITY_ACTIVE_HIGH; /*通道输出极性配置为高有效,PWM Mask后输出为低电平 */
  42.     independentChConfig[1].interruptEn = ENABLE;                       /*通道匹配中断使能位 */
  43.     independentChConfig[1].initLevel = PWM_LOW_LEVEL;                  /*通道初始电平输出配置,该配置受initChOutputEn控制,决定PMM计数器未工作前PWM口的输出电平 */
  44.     independentChConfig[1].triggerEn = DISABLE;                        /*通道匹配触发使能位,在通道值匹配时可产生触发信号用于其他模块的触发信号 */

  45.     pwmConfig.countMode = PWM_UP_DOWN_COUNT;               /*PWM计数器模式,PWM_UP_COUNT--向上计数模式;PWM_UP_DOWN_COUNT-- 向上/向下计数模式 */
  46.     pwmConfig.independentChannelNum = 2;                   /*独立通道数目*/
  47.     pwmConfig.combineChannelNum = 0;                       /*组合通道对数 */
  48.     pwmConfig.independentChConfig = independentChConfig;   /*独立通道配置赋值 */
  49.     pwmConfig.combineChConfig = NULL;                      /*组合通道配置赋值 */
  50.     pwmConfig.deadtime = 0;                                /*死区时间值,死区功能仅在组合模式下有效  */
  51.     pwmConfig.deadtimePsc = PWM_DEADTIME_DIVID_1;          /*死区时间时钟分频系数,死区功能仅在组合模式下有效 */
  52.     pwmConfig.initChOutputEn = ENABLE;                     /*初始化通道输出使能位,使能后独立PWM模式的 initLevel 和组合模式的ch1stInitLevel和ch2ndInitLevel配置才会生效*/
  53.     pwmConfig.initTriggerEn = DISABLE;                     /*PWM初始值触发使能位 */

  54.     /*
  55.     向上-向下技术模式下,频率计算为:
  56.     freq = pwm_clk/(2*(maxValue - initValue))
  57.     16000/(2*8000) = 1K
  58.     */
  59.     config.mode = PWM_MODE_MODULATION;            /*PWM模式配置,PWM_MODE_MODULATION--PWM调制模式 */
  60.     config.initModeStruct = &pwmConfig;           /*不同模式相应初始化配置结构体赋值 */
  61.     config.clkSource = PWM_CLK_SOURCE_APB;        /*PWM时钟源选择 */
  62.     config.clkPsc = 0;                            /*时钟分频系数 */
  63.     config.initValue = 0;                         /*初始计数值 */
  64.     config.maxValue = APP_PWM_MAX_DUTY_COUNT;                       /*最大计数值,决定输出波形频率 */
  65.     config.overflowInterrupEn = DISABLE;           /*溢出中断使能位 */
  66.     config.cntOverflowFreq = 0;                   /*溢出中断产生的频率与计数器频率的关系,0表示每次计数器溢出都产生中断,1表示间隔一次,以此类推 */
  67.     config.interruptEn = DISABLE;                  /*PWM总中断使能位  */
  68.     config.callBack = NULL;              /*中断回调函数 */

  69.     PWM_Init(PWM2, &config);

  70. }



app_pwm.h中实现了如下功能,定义了最大占空比宏:10000。

  1. /*
  2. @hehung
  3. 2023-6-17
  4. email: 1398660197@qq.com
  5. wechat: hehung95
  6. reproduced and please indicate the source @hehung
  7. */

  8. #ifndef APP_PWM_H__
  9. #define APP_PWM_H__

  10. #include "ac780x_pwm.h"
  11. #include "ac780x_pwm_reg.h"

  12. #define APP_PWM_MAX_DUTY_COUNT                 (10000U)

  13. extern void Pwm_Init(void);

  14. #endif /* APP_PWM_H__ */



2.2 主函数实现

主函数中实现了对LED1和LED2的驱动,主要是占空比的控制,LED1和LED2的占空比值正好相反,即LED1最亮的时候,LED2最暗,反之亦然。

设置了最大占空比为APP_PWM_MAX_DUTY_COUNT/2是因为一半占空比和满占空比的时候亮度变化不大,不便于观察,所以直接设置半占空比为最亮。

  1.     Pwm_Init();

  2.     while(1)
  3.     {
  4.         PWM_SetChannelCountValue(PWM2, 0, pwm_duty);
  5.         PWM_SetChannelCountValue(PWM2, 1, APP_PWM_MAX_DUTY_COUNT/2 - pwm_duty);


  6.         if ((pwm_duty >= APP_PWM_MAX_DUTY_COUNT/2) || (pwm_duty == 0))
  7.             pwm_flg ^= 1;

  8.         if (pwm_flg == 1)
  9.             pwm_duty += 50;
  10.         else
  11.             pwm_duty -= 50;

  12.         mdelay(10);
  13.     }



3 试验效果

见下面的动图,可见试验成功。
QQ图片20230617221254.gif




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

本版积分规则

10

主题

66

帖子

1

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