linux 定时器中断脉冲计数,怎样让定时器输出一定数量的脉冲

#ifndef _motor_h

#define _motor_h//两相四线步进电机

///

#include "stm32f10x.h"

#include "delay.h"

#include "sys.h"//io引用

//作者QQ750273008   祁成 2018.5.29

//电机类型:只能选一种

#define phase_two//两相四线步进电机

//                        #define phase_four//四相五线步进电机

//双拍

#define use_motor_4code  1 //0:8拍模式, 1:4拍模式

typedef struct

{

u8 num;                                          //电机轴的编号0~0xFF

const u8 *drive_code;          //步进电机节拍:停止+8种节拍

u8  rotate_val;        //电机旋转值

int add;                          //当前绝对位置

int go;                                  //预计移动

//加减速参数

u32 dead_us;    //最小死区时间(最快速度)//迷你滑台1ms

u32 delay_ms;                //电机转一拍停留时间(可以为0)

u16  VF;        //加减速曲线,(值越大,加减速越快)

}motors;

//电机默认参数表

extern motors zhou;

//当前可用轴

//extern motors zhou1;//x->dead_us =950 ;

//extern motors zhou2;//x->dead_us =950 ;

extern motors X;//x->dead_us =950 ;

extern motors Y;

extern motors Z;//电机Z轴

extern motors A;

extern motors B;

extern motors C;

extern motors D;

//

void motor_init(void);//轴初始化

u8 motorGoto(motors *x,int Goto);//轴定位

u8 motorGo(motors *x,long int go);//轴移动

void io_out(motors *x,u8 code);//输出驱动编码

void motor_cmd(motors *x,FunctionalState NewState);//电机失效(自由运动)

//

//

//io

//#define motor1_1   PAout(12)   //PB12 左轮 A相  IN1

//#define motor1_2   PAout(13)   //PB13 左轮 A'相 IN2

//#define motor1_3   PAout(14)   //PB14 左轮 B相  IN3

//#define motor1_4   PAout(15)   //PB15 左轮 B'相 IN4

//#define motor2_1   PBout(11)   //PB11 右轮 A相  IN1

//#define motor2_2   PBout(10)   //PB10 右轮 A'相 IN2

//#define motor2_3   PBout(1)    //PB1  右轮 B相  IN3

//#define motor2_4   PBout(0)    //PB0  右轮 B'相 IN4

#endif

// 下面是c文件

#include "stm32f10x.h"

#include "motor.h"//两相四线步进电机

#include "delay.h"//延时

//两相四线步进电机 56A9

#ifdef phase_two//两相四线步进电机(D0:A)  ,(D1:A非),   (D2:B),  (D3:B非)

//8拍                                        A    AB   B    A'B  A'   A'B' B'   AB'

static const u8 motor_code[9]={0X00,0x01,0x05,0X04,0X06,0X02,0X0A,0X08,0X09};//步进电机,停止+8种节拍

//        static const u8 motor_code[9]={0X00,0x08,0x0A,0X02,0X06,0X04,0X05,0X01,0X09};//步进电机,停止+8种节拍

#endif

//4拍                                   AB   A'B  A'B' AB'

//static const u8 motor_4code[9]={0X00,0x0A,0X06,0X05,0X09};//停止+4种节拍

//四相五线步进电机

#ifdef phase_four//四相五线步进电机

//8拍                                A    AB   B    BC   C    CD   D    DA

static const u8 motor_code[9]={0X00,0x01,0x03,0X02,0X06,0X04,0X0C,0X08,0X09};//步进电机,停止+8种节拍

#endif

//电机默认参数表

static motors zhou={

0,//电机轴的编号0~0xFF

motor_code, //步进电机节拍:停止+8种节拍

0,//电机当前节拍位置

0,//当前绝对位置

0,//预计移动

950,//最小死区时间(最快速度)//迷你滑台1000us

0,//电机转一拍停留时间(可以为0)

25//加减速曲线,(值越大,加减速变化越大)

};

//当前可用轴

