本帖最后由 abner_ma 于 2023-7-2 21:13 编辑
杰发科技AC7802x TIMER 模块功能强大:
定时器能够生成中断
定时器能够生成触发脉冲
每个定时器都具有独立的超时周期
支持 4 个 32bit 定时器
支持链( Link) 模式
捕获功能是高级定时器的重要功能之一。工作原理:在输入捕获模式下,当捕获单元捕捉到外部信号的有效边沿(上升沿/下降 沿/双边沿)时,将计数器的当前值锁存到捕获/比较寄存器TIMx_CCR, 供用户读取。用途:用于测量脉冲信号PWM参数,比如周期和频率,占空比等关键参数。
程序设计:
- /******************************************************************************
- * @version: V1.0.0 demo
- ******************************************************************************/
-
- /*!
- * [url=home.php?mod=space&uid=288409]@file[/url] timer_capture_pwm.c
- *
- * [url=home.php?mod=space&uid=247401]@brief[/url] 定时器捕捉PWM配置源文件
- *
- */
- /* =========================================== Includes =========================================== */
- #include "string.h"
- #include "ac780x_timer.h"
- #include "ac780x_timer_reg.h"
- #include "ac780x_gpio.h"
- #include "ac780x_pwm.h"
- #include "timer_capture_pwm.h"
- /* ============================================ Define ============================================ */
- #define APB_CLK (APB_BUS_FREQ) /*! APB时钟定义 */
- #define FREQ (1000) /*! 频率为1k */
- #define PWM_PRES (0) /*! PWM预分频 */
- #define MOD_PWM (APB_CLK / FREQ / (PWM_PRES + 1)) /*! PWM模值 */
- /* =========================================== Typedef ============================================ */
- /* ========================================== Variables =========================================== */
- uint32_t g_pwm_DownMomentOne = 0; /* PWM波第一次出现下降沿 */
- uint32_t g_pwm_DownMomentTwo = 0; /* PWM波第二次出现下降沿 */
- uint32_t g_pwm_UpMoment = 0; /* PWM波上升沿降沿 */
- uint32_t g_pwm_Period = 0; /* PWM频率 */
- uint32_t g_pwm_Duty = 0; /* PWM占空比 */
- /* ==================================== Functions declaration ===================================== */
- /* ====================================== Functions define ======================================== */
- /*!
- *
- * [url=home.php?mod=space&uid=247401]@brief[/url] 初始化TIMER0,产生100s计时
- *
- * @param[in] none
- * [url=home.php?mod=space&uid=266161]@return[/url] none
- */
- void Timer0_Init(void)
- {
- TIMER_ConfigType timerConfig0;
-
- memset(&timerConfig0, 0, sizeof(timerConfig0));
-
- /* TIMER0配置函数 */
- timerConfig0.periodValue = DelayS(100); /*! 100s计时 */
- timerConfig0.interruptEn = DISABLE; /*! 禁能定时器中断 */
- timerConfig0.linkModeEn = DISABLE; /*! 禁能链接模式 */
- timerConfig0.timerEn = DISABLE; /*! 先关掉定时器,在PWM第一个下降沿开,第二个下降沿关闭,以使得计时时间更精确,具体位置在GPIO中断处理函数中 */
- timerConfig0.callBack = NULL; /*! 回调函数为空 */
- TIMER_Init(TIMER_CHANNEL0, &timerConfig0); /*! TIMER初始化函数生效 */
- mdelay(10); /*! 防止在定时器溢出后产生误差 */
- }
- /**
- *
- * @brief GPIO中断处理函数
- *
- * @param device:
- * GPIOx: GPIO type structure pointer:
- * -GPIOA
- * -GPIOB
- * wpara:
- * GPIO_Pin: GPIO_Pin type num:
- * -GPIO_PIN0
- * -GPIO_PIN1
- * -GPIO_PIN2
- * - ...
- * -GPIO_PIN15
- * lpara:0
- * [url=home.php?mod=space&uid=266161]@return[/url] none
- *
- */
- void PWM_Capture_ByTimer(void *device, uint32_t wpara, uint32_t lpara)
- {
- static uint8_t pwm_EdgCount = 0;
-
- if(pwm_EdgCount == 0)
- {
- TIMER_SetChannel(TIMER_CHANNEL0, ENABLE); /*! 此处打开定时器 */
- if (GPIO_GetPinLevel(GPIOA,GPIO_PIN1) == 0) /*! PWM下降沿 */
- {
- g_pwm_DownMomentOne = TIMER_GetCurrentValue(TIMER_CHANNEL0);
- pwm_EdgCount = 1;
- }
- }
- else if(pwm_EdgCount == 1)
- {
- if (GPIO_GetPinLevel(GPIOA,GPIO_PIN1) == 1) /*! PWM上升沿 */
- {
- g_pwm_UpMoment = TIMER_GetCurrentValue(TIMER_CHANNEL0);
- pwm_EdgCount = 2;
- }
- }
- else if(pwm_EdgCount == 2)
- {
- if(GPIO_GetPinLevel(GPIOA,GPIO_PIN1) == 0) /*! PWM下降沿 */
- {
- TIMER_SetChannel(TIMER_CHANNEL0, DISABLE); /*!此处关闭定时器 */
- g_pwm_DownMomentTwo = TIMER_GetCurrentValue(TIMER_CHANNEL0);
- pwm_EdgCount = 0;
- }
- }
-
- if((g_pwm_UpMoment < g_pwm_DownMomentOne)&&(g_pwm_DownMomentTwo < g_pwm_UpMoment)) /*! Timer为向下计数 */
- {
- g_pwm_Period = (g_pwm_DownMomentOne - g_pwm_DownMomentTwo)/16; /*! 16个计数为1us */
- g_pwm_Duty = (100 * (g_pwm_UpMoment - g_pwm_DownMomentTwo))/(g_pwm_DownMomentOne - g_pwm_DownMomentTwo);
- }
- }
- /*!
- * @brief 初始化PWM捕获GPIO
- *
- * @param[in] none
- * @return none
- */
- void Capture_Gpio_Init(void)
- {
- GPIO_SetFunc(GPIOA,GPIO_PIN1,GPIO_FUN0); /*! PA1引脚配置为GPIO模式,用于采集端口 */
-
- GPIO_SetDir(GPIOA,GPIO_PIN1,GPIO_IN); /*! PA1引脚配置为输入模式,用于采集端口 */
-
- GPIO_EnableExtInterrupt(GPIOA,GPIO_PIN1, EXTI_TRIGGER_RISING_FALLING); /*! 使能外部中断,上升沿下降沿都中断 */
-
- GPIO_SetCallback(GPIO_PIN1, PWM_Capture_ByTimer); /*! 设置中断回调函数 */
- }
- /**
- *
- * @brief PA2,PWM2_CH1,PMW输出频率为1K,占空比为25%
- *
- * @param[in] none
- * @return none
- */
- void PWM_Generate(void)
- {
- GPIO_SetFunc(GPIOA, GPIO_PIN2, GPIO_FUN1); /*! PWM2_CH0 */
- PWM_IndependentChConfig independentChConfig[1]; /*! 独立模式相关结构体 */
- PWM_ModulationConfigType pwmConfig; /*! PWM模式相关结构体 */
- PWM_ConfigType config; /*! PWM模块结构体 */
-
- memset(&independentChConfig, 0, sizeof(independentChConfig));
- memset(&pwmConfig, 0, sizeof(pwmConfig));
- memset(&config, 0, sizeof(config));
-
- independentChConfig[0].channel = PWM_CH_1; /*! 通道1 */
- independentChConfig[0].chValue = MOD_PWM >> 2; /*! 通道1 channel值,输出占空比 = chValue / maxValue = 25% */
- independentChConfig[0].levelMode = PWM_HIGH_TRUE; /*! 输出PWM高有效 */
- independentChConfig[0].polarity = PWM_OUTPUT_POLARITY_ACTIVE_HIGH; /*! 输出极性高有效,PWM mask后PWM输出低电平 */
- independentChConfig[0].interruptEn = DISABLE; /*! PWM通道匹配中断使能位 */
- independentChConfig[0].initLevel = PWM_LOW_LEVEL; /*! PWM初始电平输出为低,该配置受initChOutputEn控制,决定PWM计数器未工作前PWM口的输出电平值 */
- independentChConfig[0].triggerEn = DISABLE; /*! 通道外部触发使能 */
-
- /*! modulation mode config */
- pwmConfig.countMode = PWM_UP_COUNT; /*! PWM计数器模式 (不同的计数模式频率及占空比计算方式不同) */
- pwmConfig.independentChannelNum = 1; /*! 独立通道数 */
- pwmConfig.combineChannelNum = 0; /*! 组合对数 */
- pwmConfig.independentChConfig = independentChConfig; /*! 独立通道配置变量地址赋值 */
- pwmConfig.initChOutputEn = ENABLE; /*! 使能初始化通道输出 */
- pwmConfig.initTriggerEn = DISABLE; /*! 通道外部触发使能 */
-
- /*! pwm config */
- config.mode = PWM_MODE_MODULATION; /*! PWM模块配置为PWM模式 */
- config.initModeStruct = &pwmConfig; /*! PWM配置结构体地址赋值 */
- config.clkSource = PWM_CLK_SOURCE_APB; /*! PWM时钟源配置 */
- config.clkPsc = PWM_PRES; /*! PWM时钟源分频 */
- config.initValue = 0; /*! 计数器初始寄存器值 */
- config.maxValue = MOD_PWM - 1; /*! PWM计数器最大值 */
- config.overflowInterrupEn = DISABLE; /*! 计数器溢出中断禁能 */
- config.cntOverflowFreq = 0; /*! CNTOF中断产生的频率与计数器频率的关系(0-127), 0表示每次计数器溢出都产生溢出中断,1表示间隔1次,2表示间隔2次,以此类推 */
- config.interruptEn = DISABLE; /*! PWM中断使能 */
-
- PWM_Init(PWM2, &config); /*! 配置初始化生效 */
- }
- /*!
- * @brief PWM捕捉函数
- *
- * @param[in] none
- * @return none
- */
- void TIMER_PWM_Capture(void)
- {
- Capture_Gpio_Init(); /*! 初始化PWM捕获GPIO */
- Timer0_Init(); /*! 定时器配置函数 */
- PWM_Generate(); /*! PWM输出函数 */
- }
1、 通过 Timer 实现 GPIO 捕获 PWM 频率及占空比
2、 例程中将 PA2 设置为 PWM 口, 输出频率为 1KHz, 占空 比为 25%的 PWM;
3、 将 PA1 设置成 GPIO 口, 使能 GPIO 中断, 设置为 EXTI_TRIGGER_RISING_FALLING, 上升沿下降沿都产 生中断;
4、 将 PA2 与 PA1 连接测试如下:调试debug:
测评结果:精度范围内符合设计值。
|