OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5923|回复: 12

最近测试类似的STM32架构的TIMER,分享一下。~~勿喷,新手多指教!!代码二楼补上了

[复制链接]

5

主题

31

帖子

0

精华

初级会员

Rank: 2

积分
74
金钱
74
注册时间
2015-1-14
在线时间
1 小时
发表于 2015-1-28 17:52:36 | 显示全部楼层 |阅读模式
由于全部复制的时候图片不能显示所以偷懒全部截图了。

还有一个非常重要的事情,像这样子操作寄存的时候,要注意软件和硬件是并行的,清某些寄存器的时候,不是写0马上就清零了。

有什么不对的地方希望大家能帮忙指正,小弟在此谢谢了。

PSC预分频:
    timer的时钟由总线上取得,但是由于需要的周期大于65535/tim的clock,所以需要采用预分频。分频系数1-65536,timer时钟变成(PSC+1)/系统clock,最大周期也相应的延长至65535*(PSC+1)/系统的clock。
CNT计数器上升模式:
    也就是计数器向上计数,根据时钟频率来确定周期,实质上ARR寄存器中的数字就是确定周期。
CNT计数器下降模式:
    也就是计数器下降计数,根据时钟频率来确定周期,实质上ARR寄存器中的数字就是确定周期。
CNT中心对齐模式:
    模式1:计数器交替进行递增计数和递减计数。仅当计数器递减计数的时候,才会更新输出比较中断标志位(SR寄存器中CCxIF位)。目前没有想到在应用的时候有什么意义????(可能是当PWM周期是双数的时候可以读SR寄存器来进中断)
    模式2:计数器交替进行递增计数和递减计数。仅当计数器递增计数的时候,才会更新输出比较中断标志位(SR寄存器中CCxIF位)。目前没有想到在应用的时候有什么意义????(可能是当PWM周期是单数的时候可以读SR寄存器来进中断)
    模式3:计数器交替进行递增计数和递减计数。计数器递增计数和递减计数的时候,都会更新输出比较中断标志位(SR寄存器中CCxIF位)。目前没有想到在应用的时候有什么意义????
重复计数器模式:
    重复计数器就是产生RCR+1次上溢或者下溢时间的时候才会更新SR中的UIF位。
输入捕获模式:
    用以捕获PWM的沿跳变,以达到测量PWM的占空比和周期。
强制输出模式:
    强制输出高低电平,发生异常时的简单处理,或者根据需要的一种控制方法。
PWM模式:
    为了产生相应的PWM波形。
互不输出和死区插入模式:
    全桥驱动电机的控制,为了防止同时输出高。
断路模式:
    就是一种异常的处理方式。(没有太具体的测试)
外部事件清除OCxREF模式:
    外部发生了某种变化,来改变timer的输出。
六步PWM模式:
    应该是在无刷电机上的应用。
单脉冲模式:
    简单的实现定时功能。
编码器模式:
    可以通过测量,可以知道编码器的角度值,速度和方向。
连接霍尔传感器模式:
    根据外部电路的变化来采取相应的计数方式,一般与外部触发一起使用。

寄存器的具体说明手册中说的很是详细。

测试流程。采用的是CHIBOS

tim的上升计数,具体是看时钟是否准确和计数的方向。
    
当CNT的数值<5的时候说明计数器的更新值从零开始。

tim的下降计数

ARR是否预装载

tim产生UEV的更新方式

tim的中心模式1

tim的中心模式2

tim中心模式3

重复计数器

强制输出的测试

强制输出和死区插入

清除OCxREF

单脉冲

六步PWM

外部触发



PWM

编码器

输入捕获

cmd_tim.c
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

5

主题

31

帖子

0

精华

初级会员

Rank: 2

积分
74
金钱
74
注册时间
2015-1-14
在线时间
1 小时
 楼主| 发表于 2015-1-28 18:02:25 | 显示全部楼层
int test_tim0_up()
{
    HS_TIM0 -> PSC = 0;
    HS_TIM0 -> ARR = 60010;
    HS_TIM0 -> CR1 = 1;
    while(!(HS_TIM0 -> SR & 1));
    return (HS_TIM0 -> CNT < 5);
}

int test_tim0_down()
{
    int loop = 10;
    HS_TIM0 -> PSC = 0;
    HS_TIM0 -> ARR = 60010;
    HS_TIM0 -> CR1 = 0x11;
    while(!(HS_TIM0 -> SR & 1));
    while(loop--);
    return (HS_TIM0 -> CNT < 60010 && HS_TIM0 -> CNT > 10005);
}