motors X={0x01,motor_code,0,0,0,1000,0,50};//x->dead_us =950 ;

motors Y={0x02,motor_code,0,0,0,1000,0,50};//x->dead_us =950 ;

motors Z={0x03,motor_code,0,0,0,1000,0,50};//x->dead_us =950 ;

motors A={0x04,motor_code,0,0,0,1000,0,50};//x->dead_us =950 ;

motors B={0x05,motor_code,0,0,0,1000,0,50};//x->dead_us =950 ;

motors C={0x06,motor_code,0,0,0,1000,0,50};//x->dead_us =950 ;

//extern motors zhou1;//x->dead_us =950 ;

//extern motors zhou2;

///

///

/*初始化*/

void motor_init(void)//初始化

{

//添加并初始化需要用的轴

//X=zhou;

//        X.num=0x01;

//        Y.num =0x02;

//        Y.delay_ms=0;

motorGoto(&X,0);

motorGoto(&Y,0);

motorGoto(&Z,0);

delay_s(5);

motorGoto(&X,1);

motorGoto(&Y,1);

motorGoto(&Z,1);

}

/*轴定位*/

u8 motorGoto(motors *x,int Goto)//轴定位

{

int i;

i=Goto - x->add;//偏移量;

motorGo(x,i);//轴移动(定位值 减 当前位置)

return 0;

}

/*轴移动*/

u8 motorGo(motors *x,long int go)//轴移动

{

u8  rotate,drive_val;//节拍,线圈驱动值

long int        i;//脉冲数

if(go>0)//正转

{

x->go=go;//距离脉冲

for(i=0;i < x->go;i++)//正转循环

{

//得到下一个节拍,齿轮

rotate=(x->rotate_val + (1+use_motor_4code))%9;//当前节拍 + 偏移节拍

//一拍是否小于一拍

if(rotate < (1+use_motor_4code))//一节拍值

{

rotate = 1 + use_motor_4code;//绕过电机停止的编码值0x00,齿轮

}

drive_val=x->drive_code[rotate];//得到电机8拍驱动编码

//

//输出:

io_out(x,drive_val);//输出驱动编码

x->rotate_val=rotate;        //记录电机最后一次节拍编号

}

//记录当前地址

x->add += go;

return 0;

}

else//反转

{

x->go=go;//距离脉冲

for(i=0;i > x->go;i--)//负数

{

//补一圈回到原点,减1步节拍。

rotate = (x->rotate_val + 9-1-use_motor_4code)%9;

///

//旋转纠错

if(use_motor_4code) rotate += rotate%2 ;//回到双4拍的节拍上

if(rotate==0)

{

rotate=8;//绕过电机停止的编码值0x00

}

drive_val=x->drive_code[rotate];//得到电机8拍驱动编码

//

//输出:

io_out(x,drive_val);//输出驱动编码

x->rotate_val=rotate;        //记录电机最后一次节拍编号

}

//记录当前地址

x->add += go;

return 0;

}

}

void motor_cmd(motors *x,FunctionalState NewState)//电机失效(自由运动)

{

if(NewState==ENABLE)

{

io_out(x,0x08);//轴控制

}

else

{

io_out(x,0x00);//取消轴控制

}

//        io_out(&zhou2,0x00);//取消轴控制

/

//        u32 i,j,code=0x0f;

//        //

//                                //输出:

//                        GPIOB->ODR&=0XFFFF0FFF,//轴1

//                                                                GPIOB->BSRR = code<<12;

//

//                        GPIOB->ODR&=0XFFFFF3FC,//轴2

//                                                                i=code & 0x0C;//d3,d2

//                                                                i=i << 8;//d10

//                                                                j=code & 0x03;

//                                                                i |= j;

//                                                                GPIOB->BSRR = i;

}

void io_out(motors *x,u8 drive_code)//输出驱动编码

