打印
[开发资料]

cw32l010怎么使得定时器尽量准确?

[复制链接]
841|56
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
fox1|  楼主 | 2024-12-27 20:59 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 fox1 于 2024-12-27 21:20 编辑

我是使用BTIM1设置100us定时,用查询方式,反转的频率在117us左右,怎么尽量减少这个误差?主频4mhz
代码如下:PSC 是3 也就是分完频1MHZ



使用特权

评论回复
沙发
fox1|  楼主 | 2024-12-27 21:01 | 只看该作者
void testBTIM(void)
{
    GPIO_InitTypeDef GPIO_InitStructure = {0};
    /* Configure the GPIO_LED pin */
    GPIO_InitStructure.Pins = GPIO_PIN_3;
    GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_Init(CW_GPIOB, &GPIO_InitStructure);
    __SYSCTRL_BTIM123_CLK_ENABLE();
    CW_SYSCTRL->APBEN2 |= SYSCTRL_KEY | SYSCTRL_APBEN2_BTIM123_Msk;
        CW_BTIM1->SMCR_f.SMS = 0;
    CW_BTIM1->CR1_f.ONESHOT = 1;
    CW_BTIM1->PSC = 3;
   

    while (1)
    {
        BTIM1_DELAY_US(100);
        PB03_TOG();
        /* code */
    }
}

// BTIM1 基地址
static const uint32_t BTIM1_BASE = 0x40004800;

// 定义 BTIM1 寄存器地址(static 限制作用域)
// 定义 BTIM1 寄存器地址
#define BTIM1_CNT (*(volatile uint32_t *)(BTIM1_BASE + 0x24)) // 计数寄存器
#define BTIM1_CR1 (*(volatile uint32_t *)(BTIM1_BASE + 0x00)) // 控制寄存器 1
#define BTIM1_ARR (*(volatile uint32_t *)(BTIM1_BASE + 0x2C)) // 计数寄存器
void BTIM1_DELAY_US(uint16_t us)
{

    BTIM1_ARR = us;
    // CW_BTIM1->ARR = us;
    // CW_BTIM1->CNT_f.CNT = 0;
    // CW_BTIM1->CR1_f.EN = 1;
    BTIM1_CNT &= 0xFFFF0000;
    BTIM1_CR1 |= 0x01;

    while (1)
    {
        if (CW_BTIM1->ISR_f.UIF == 1)
        {
            CW_BTIM1->ISR;
            CW_BTIM1->ICR_f.UIF = 0;
            break;
        }
        /* code */
    }
}

使用特权

评论回复
板凳
fox1|  楼主 | 2024-12-27 21:21 | 只看该作者

image.png

使用特权

评论回复
地板
fox1|  楼主 | 2024-12-27 21:21 | 只看该作者

image.png

image.png

使用特权

评论回复
5
cooldog123pp| | 2024-12-28 20:42 | 只看该作者
感觉需要参考一下官方的demo,现在国产芯片太多太杂了,你问的型号可能用的很少,最好有原厂支持。

使用特权

评论回复
6
pssyx| | 2024-12-30 10:34 | 只看该作者
fox1 发表于 2024-12-27 21:01
void testBTIM(void)
{
    GPIO_InitTypeDef GPIO_InitStructure = {0};

试试如下操作,能减小定时误差:
...
CW_BTIM1->CR1_f.ONESHOT = 0; //BTIM初始化为连续计数模式
...

void BTIM1_DELAY_US(uint16_t us)
{
    CW_BTIM1->CNT = 0;
    while(CW_BTIM1->CNT < us);  
}
提高HCLK频率,可以减小调用BTIM1_DELAY_US()的时间,或者直接将子函数中的那两句定义为宏。

使用特权

评论回复
7
modesty3jonah| | 2025-1-3 11:21 | 只看该作者
使用系统内部的时钟源,通常是较为稳定的时钟,适合用于高精度定时。

使用特权

评论回复
8
jkl21| | 2025-1-3 12:35 | 只看该作者
选择合适的计数模式,如单次计数或连续计数模式。
通过控制寄存器BTIMx_CR1的ONESHOT位域来选择计数模式。

使用特权

评论回复
9
rosemoore| | 2025-1-3 13:11 | 只看该作者
如果可能的话,可以定期对定时器进行校准,以确保其精度。这可以通过比较定时器的输出与一个已知的精确时钟源来实现。

使用特权

评论回复
10
sanfuzi| | 2025-1-3 15:26 | 只看该作者
CW32L010 有多种时钟源可供选择,如内部高速 RC 振荡器(HSI)、外部高速晶体振荡器(HSE)等。为了使定时器更准确,在对精度要求较高的应用中,优先考虑使用外部高速晶体振荡器。外部晶体振荡器通常具有更高的频率稳定性,能够提供更精准的时钟信号。例如,一个稳定的 8MHz 外部晶振,其频率偏差相较于内部 RC 振荡器要小很多。

使用特权

评论回复
11
zerorobert| | 2025-1-3 16:29 | 只看该作者
如果应用对定时精度要求较高,可以考虑使用高级定时器(如ATIM)而不是基本定时器(BTIM)。高级定时器通常具有更多的功能和更高的精度。

使用特权

评论回复
12
pmp| | 2025-1-3 16:57 | 只看该作者
在定时器中断服务程序中,尽量避免使用其他中断,以减少中断处理时间,提高定时器的响应速度和精度。

使用特权

评论回复
13
geraldbetty| | 2025-1-3 19:59 | 只看该作者
合理布局电源线路和信号线路,以减少电源噪声和信号干扰。
使用屏蔽和接地技术来减少外部干扰。

使用特权

评论回复
14
10299823| | 2025-1-3 23:00 | 只看该作者
如果需要更高的精度或与其他模块同步,可以考虑使用外部时钟源。

使用特权

评论回复
15
hearstnorman323| | 2025-1-4 02:03 | 只看该作者
CW32L010提供了多种定时器,选择分辨率更高的定时器(如16位高级控制定时器)以提高定时精度。

使用特权

评论回复
16
elsaflower| | 2025-1-4 07:42 | 只看该作者
在使用中断方式处理定时事件,尽量减小中断服务程序中的代码量,以减少响应时间和抖动。同时,确保中断优先级设置得当,以便快速响应定时器中断。

使用特权

评论回复
17
lzbf| | 2025-1-5 09:05 | 只看该作者
如果使用内部RC振荡器作为时钟源,可以通过软件校准来提高其精度。CW32L010提供了内部RC振荡器的校准功能。

使用特权

评论回复
18
10299823| | 2025-1-5 09:32 | 只看该作者
如果需要频繁更新定时器参数或读取计数值,考虑使用DMA来减少CPU干预,从而提高定时器的稳定性。

使用特权

评论回复
19
tabmone| | 2025-1-5 10:01 | 只看该作者
通过预分频器将高频的系统时钟降低到计数器所能承受的频率范围,从而提高计数器的精度和稳定性。选择合适的分频系数可以实现更细粒度的定时

使用特权

评论回复
20
loutin| | 2025-1-5 10:31 | 只看该作者
正确设置定时器中断的优先级。在系统中有多个中断源的情况下,为定时器中断分配合理的优先级,确保定时器中断能够及时响应。如果定时器中断被其他高优先级中断长时间延迟,会导致定时出现偏差。例如,将定时器中断优先级设置为较高的级别,使得它在需要响应时能够快速进入中断服务程序进行定时处理。

使用特权

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

本版积分规则

8

主题

32

帖子

0

粉丝