STM32驱动步进电机(附原工程)
2023-12-13 20:14:05
一、引言
本文旨在分享STM32对步进电机的驱动方法和代码工程(文末附工程连接)。初衷是我刚开始学者使用STM32驱动步进电机时,在CSDN上查阅了很多资料,好多都是只分享部分代码,有原工程的资源都需要付费!!!所以在我成功驱动步进电机后,我决定把驱动工程开源,以供和我一样的学者学习指导!
二、硬件准备?
1、单片机
这里我使用的是STM32F103C8T6,学者使用其他单片机也是可以的,关键看代码中的思路!
2、驱动模块
关于这个驱动模块的接线图,请看下图:
3、步进电机?
三、驱动的详细操作说明
这里我把搜集到的有关驱动如何使用的详细说明再列举一下,以方便大家加深理解,同时也是我对自己所学知识点的总结共享。
?四、关键代码
1、电机的初始化配置,相关引脚配置
#include "sm.h"
//num用于对引脚的索引,j用于计算步数,fx为电机旋转方向
unsigned short int num=0,j,fx;
void dj_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能PB端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz
GPIO_Init(GPIOB, &GPIO_InitStructure); //根据设定参数初始化GPIOB
GPIO_ResetBits(GPIOB,GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8); //PB.5/6/7/8 输出低电平
}
void TIM3_Int_Init(u16 arr,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能
TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 计数到5000为500ms
TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值 10Khz的计数频率
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
TIM_ITConfig( //使能或者失能指定的TIM中断
TIM3, //TIM
TIM_IT_Update ,
ENABLE //使能
);
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //TIM3中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //先占优先级0级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //从优先级3级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
TIM_Cmd(TIM3, ENABLE); //使能TIMx外设
}
static uint8_t GPIO_list[] = {0x01,0x02,0x04,0x08}; //对应驱动器4引脚,即电机4相
void TIM3_IRQHandler(void) //TIM3中断
{
if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源
{
TIM_ClearITPendingBit(TIM3, TIM_IT_Update); //清除TIMx的中断待处理位:TIM 中断源
if(judge == 0)
{
judge=0;
}
if(judge == 1)
{
if(fx == 0) //fx为电机旋转方向,fx=0时电机正转,fx=1时电机反转
{
dj_GPIO1 = ~(GPIO_list[num]&GPIO_list[0])>>0; //判断是否为引脚1,然后将其数值向右移动0位至第1位,得到unsigned int类型时的1或0
dj_GPIO2 = ~(GPIO_list[num]&GPIO_list[1])>>1; //判断是否为引脚2,然后将其数值向右移动1位至第1位,得到unsigned int类型时的1或0
dj_GPIO3 = ~(GPIO_list[num]&GPIO_list[2])>>2; //判断是否为引脚3,然后将其数值向右移动2位至第1位,得到unsigned int类型时的1或0
dj_GPIO4 = ~(GPIO_list[num]&GPIO_list[3])>>3; //判断是否为引脚4,然后将其数值向右移动3位至第1位,得到unsigned int类型时的1或0
}
if(fx == 1)
{
dj_GPIO4 = ~(GPIO_list[num]&GPIO_list[0])>>0; //上述的反转
dj_GPIO3 = ~(GPIO_list[num]&GPIO_list[1])>>1;
dj_GPIO2 = ~(GPIO_list[num]&GPIO_list[2])>>2;
dj_GPIO1 = ~(GPIO_list[num]&GPIO_list[3])>>3;
}
num += 1; //num用于对引脚的索引
j += 1; //j用于计算步数
if(num == 4) //到第4个GPIO后回到第1个GPIO
{
num = 0;
}
if(j == 2048&fx == 0) //走完一圈同时是正转结束,对参数进行修改
{
j = 0;
fx = 1;
num = 0;
}
if(j == 2048&fx == 1) //走完一圈同时是反转结束,对参数进行修改
{
j = 0;
fx = 0;
start = 0;
num = 0;
}
}
}
}
?2、主函数
/*
硬件连接方式如下:
驱动器ULN2003:IN1-->PB8
IN2-->PB7
IN3-->PB6
IN4-->PB5
+、-连接电源5-12v
连接电机
CH340:TXD-->PA10
RXD-->PA9
GND-->单片机GND
5V-->单片机5V
*/
#include "usart.h"
#include "delay.h"
#include "sm.h"
#include "Decode.h"
u8 judge = 0; //judge为1时电机开始旋转,为0时停止
u8 start = 0; //start为1时启动电机程序,为0时关闭
void run(void) //电机启动程序
{
if(start == 1) {judge = 1;}
else {judge = 0;}
}
int main(void)
{
delay_init(); // 延时函数初始化
dj_GPIO_Init(); // 电机初始化
uart_init(115200); //串口初始化
judge = 0; //电机停止运作
start = 0; //电机启动程序停止运作
TIM3_Int_Init(19,7199); //电机运行使用的定时器,72MHz,时间: 2ms = 20*7200/72000000s
while(1)
{
if(USART_RX_STA&0x8000) //USART_RX_STA标志最高位置1(接收完成了)
{
Code_Analysis((u8*)USART_RX_BUF); //判断接收数据是否正确
}
run(); //电机启动程序
}
}
?五、工程分享
链接:https://pan.baidu.com/s/1lUbV6sZAKrkNrclyVxGXlQ?pwd=zxf1?
提取码:zxf1?
--来自百度网盘超级会员V3的分享
链接:https://pan.baidu.com/s/1_aJUMeylCoUgCcGTQBda7A?pwd=zxf1?
提取码:zxf1?
--来自百度网盘超级会员V3的分享
文章来源:https://blog.csdn.net/m0_73931287/article/details/134976923
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!