打印
[开发资料]

(分享)CW32定时器操作讲解——输入捕获

[复制链接]
1070|21
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
CW32系列MCU的GTIM、ATIM的每个定时器都带有至少4路独立的捕获 / 比较通道,输入捕获功能可以测量输入信号的脉冲宽度或者频率。当捕获比较通道 CHy 上信号发生跳变(上升沿或下降沿)时,硬件自动将当前计数寄存器 GTIMx_CNT 的值存放到对应通道的比较捕获寄存器 GTIMx_CCRy 中,完成一次捕获。通过连续几次捕获即可完成信号脉冲宽度或者频率的测量。
功能框图如下图所示:
各个通道上触发捕获的条件由比较捕获控制寄存器 GTIMx_CMMR 决定。
当发生一次捕获时,通道 CHy 比较捕获中断标志 GTIMx_ISR.CCy 被硬件置位,如果允许中断 ( 设置中断使能寄 存器 GTIMx_IER.CCy 为 1),CPU 将响应中断服务程序。退出中断服务程序之前,应设置中断标志清除寄存器 GTIMx_ICR.CCy 为 0 以清除该标志。
输入捕获来源
GTIM 的输入捕获来源可以是外部 GTIMx_CHy 引脚,也可以是片内其它外设,通过通用定时器输入捕获来源配置寄存器 SYSCTRL_GTIMxCAP 进行配置。当 SYSCTRL_GTIMxCAP.CHy 为 0x00 时,输入捕获信号的外部输入端口由 GPIO 复用功能寄存器 (GPIOx_AFRH 和 GPIOx_AFRL) 进行配置。当 SYSCTRL_GTIMxCAP.CHy 为 0x01 ~ 0x07 时,输入捕获信号来自片内其它外设,如下表所示:

这种配置下,可以在芯片内部实现外部输入的互联,例如将 UART 的 RXD 信号作为输入捕获来源,可以实现对 UART 波特率的自动检测。

实例演示

利用GTIM的输入捕获功能,测量PWM信号的周期和脉宽

1.初始化系统时钟
void RCC_Configuration(void)
{
__RCC_GTIM1_CLK_ENABLE();
__RCC_GPIOA_CLK_ENABLE();
RCC_HSI_Enable(RCC_HSIOSC_DIV6);
// 系统时钟设置为HSI,6分频,8MHz, PCLK、HCLK不分频, PCLK=HCLK=SysClk=8MHz
}

2.初始化GPIO
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.IT = GPIO_IT_NONE;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pins = GPIO_PIN_6 | GPIO_PIN_7;
GPIO_Init(CW_GPIOA, &GPIO_InitStruct);
PA06_AFx_GTIM1CH1();//设置PA06复用为GTIM1_CH1, 上升沿触发捕获
PA07_AFx_GTIM1CH2();//设置PA07复用为GTIM1_CH2,下降沿触发捕获。
}
3.配置中断服务程序
void NVIC_Configuration(void)
{
    __disable_irq();
    NVIC_EnableIRQ(GTIM1_IRQn);
    __enable_irq();
}

4.GTIM1中断服务程序:通道1的输入捕获中断获取计数值VALUE1,通道2的输入捕获中断获取计数值VALUE2,通道1的第2次输入捕获中断获取计数值VALUE3。则信号脉宽=VALUE2-VALUE1,信号周期=VALUE3-VALUE1。注意如果待测量信号的脉宽和周期较长,在计算时需要考虑定时器的溢出问题,详见定时器溢出中断处理内容。
void GTIM1_IRQHandler(void)
{
    GTIM1_IRQHandlerCallBack();
}
void GTIM1_IRQHandlerCallBack(void)
{
    static uint8_t stage = 0;
    static uint32_t cnt = 0;
    if (GTIM_GetITStatus(CW_GTIM1, GTIM_IT_OV))
    {
        GTIM_ClearITPendingBit(CW_GTIM1, GTIM_IT_OV);
        if (stage == 1)
        {
            cnt++;
        }
    }
    if (GTIM_GetITStatus(CW_GTIM1, GTIM_IT_CC1))
    {
        if (stage == 0)
        {
            PWMPeriod = GTIM_GetCapture1(CW_GTIM1);
            stage = 1;
        }
        else if (stage == 1)
        {
            PWMPeriod = GTIM_GetCapture1(CW_GTIM1) + cnt * 65536 - PWMPeriod;
            stage = 0;
            cnt = 0;
        }
        GTIM_ClearITPendingBit(CW_GTIM1, GTIM_IT_CC1);
    }
    if (GTIM_GetITStatus(CW_GTIM1, GTIM_IT_CC2))
    {
        if (stage == 1)
        {
            PWMWidth = GTIM_GetCapture2(CW_GTIM1) + cnt * 65536 - PWMPeriod;
        }
        GTIM_ClearITPendingBit(CW_GTIM1, GTIM_IT_CC2);
    }
}