int test_tim0_arr_buffrerd()
{
    int test_big_down = 0, test_small_down = 0, loop = 10;
    HS_TIM0 -> PSC = 0;
    HS_TIM0 -> ARR = 60010;
    HS_TIM0 -> CR1 = 0x11;
    while(!(HS_TIM0 -> SR & 1));
    HS_TIM0 -> SR = 0;
    while(loop--);
    test_big_down = (HS_TIM0 -> CNT < 60010 && HS_TIM0 -> CNT > 10000);
    HS_TIM0 -> CR1 |= 0x0080;
    HS_TIM0 -> ARR = 600;
    while(!(HS_TIM0 -> SR & 1));
    test_small_down = (HS_TIM0 -> CNT < 600);
    return test_small_down && test_big_down;
}

int test_tim0_updata_source()
{
    HS_TIM0 -> CR1 = 4;
    HS_TIM0 -> EGR = 1;
    while(HS_TIM0 -> SR & 1){
        return 0;
    }
    return 1;
}

int test_tim0_mid_one()
{
    HS_TIM0 -> PSC = 0;
    HS_TIM0 -> ARR = 60000;
    HS_TIM0 -> CR1 |= 0x0020;
    HS_TIM0 -> CCR[0] = 50000;
    HS_TIM0 -> CR1 |= 0x0001;
    while(!(HS_TIM0 -> SR & 2));
    return HS_TIM0 -> CR1 & 0x10;
}

int test_tim0_mid_two()
{
    HS_TIM0 -> PSC = 0;
    HS_TIM0 -> ARR = 60000;
    HS_TIM0 -> CR1 |= 0x0040;
    HS_TIM0 -> CCR[0] = 50000;
    HS_TIM0 -> CR1 |= 0x0001;
    while(!(HS_TIM0 -> SR & 2));
    return !(HS_TIM0 -> CR1 & 0x10);
}

int test_tim0_mid_three()
{
    int flag = 0;
    HS_TIM0 -> PSC = 0;
    HS_TIM0 -> ARR = 60000;
    HS_TIM0 -> CR1 |= 0x0060;
    HS_TIM0 -> CCR[0] = 30000;
    HS_TIM0 -> CR1 |= 0x0001;
    while(!(HS_TIM0 -> SR & 2));
    flag = !(HS_TIM0 -> CR1 & 0x10);
    HS_TIM0 -> SR &= 0x0d;
    while(!(HS_TIM0 -> SR & 2));
    return flag && (HS_TIM0 -> CR1 & 0x10);
}

int test_tim0_repeat_up()//手动测试大约10S
{
    HS_TIM0 -> PSC = 16000;
    HS_TIM0 -> ARR = 5000;
    HS_TIM0 -> RCR = 1;
    HS_TIM0 -> EGR = 1;
    while(!(HS_TIM0 -> SR & 1));
    HS_TIM0 -> SR = 0;
    HS_TIM0 -> CR1 = 1;
    while(!(HS_TIM0 -> SR & 1));
    return 1;
}

void test_tim0_OCM_001()
{
    HS_TIM0 -> PSC = 0;
    HS_TIM0 -> ARR = 5000;
    HS_TIM0 -> CCR[0] = 2500;
    HS_TIM0 -> CCR[1] = 2500;
    HS_TIM0 -> CCR[2] = 2500;
    HS_TIM0 -> CCR[3] = 2500;
    HS_TIM0 -> CCMR1 |= 0x6060;
    HS_TIM0 -> CCMR2 |= 0x6060;
    HS_TIM0 -> CCER |= 0x1111;
    HS_TIM0 -> BDTR |= 0x8000;
    HS_TIM0 -> CR1 = 1;

    chThdSleepSeconds(3);

    HS_TIM0 -> CCMR1 = 0x1010;
    HS_TIM0 -> CCMR2 = 0x1010;
}

void test_tim0_OCM_010()
{
    HS_TIM0 -> PSC = 0;
    HS_TIM0 -> ARR = 5000;
    HS_TIM0 -> CCR[0] = 2500;
    HS_TIM0 -> CCR[1] = 2500;
    HS_TIM0 -> CCR[2] = 2500;
    HS_TIM0 -> CCR[3] = 2500;
    HS_TIM0 -> CCMR1 |= 0x6060;
    HS_TIM0 -> CCMR2 |= 0x6060;
    HS_TIM0 -> CCER |= 0x1111;
    HS_TIM0 -> BDTR |= 0x8000;
    HS_TIM0 -> CR1 = 1;

    chThdSleepSeconds(3);

    HS_TIM0 -> CCMR1 = 0x2020;
    HS_TIM0 -> CCMR2 = 0x2020;
}

