173 2438 5004
KEROS加密芯片——品牌直销 | 免费样品 | 技术支持
当前位置:网站首页 > 资讯中心 正文 资讯中心

stm32控制脉冲产生(stm32输出脉冲)

htxw 2022-12-05 资讯中心 14 ℃

stm32单片机产生100khz时钟脉冲思路

1,使用内部定时器产生。2,输出高电平,延时,再输出低电平,调节延时时间。

stm32如何输出数量可控的脉冲

单脉冲法,需要一个脉冲中断一次,中断次数多,影响效率

一个定时器输出PWM,另一定时器进行中断计数

用主从定时器门控方式

用一个定时器(从)作为另一个定时器(主)的外部时钟触发源

高级定时器T1、T8的重复计数方式,RCR计数中断,看手册好像这种方式最简单,能满足一部分人要求,缺点是寄存器只有8位,最多实现255个脉冲计数输出。

怎样使用STM32准确的产生任意个数的脉冲信号

使用定时器PWM输出模式即可。占空比和频率随意调节。相位差我想了一会也可以实现,你先启动一个定时器,然后一直检测计数器的计数,一旦达到某一个数值时再启动另外一个计数器,这样相位差就有了。但是因为函数执行本来就有一定时间,计算出来的数值应该并不是准确数,如果相位差要求不大这样就行,要求高的话在原本数值上加加减减总能达到。另外使用STM32产生信号简直就是大材小用,直接使用模电数电电路自震荡产生信号才是最廉价调节最便捷的方式,百度搜运放电路波形发生器即可,555定时器也可生成方波。这种方式调节相位幅值频率,乃至波形变换滤波什么的简直太简单。

STM32单片机怎么产生脉冲信号控制步进电动机?

STM32单片机怎么产生脉冲信号控制步进电动机:

#include "stepmotor.h"

#include

u32 PUL_CNT; // TIM3脉冲计数

vu32 step_done;

vu32 run_state;

#define run_state_stop 0

#define run_state_acc 1

#define run_state_run 2

#define run_state_dec 3

void STEPMOTOR_CTRL_INIT(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

NVIC_InitTypeDef NVIC_InitStructure;

TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

TIM_OCInitTypeDef TIM_OCInitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //GPIO时钟使能

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //定时器3时钟使能

//RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //定时器2时钟使能

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; //PA7为TIM3通道2

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推免输出

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //GPIO口响应速度

GPIO_Init(GPIOA, GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; //PA6为DIR控制输出

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推免输出

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //GPIO口响应速度

GPIO_Init(GPIOA, GPIO_InitStructure);

//TIM3_Configuration

TIM_TimeBaseStructure.TIM_Period = 23999; //自动重装载寄存器

TIM_TimeBaseStructure.TIM_Prescaler = 2; //预分频器,t=(23999+1)*(2+1)/72M

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //计数器向上计数模式

TIM_TimeBaseStructure.TIM_ClockDivision = 0x0; //时钟分频因子

TIM_TimeBaseStructure.TIM_RepetitionCounter = 0x0; //每次溢出都产生事件更新

TIM_TimeBaseInit(TIM3,TIM_TimeBaseStructure); //写TIM3各寄存器参数

TIM_ClearFlag(TIM3,TIM_FLAG_Update); //中断标志位清零

TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); //允许捕获/比较3中断

TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //PWM模式2 TIM3_CCMR1[14:12]=111 在向上计数时,一旦TIMx_CNT

TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //输入/捕获2输出允许

TIM_OCInitStructure.TIM_Pulse = 40; //确定占空比,这个值决定了有效电平的时间。

TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性,低电平有效

TIM_OC2Init(TIM3, TIM_OCInitStructure); //配置定时器输出模式,比较参数等

TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能TIM3在CCR2上的预装载寄存器

//TIM2_Configuration

TIM_DeInit(TIM2); //TIM2重新配置为缺省值,默认状态

TIM_TimeBaseStructure.TIM_Period = 359; //自动重装载寄存器

TIM_TimeBaseStructure.TIM_Prescaler = 199; //时钟预分频器

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //计数器向上计数模式

TIM_TimeBaseStructure.TIM_ClockDivision = 0x0; //时钟分频因子

TIM_TimeBaseInit(TIM2,TIM_TimeBaseStructure); //配置TIM2寄存器各参数

TIM_ClearFlag(TIM2,TIM_FLAG_Update); //中断标志位清零

TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE); //允许捕获/比较2中断

NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn ; //选择定时器TIM3

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //选择抢先式优先级(与中断嵌套级别有关)

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //选择子优先级(同抢先式优先级的响应顺序)

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //选择使能中断源

NVIC_Init(NVIC_InitStructure);

NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn ; //选择定时器TIM2

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //选择抢先式优先级(与中断嵌套级别有关)

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //选择子优先级(同抢先式优先级的响应顺序)

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //选择使能中断源

NVIC_Init(NVIC_InitStructure);

}

void TIM3_Configuration(u32 period)

{

TIM3-ARR = period-1;

TIM3-CCR2 = period 2;

//TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

//TIM_OCInitTypeDef TIM_OCInitStructure;

//TIM_TimeBaseStructure.TIM_Period = period-1; //自动重装载寄存器

//TIM_TimeBaseStructure.TIM_Prescaler = 29; //预分频器,f=72M/[(period+1)*(29+1)], ft = 2400000

//TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //计数器向上计数模式

//TIM_TimeBaseStructure.TIM_ClockDivision = 0x0; //时钟分频因子

//TIM_TimeBaseStructure.TIM_RepetitionCounter = 0x0; //每次溢出都产生事件更新

//TIM_TimeBaseInit(TIM3,TIM_TimeBaseStructure); //写TIM3各寄存器参数

//TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //PWM模式2 TIM3_CCMR1[14:12]=111 在向上计数时,一旦TIMx_CNT

//TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //输入/捕获2输出允许

//TIM_OCInitStructure.TIM_Pulse = period 2; //确定占空比,25%

//TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性,低电平有效

//TIM_OC2Init(TIM3, TIM_OCInitStructure); //配置定时器输出模式,比较参数等

}

//void MOTOR_RUN(u32 acc, u32 dec, u32 topspeed, u32 dis)

//步进电机运行参数

//acc -- 加速度,单位: round/min/s

//dec -- 减速度,单位: round/min/s

//topspeed -- 最高速度,单位: round/min

//dis -- 总角位移,单位: round/10000

void MOTOR_RUN(u32 acc, u32 dec, u32 topspeed, u32 dis)