{

u32 i=0,j;

switch(x->num)

{

//

//输出:

case 0x01:GPIOB->ODR&=0XFFFF0FFF;          //轴1

GPIOB->BSRR = drive_code<<12;         //PB15,14,13,12

break;

case 0x02:GPIOB->ODR&=0XFFFFF3FC;          //轴2

i=drive_code & 0xC; //1100

i=i << 8;                   //PB11,PB10

j=drive_code & 0x3;

i |= j;                     //PB1,B0

GPIOB->BSRR = i;                      //PB11,10,1,0

break;

//                        case 0x03:GPIOB->ODR&=0XFFFF0FFF,

//                                                                GPIOB->BSRR |=code<<12;break;

}

//

//停留时间:

//电机转一拍停留时间

if(x->dead_us > 0)delay_us(x->dead_us);//最小死区时间(最快速度)

if(x->delay_ms > 0)delay_ms(x->delay_ms);

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: STM32主从定时器是一种嵌入式系统的定时器,可以用于生成固定脉冲数量输出。 主从定时器由一个主定时器和一个从定时器组成,主定时器负责计数,从定时器负责输出。工作原理是主定时器开始计数后,当计数值达到预设的固定脉冲数量时,从定时器触发输出脉冲。 首先,需要配置主定时器计数模式和计数器的加载值,以确定计数范围。例如,如果要生成100个脉冲,可以将计数器加载值设置为100-1,即99。 其次,需要配置从定时器的触发模式和输出模式。触发模式确定从定时器何时触发,可以选择主定时器计数值等于预设值时触发。输出模式确定输出脉冲的参数,如脉冲频率、占空比等。 最后,开启主定时器和从定时器,并等待主定时器计数值达到预设的固定脉冲数量。一旦达到,从定时器将触发输出脉冲,完成固定脉冲数量的生成。 需要注意的是,具体的配置和控制方式可能因不同的STM32型号而有所差异。因此,在使用STM32主从定时器生成固定脉冲数量之前,应该仔细阅读所使用的芯片的相关文档,并根据具体的需求进行配置和编程。 ### 回答2: STM32主从定时器可用于输出固定脉冲数量的功能。主从定时器在STM32微控制器中是指由一个主定时器和一个从定时器组成的定时器组。主从定时器之间通过一个信号线相连,主定时器控制从定时器的工作模式和计数脉冲。 首先,我们需要配置主定时器和从定时器的参数。通过设置主定时器计数方向和频率,以及从定时器计数方向和分频系数,我们可以实现不同频率和方向的计数。然后,我们需要设置主定时器计数周期,即所需输出脉冲数量。 接下来,我们设置主定时器的工作模式为触发模式,并选择一个触发源用于触发从定时器计数。当主定时器计数达到设定的周期后,触发源会触发从定时器开始计数。 在主从定时器开始工作后,从定时器会根据主定时器计数触发信号来进行计数,直至达到所设定的脉冲数量。一旦从定时器计数完成,我们可以设置一个中断标志位来表示脉冲数量已达到预期,并进行相应的处理。 总结起来,使用STM32主从定时器输出固定脉冲数量的功能,我们需要配置主定时器和从定时器的参数,并设置主定时器计数周期和触发源。通过触发源的触发信号,从定时器开始计数输出固定数量脉冲。 ### 回答3: STM32主从定时器可以通过编程实现输出固定脉冲数量。具体步骤如下: 1. 首先,选择一个主定时器和一个从定时器来实现功能。主定时器负责计数,从定时器负责输出脉冲信号。 2. 设置主定时器计数器模式为向上计数,并设置计数周期(脉冲数量)。 3. 配置主定时器的输入时钟源和预分频系数,使计数器按照指定的频率进行计数。 4. 配置从定时器输出模式为PWM输出。 5. 设置从定时器输出比较值,使脉冲的高电平和低电平持续时间达到期望的占空比。 6. 启动主定时器和从定时器计数。 7. 在主定时器中断服务函数中,检查计数值是否达到预设的脉冲数量。一旦达到,关闭主定时器和从定时器计数功能。 8. 关闭从定时器的PWM输出功能。 通过以上步骤,就可以实现输出固定脉冲数量的功能。需要注意的是,根据具体的需求,还可以对输出信号的占空比、频率等参数进行进一步调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值