void test_tim0_OCM_011()
{
    HS_TIM0 -> PSC = 0;
    HS_TIM0 -> ARR = 5000;
    HS_TIM0 -> CCR[0] = 2500;
    HS_TIM0 -> CCR[1] = 2500;
    HS_TIM0 -> CCR[2] = 2500;
    HS_TIM0 -> CCR[3] = 2500;
    HS_TIM0 -> CCMR1 |= 0x1010;
    HS_TIM0 -> CCMR2 |= 0x1010;
    HS_TIM0 -> CCER |= 0x1111;
    HS_TIM0 -> BDTR |= 0x8000;
    HS_TIM0 -> CR1 = 1;

    chThdSleepSeconds(3);

    HS_TIM0 -> CCMR1 = 0x3030;
    HS_TIM0 -> CCMR2 = 0x3030;
}

void test_tim0_OCM_100()
{
    HS_TIM0 -> PSC = 0;
    HS_TIM0 -> ARR = 5000;
    HS_TIM0 -> CCR[0] = 2500;
    HS_TIM0 -> CCR[1] = 2500;
    HS_TIM0 -> CCR[2] = 2500;
    HS_TIM0 -> CCR[3] = 2500;
    HS_TIM0 -> CCMR1 |= 0x6060;
    HS_TIM0 -> CCMR2 |= 0x6060;
    HS_TIM0 -> CCER |= 0x1111;
    HS_TIM0 -> BDTR |= 0x8000;
    HS_TIM0 -> CR1 = 1;

    chThdSleepSeconds(3);

    HS_TIM0 -> CCMR1 = 0x4040;
    HS_TIM0 -> CCMR2 = 0x4040;
}

void test_tim0_six_step_pwm()
{
    HS_TIM0 -> PSC = 0;
    HS_TIM0 -> CR2 = 1;
    HS_TIM0 -> CCER |= 0x555;
    HS_TIM0 -> BDTR |= 0x8000;
    while(1){
        //ONE
        HS_TIM0 -> CCMR1 = 0x4050;
        HS_TIM0 -> CCMR2 = 0x0050;
        test_tim0_one_pluse_delay(160);
        while(!(HS_TIM0 -> SR & 1));
        HS_TIM0 -> EGR |= 0x0020;
        HS_TIM0 -> SR = 0;

        //TWO
        HS_TIM0 -> CCMR1 = 0x4050;
        HS_TIM0 -> CCMR2 = 0x0040;
        test_tim0_one_pluse_delay(160);
        while(!(HS_TIM0 -> SR & 1));
        HS_TIM0 -> EGR |= 0x0020;
        HS_TIM0 -> SR = 0;

        //THREE
        HS_TIM0 -> CCMR1 = 0x5050;
        HS_TIM0 -> CCMR2 = 0x0040;
        test_tim0_one_pluse_delay(160);
        while(!(HS_TIM0 -> SR & 1));
        HS_TIM0 -> EGR |= 0x0020;
        HS_TIM0 -> SR = 0;

        //FOUR
        HS_TIM0 -> CCMR1 = 0x5040;
        HS_TIM0 -> CCMR2 = 0x0040;
        test_tim0_one_pluse_delay(160);
        while(!(HS_TIM0 -> SR & 1));
        HS_TIM0 -> EGR |= 0x0020;
        HS_TIM0 -> SR = 0;

        //FIVE
        HS_TIM0 -> CCMR1 = 0x5040;
        HS_TIM0 -> CCMR2 = 0x0050;
        test_tim0_one_pluse_delay(160);
        while(!(HS_TIM0 -> SR & 1));
        HS_TIM0 -> EGR |= 0x0020;
        HS_TIM0 -> SR = 0;

        //SIX
        HS_TIM0 -> CCMR1 = 0x4040;
        HS_TIM0 -> CCMR2 = 0x0050;
        test_tim0_one_pluse_delay(160);
        while(!(HS_TIM0 -> SR & 1));
        HS_TIM0 -> EGR |= 0x0020;
        HS_TIM0 -> SR = 0;
    }
}
int test_tim0_XOR_reset()
{
    //tim1  cc1   pwm  -_- tim0  cc1  cc2  cc3  XOR
    HS_TIM1 -> PSC = 100;
    HS_TIM1 -> ARR = 10000;
    HS_TIM1 -> CCR[3] = 5000;
    HS_TIM1 -> CCMR2 |= 0x6000;
    HS_TIM1 -> CCER = 0x1000;
    HS_TIM1 -> BDTR = 0x8000;

    HS_TIM0 -> PSC = 100;
    HS_TIM0 -> CR2 |= 0x0080;
    HS_TIM0 -> CCMR1 |= 0x0101;
    HS_TIM0 -> CCMR2 |= 0x0001;
    HS_TIM0 -> SMCR |=0x0044;
    HS_TIM0 -> ARR |= 0xffff;
    HS_TIM0 -> CR1 = 1;

    HS_TIM1 -> CR1 = 1;

    while(!(HS_TIM1 -> SR & 1));

    chThdSleepMilliseconds(1);//软件和硬件是并行关系,所以需要等待硬件反应。

    return HS_TIM0 -> CNT < 1000;
}