{

u32 t_acc,t_dec,step_all,step_acc,step_dec,step_run;

u32 i,tim_cnt,tim_rest,tim_cnt_temp;

step_all = (float)dis * (N_MOTOR * 0.0001);

t_acc = topspeed * 1000 / acc; //unit: ms

t_dec = topspeed * 1000 / dec; //unit: ms

if(topspeed * (t_acc + t_dec) / 12 dis) //达不到最高速度 // topspeed/60/1000 * (t_acc + t_dec) / 2 dis / 10000

{

topspeed = sqrt(dis * acc * dec * 12 / (acc + dec) / 1000);

t_acc = topspeed * 1000 / acc; //unit: ms

t_dec = topspeed * 1000 / dec; //unit: ms

}

step_acc = N_MOTOR * ((float)topspeed*topspeed/(acc*120));

step_dec = N_MOTOR * ((float)topspeed*topspeed/(dec*120));

if(step_all step_acc + step_dec)

step_run = step_all - step_acc - step_dec;

else

step_run = 0;

//tim_cnt = 5.2363 * ft / (sqrt(acc*N_MOTOR/2)); //(ft * sqrt(60)*0.676) / sqrt(acc*N_MOTOR/2);

tim_cnt = 7.7460 * ft / (sqrt(acc*N_MOTOR/2));

tim_rest = 0;

i = 0;

TIM3_Configuration(tim_cnt);

run_state = run_state_acc;

TIM_Cmd(TIM3,ENABLE);

step_done = 0;

while(step_done==0);

while(i

{

i++;

//tim_cnt_temp = tim_cnt;

//tim_cnt = tim_cnt - (2*tim_cnt+tim_rest) / (4*i+1);

//tim_rest = (2*tim_cnt_temp+tim_rest) % (4*i+1);

tim_cnt_temp = tim_cnt / ( sqrt((float)(i+1)) + sqrt((float)(i)) );

TIM3_Configuration(tim_cnt_temp);

step_done = 0;

while(step_done==0);

}

if(step_run 0)

{

run_state = run_state_run;

tim_cnt = ft * 60 / (N_MOTOR*topspeed);

i = 0;

TIM3_Configuration(tim_cnt);

while(i

{

step_done = 0;

while(step_done==0);

i++;

}

}

run_state = run_state_dec;

tim_rest = 0;

i=0;

tim_cnt = tim_cnt + (2*tim_cnt+tim_rest) / (4*(step_dec-i)-1);

while(i

{

TIM3_Configuration(tim_cnt);

step_done = 0;

while(step_done==0);

i++;

tim_cnt_temp = tim_cnt;

tim_cnt = tim_cnt + (2*tim_cnt+tim_rest) / (4*(step_dec-i)-1);

tim_rest = (2*tim_cnt_temp+tim_rest) % (4*(step_dec-i)-1);

}

run_state = run_state_stop;

TIM_Cmd(TIM3,DISABLE);

}

void TIM2_IRQHandler(void)

{

}

void TIM3_IRQHandler(void)

{

TIM_ClearFlag(TIM3,TIM_FLAG_Update);

step_done = 1;

//PUL_CNT++;

}

文件:stepmotor.h 声明步进电机控制头文件

#define N_MOTOR 10000 //步进电机细分

#define ft 24000000

void STEPMOTOR_CTRL_INIT(void);

void MOTOR_RUN(u32 acc, u32 dec, u32 topspeed, u32 dis);

文件:main.c 主函数,设置加速度,减速度,最大速度和步数的参数值

#include "main.h"

#define LED_SET() GPIO_SetBits(GPIOB,GPIO_Pin_8)

#define LED_RST() GPIO_ResetBits(GPIOB,GPIO_Pin_8)

#define SET_DIR_CW() GPIO_SetBits(GPIOA,GPIO_Pin_6)

#define SET_DIR_CCW() GPIO_ResetBits(GPIOA,GPIO_Pin_6)

void NVIC_Configuration(void);

void LED_init(void);

void soft_delayms(u16 t);

int main(void)

{

SystemInit();

STEPMOTOR_CTRL_INIT();

soft_delayms(1000);

while(1)

{

SET_DIR_CW();

MOTOR_RUN(600,600,1000,500000);

soft_delayms(1000);

SET_DIR_CCW();

MOTOR_RUN(600,600,1000,500000);

soft_delayms(1000);

}

return 0;

}

void NVIC_Configuration(void)

{

NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0000); //将中断矢量放到Flash的0地址

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); //设置优先级配置的模式,详情请阅读原材料中的文章

}

void LED_init(void)

{

GPIO_InitTypeDef GPIO_InitStruct;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);

GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;

GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8;

GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;

GPIO_Init(GPIOB, GPIO_InitStruct);

}

void soft_delayms(u16 t)

{

u16 tt;

while(t--)

{

tt = 10000;

while(tt--);

}

}

#ifndef _MAIN_H

#define _MAIN_H

#include "stm32f10x.h"

#include "stepmotor.h"

#endif

stm32控制脉冲产生的介绍到此就结束了,感谢您耐心阅读,谢谢。

本文标签:stm32控制脉冲产生

<