5.主程序:使用GTIM1的CH1和CH2两个通道对PWM输入信号进行测量,在捕获中断服务程序中完成信号的周期和脉宽计算。
static uint32_t PWMPeriod = 0;
static uint32_t PWMWidth = 0;
int32_t main(void)
{
RCC_Configuration();//System Clocks Configuration
            GPIO_Configuration();//GPIO Configuration
            NVIC_Configuration();//NVIC Configuration
GTIM_InitTypeDef GTIM_InitStruct = {0};
GTIM_ICInitTypeDef GTIM_ICInitStruct = {0};
GTIM_InitStruct.Mode = GTIM_MODE_TIME; /*!< GTIM的模式选择。*/
GTIM_InitStruct.OneShotMode = GTIM_COUNT_CONTINUE;
/*!< GTIM的单次/连续计数模式选择。*/
GTIM_InitStruct.Prescaler = GTIM_PRESCALER_DIV1; /*!< GTIM的预分频系数。*/
GTIM_InitStruct.ReloadValue = 0xFFFF; /*!< GTIM的重载值。*/
GTIM_InitStruct.ToggleOutState = DISABLE;
GTIM_TimeBaseInit(CW_GTIM1, &GTIM_InitStruct); //GTIM的基础参数初始化

GTIM_ICInitStruct.CHx = GTIM_CHANNEL1;// GTIM 输入捕获的配置参数
GTIM_ICInitStruct.ICFilter = GTIM_CHx_FILTER_NONE;
GTIM_ICInitStruct.ICInvert = GTIM_CHx_INVERT_ON;
GTIM_ICInitStruct.ICPolarity = GTIM_ICPolarity_Rising;
GTIM_ICInit(CW_GTIM1, &GTIM_ICInitStruct);//输入捕获功能初始化

GTIM_ICInitStruct.CHx = GTIM_CHANNEL2;
GTIM_ICInitStruct.ICPolarity = GTIM_ICPolarity_Falling;
GTIM_ICInit(CW_GTIM1, &GTIM_ICInitStruct);

GTIM_ITConfig(CW_GTIM1, GTIM_IT_CC1 | GTIM_IT_CC2 | GTIM_IT_OV, ENABLE);
GTIM_Cmd(CW_GTIM1, ENABLE);
while (1)
    {
    }
}

使用特权

评论回复
沙发
豌豆爹|  楼主 | 2023-2-16 09:22 | 只看该作者
6.演示说明:

将同一个PWM输入信号引入到PA06和PA07上,运行程序,使用GTIM1的CH1和CH2两个通道对PWM输入信号的脉宽和周期进行测量。

使用特权

评论回复
板凳
updownq| | 2023-3-2 10:10 | 只看该作者
通过比比较器实现的吗?              

使用特权

评论回复
地板
51xlf| | 2023-3-2 10:48 | 只看该作者
所有的定时器都有这个捕获功能吗              

使用特权

评论回复
5
ingramward| | 2023-3-2 16:16 | 只看该作者
这个cw32有多少个定时器可以使用

使用特权

评论回复
6
hudi008| | 2023-3-2 16:37 | 只看该作者
GTIM、ATIM这个有什么不同?

使用特权

评论回复
7
juliestephen| | 2023-3-3 21:35 | 只看该作者
定时器捕获功能怎么编程的?              

使用特权

评论回复
8
uytyu| | 2023-3-3 21:47 | 只看该作者
这个捕获最大的时间范围是多少?              

使用特权

评论回复
9
biechedan| | 2023-3-4 13:17 | 只看该作者
这个捕获的时候可以捕获上升或者下降边沿吗

使用特权

评论回复
10
belindagraham| | 2023-3-4 19:39 | 只看该作者
这个输入信息有什么要求?              

使用特权

评论回复
11
fengm| | 2023-3-4 19:45 | 只看该作者
cw32的定时器可以读取编码器的吗?

使用特权

评论回复
12
phoenixwhite| | 2023-3-5 10:21 | 只看该作者
这个捕获的时候可以捕获上升或者下降边沿吗

使用特权

评论回复
13
kmzuaz| | 2023-3-5 10:40 | 只看该作者
这个输入信息有什么要求?              

使用特权

评论回复
评论
pssyx 2023-3-8 09:48 回复TA
输入信号频率不能大于定时器的计数时钟频率的1/2。 
14
pentruman| | 2023-3-5 10:54 | 只看该作者
cw32的定时器可以读取编码器的吗?

使用特权

评论回复
15
uptown| | 2023-3-7 22:09 | 只看该作者
最大捕获的时长是多少?              

使用特权

评论回复
16
hudi008| | 2023-3-7 22:20 | 只看该作者
定时器的功能有什么不同的吗?              

使用特权

评论回复
17
pssyx| | 2023-3-8 09:37 | 只看该作者
51xlf 发表于 2023-3-2 10:48
所有的定时器都有这个捕获功能吗

通用定时器(GTIM)和高级定时器(ATIM)都有捕获功能。基本定时器(BTIM)的触发启动模式也可以实现此捕获功能。

使用特权

评论回复
18
pssyx| | 2023-3-8 09:40 | 只看该作者
uptown 发表于 2023-3-7 22:09
最大捕获的时长是多少?

最大捕获时长=65536*定时器的计数时钟周期。

使用特权

评论回复
19
pssyx| | 2023-3-8 09:41 | 只看该作者
pentruman 发表于 2023-3-5 10:54
cw32的定时器可以读取编码器的吗?

CW32 MCU的高级定时器(ATIM)支持正交编码计数功能。

使用特权

评论回复
20
pssyx| | 2023-3-8 09:44 | 只看该作者
phoenixwhite 发表于 2023-3-5 10:21
这个捕获的时候可以捕获上升或者下降边沿吗

支持上升沿捕获、下降沿捕获、上下沿同时捕获等3种触发条件。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

517

主题

1984

帖子

5

粉丝