int test_tim0_XOR_gated()
{
    int test_num = 0;
    //tim1  cc1   pwm  _-_ tim0  cc1  cc2  cc3  XOR
    //tim0  cc1 cc2  high
    HS_TIM1 -> PSC = 100 ;
    HS_TIM1 -> ARR = 10000;
    HS_TIM1 -> CCR[0] = 5000;
    HS_TIM1 -> CCMR1 |= 0x60;
    HS_TIM1 -> CCER = 1;
    HS_TIM1 -> BDTR = 0x8000;
    HS_TIM1 -> CR1 = 9;

    HS_TIM0 -> PSC = 100;
    HS_TIM0 -> CR2 |= 0x0080;
    HS_TIM0 -> CCMR1 |= 0x0101;
    HS_TIM0 -> CCMR2 |= 0x0001;
    HS_TIM0 -> SMCR |=0x0045;
    HS_TIM0 -> ARR |= 0xffff;

    while(!(HS_TIM1 -> SR & 1));
    test_num = HS_TIM0 -> CNT;
    chThdSleepMilliseconds(2);
    return test_num == HS_TIM0 -> CNT;
}
int test_tim0_XOR_trigger()
{
    //tim1  cc1   pwm  _-_ tim0  cc1  cc2  cc3  XOR
    //tim0  cc1 cc2  high
    HS_TIM1 -> PSC = 0;
    HS_TIM1 -> ARR = 10000;
    HS_TIM1 -> CCR[0] = 5000;
    HS_TIM1 -> CCMR1 |= 0x60;
    HS_TIM1 -> CCER = 1;
    HS_TIM1 -> BDTR = 0x8000;
    HS_TIM1 -> CR1 = 9;

    HS_TIM0 -> PSC = 100;
    HS_TIM0 -> CR2 |= 0x0080;
    HS_TIM0 -> CCMR1 |= 0x0101;
    HS_TIM0 -> CCMR2 |= 0x0001;
    HS_TIM0 -> SMCR |=0x0046;
    HS_TIM0 -> ARR |= 0xffff;

    while(!(HS_TIM1 -> SR & 1));
    return HS_TIM0 -> CNT != 0;
}

void test_tim0_dead_pwm()
{
    HS_TIM0 -> PSC = 0;
    HS_TIM0 -> ARR = 999;
    HS_TIM0 -> CCR[0] = 500;
    HS_TIM0 -> CCR[1] = 500;
    HS_TIM0 -> CCR[2] = 500;
    HS_TIM0 -> CCR[3] = 500;
    HS_TIM0 -> CCMR1 |= 0x6060;
    HS_TIM0 -> CCMR2 |= 0x6060;
    HS_TIM0 -> CCER |= 0x5555;
    HS_TIM0 -> BDTR |= 0x8080;
    HS_TIM0 -> CR1 = 1;
}
int test_tim0_clear_ocref()
{
    HS_TIM0 -> PSC = 0;
    HS_TIM0 -> ARR = 5000;
    HS_TIM0 -> CCR[0] = 2500;
    HS_TIM0 -> CCR[1] = 2500;
    HS_TIM0 -> CCR[2] = 2500;
    HS_TIM0 -> CCR[3] = 2500;
    HS_TIM0 -> CCMR1 |= 0xe0e0;
    HS_TIM0 -> CCMR2 |= 0xe0e0;
    HS_TIM0 -> CCER |= 0x5555;
    HS_TIM0 -> BDTR |= 0x8000;
    HS_TIM0 -> CR1 |= 0x01;
    return 1;
}
int test_tim0_encoder_mode1()
{
    //tim1 and tim2  pwm
    test_tim1_pwm();
    test_tim0_one_pluse_delay(250);
    while(!(HS_TIM0 -> SR & 0x0001));
    tim0_remove();
    test_tim2_pwm();
    //tim0 encoder
    HS_TIM0 -> ARR = 65530;
    HS_TIM0 -> CCMR1 |= 0x0101;
    HS_TIM0 -> SMCR |= 0x0001;
    HS_TIM0 -> CR1 |= 0x00001;
    while(!(HS_TIM0 -> CNT > 0));
    return 1;
}
int test_tim0_padmux_pwm_and_capture()//_-_
{
    HS_TIM0 -> PSC = 1600;
    HS_TIM0 -> ARR = 50000;
    HS_TIM0 -> CCR[0] = 25000;
    HS_TIM0 -> CCR[1] = 25000;
    HS_TIM0 -> CCR[2] = 25000;
    HS_TIM0 -> CCMR1 |= 0x7070;
    HS_TIM0 -> CCMR2 |= 0x0170;
    HS_TIM0 -> CCER |= 0x5555;
    HS_TIM0 -> BDTR |= 0x8000;
    HS_TIM0 -> CR1 = 1;

    while(!(HS_TIM0 -> SR & 0x0010));
    return HS_TIM0 -> CCR[3] = 25000;
}

回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2015-1-28 22:39:33 | 显示全部楼层
楼主什么芯片啊?
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

5

主题

31

帖子

0

精华

初级会员

Rank: 2

积分
74
金钱
74
注册时间
2015-1-14
在线时间
1 小时
 楼主| 发表于 2015-1-29 10:15:52 | 显示全部楼层
现在还没有起名字  自己做的一款   这个是仿照STM32做的一个timer  做了一个测试  分享一下经验
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2015-1-30 00:13:33 | 显示全部楼层
回复【4楼】小萨:
---------------------------------
牛逼.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

5

主题

31

帖子

0

精华

初级会员

Rank: 2

积分
74
金钱
74
注册时间
2015-1-14
在线时间
1 小时
 楼主| 发表于 2015-1-30 12:19:48 | 显示全部楼层
回复【5楼】正点原子:
---------------------------------
就是想着分享一下  没有你说的那么厉害   也是互相学习
回复 支持 反对

使用道具 举报

5

主题

31

帖子

0

精华

初级会员

Rank: 2

积分
74
金钱
74
注册时间
2015-1-14
在线时间
1 小时
 楼主| 发表于 2015-1-30 12:29:36 | 显示全部楼层
回复【5楼】正点原子:
---------------------------------
原子哥对STM32熟悉,有什么不对的地方帮忙指正一下,谢谢。
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2015-1-30 23:03:31 | 显示全部楼层
回复【7楼】小萨:
---------------------------------
广而不精,不敢当啊.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

5

主题

31

帖子

0

精华

初级会员

Rank: 2

积分
74
金钱
74
注册时间
2015-1-14
在线时间
1 小时
 楼主| 发表于 2015-2-1 13:16:57 | 显示全部楼层
回复【8楼】正点原子:
---------------------------------
原子哥  你是西电么?
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2015-2-1 19:33:05 | 显示全部楼层
回复【9楼】小萨:
---------------------------------
不是
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

5

主题

31

帖子

0

精华

初级会员

Rank: 2

积分
74
金钱
74
注册时间
2015-1-14
在线时间
1 小时
 楼主| 发表于 2015-2-1 21:01:36 | 显示全部楼层
回复【10楼】正点原子:
---------------------------------
搞错了   刚才问了一下说的是圈圈  嘿嘿
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2015-2-1 23:36:44 | 显示全部楼层
回复【11楼】小萨:
---------------------------------
圈圈也是华工的,我师兄来的,呵呵.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

5

主题

31

帖子

0

精华

初级会员

Rank: 2

积分
74
金钱
74
注册时间
2015-1-14
在线时间
1 小时
 楼主| 发表于 2015-2-3 10:46:59 | 显示全部楼层
我知道  那个学校和成电还是有点渊源
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-26 04:13

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表