STM32/51单片机实训day7——电机驱动|ULN2003A步进电机|Proteus电路设计|旋转角度控制函数|驱动函数|Keil5程序设计

这篇博客介绍了如何使用STM32单片机通过ULN2003A驱动步进电机,实现步进电机旋转不同角度的控制。内容包括步进电机和ULN2003A的工作原理、步进电机的电路设计、编程实现旋转角度控制的函数以及Proteus仿真实验。通过GPIO配置、步进电机的八拍工作方式和特定的时序控制,实现了电机的正反转,并提供了程序代码示例。
摘要由CSDN通过智能技术生成

目录

目录

1  ULN2003A步进电机简介

2  步进电机电路设计

3 旋转角度控制函数

4 程序设计 

motor.c

motor.h

前期LCD参考文章:


内  容:编程实现控制步进电机旋转不同角度

学  时:3学时

知识点: GPIO配置、步进电机电路设计、编程实现旋转角度控制

重点: 步进电机电路设计、编程实现旋转角度控制

难点:编程实现旋转角度控制

时间:2022年12月27日9:00~11:50 

总结:

1 步进电机使用GPIOA进行输入输出,需要进行GPIO配置;

2 使用proteus设计步进电机电路;

3 编程实现步进电机旋转角度控制。

51单片机Proteus仿真+Keil工程-实验4-外部中断-步进电机驱动_轩笑鹄的博客-CSDN博客_51单片机外部中断实验

掌握外部中断的打开方式;掌握步进电机的基本控制。

步进电机控制系统+LCD状态显示+详细源码注释+proteus仿真(超详细)_HNU_刘yuan的博客-CSDN博客_步进电机驱动设计实现电机lcd按键加减速


1  ULN2003A步进电机简介

ULN2003A是一个七路反向器电路,即输入端高电平时ULN2003A输出端低电平,相反当输入端低电平的时ULN2003A输出端高电平

ULN2300A内部结构如下图所示,两个三极管串联,第一个管子的发射极接第2个管子的基极,所以整个电路的放大倍数是两个三极管放大倍数的乘积,具有很大的放大倍数。IN端接到单片机上,当IN端接入高电平时,两个三极管均导通,OUT端则能输出较大的电流

图1 ULA2300A内部结构

步进电机原理图如图2,电机共有六个引脚线,其中有两条线与供电电源相接,剩下四条线(A、B、C、D)用来控制电机的旋转。每个引脚线相当于有一个控制开关,通电后则可旋转一定的角度。

 图2 步进电机原理图

2  步进电机电路设计

步进电机电路设计如下图所示,其中步进电机的引脚通过网络与单片机引脚进行连接。

图2 步进电机电路

我的电路连接图如下: 

四相步进电机有单四拍(A-B-C-D)和双四拍(AB-BC-CD-DA)和八拍(A-AB-B-BC-C-CD-D-DA)这三种工作方式。

第一种工作方式扭矩小,功耗小,但震动大。

第二种工作方式扭矩较大,功耗也大,震动小。

第三种工作方式步距角小,输出更平滑,推荐采用这种方式。

只需要控制单片机的IO口使得ULN2003芯片按A-AB-B-BC-C-CD-D-DA的次序输出低电平(ULN2003A会使电平反向输出,因此STM32在输出高电平时,到达步进电机的电平才会为低电平)即可完成步进电机转动的一轮循环。如果要按相反方向转动,只要把上面A-AB-B-BC-C-CD-D-DA的次序反过来即可。

3 旋转角度控制函数

ULN2003A有四条线(A、B、C、D)用来控制电机的旋转,本实训使用八拍方式来驱动电机的旋转,每一拍旋转45°。经过proteus仿真试验发现,当节拍为A时,对应角度为-45°,当节拍为AB时,对应角度为0°,故为使电机顺时针旋转一周,我们采用如下节拍方式:B-BC-C-CD-D-DA-A-AB,八拍驱动方式逻辑时序如下表所示。

4 程序设计 

motor.c

#include "stm32f10x.h"

//PA2 PA3 PA4 PA5
/*void delay(void){
	uint32_t cnt = 0x20000;
	while(cnt--);}*/

void motor_init(void){
	//定义GPIO结构体
	GPIO_InitTypeDef GPIO_InitStruct;
	//打开时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	//PB引脚
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5;    // 初始化4个引脚
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; // ?????????????
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;// 输出速率为50MHz
	GPIO_Init(GPIOA, &GPIO_InitStruct);    // ???????
	GPIO_ResetBits(GPIOA, GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5); }
	
void motor_45(void){
	//B
	GPIO_SetBits(GPIOA, GPIO_Pin_3);  
	GPIO_ResetBits(GPIOA, GPIO_Pin_2 | GPIO_Pin_4 | GPIO_Pin_5);
	delay();}
	
void motor_180(void){
	//B
	GPIO_SetBits(GPIOA, GPIO_Pin_3);  // 45°
	GPIO_ResetBits(GPIOA, GPIO_Pin_2 | GPIO_Pin_4 | GPIO_Pin_5);
	delay();
	//BC
	GPIO_SetBits(GPIOA, GPIO_Pin_3 | GPIO_Pin_4 );  // LED ON
	GPIO_ResetBits(GPIOA, GPIO_Pin_2 | GPIO_Pin_5);
	delay();
	//C
	GPIO_SetBits(GPIOA, GPIO_Pin_4 );  // LED ON
	GPIO_ResetBits(GPIOA, GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_5);
	delay();
	//CD
	GPIO_SetBits(GPIOA, GPIO_Pin_4 | GPIO_Pin_5);  // LED ON
	GPIO_ResetBits(GPIOA, GPIO_Pin_2 | GPIO_Pin_3);
	delay();
}

药品信息管理系统 :

#include "motor.h"
#include "stm32f10x.h"
#include "delay.h"

void delay(void){
	uint32_t cnt=0x20000;
	while(cnt--);
	
}



void Motor_GPIOInit (void)
{
	GPIO_InitTypeDef GPIO_InitStructure;	
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);	
	
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5;	
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	//GPIO_Write(GPIOB,0x0000);			/?????
  GPIO_ResetBits(GPIOA,GPIO_Pin_2|GPIO_Pin_3|	GPIO_Pin_4|	GPIO_Pin_5);	

}

void Motor_CW(void)			
{
	//B
	GPIO_SetBits(GPIOA,GPIO_Pin_3);
	GPIO_ResetBits(GPIOA,GPIO_Pin_2|GPIO_Pin_4|GPIO_Pin_5);
	delay();
	
	//BC
	GPIO_SetBits(GPIOA,GPIO_Pin_3|GPIO_Pin_4);
	GPIO_ResetBits(GPIOA,GPIO_Pin_2|GPIO_Pin_5);
	delay();
	//GPIO_SetBits(GPIOA,GPIO_Pin_1);
	//SysTick_Delay_Ms(DELAY_TIME);
	//GPIO_ResetBits(GPIOA,GPIO_Pin_1);
	
	//GPIO_SetBits(GPIOA,GPIO_Pin_2);
	//SysTick_Delay_Ms(DELAY_TIME);
	//GPIO_ResetBits(GPIOA,GPIO_Pin_2);
	
	//GPIO_SetBits(GPIOA,GPIO_Pin_3);
	//SysTick_Delay_Ms(DELAY_TIME);
	//GPIO_ResetBits(GPIOA,GPIO_Pin_3);
}
void Motor_RW(void){			
  GPIO_SetBits(GPIOA,GPIO_Pin_2|GPIO_Pin_3);
	GPIO_ResetBits(GPIOA,GPIO_Pin_4|GPIO_Pin_5);
	delay();
	//B
	GPIO_SetBits(GPIOA,GPIO_Pin_4|GPIO_Pin_5);
	GPIO_ResetBits(GPIOA,GPIO_Pin_2|GPIO_Pin_3);
	delay();
	
	//BC
	
	//GPIO_SetBits(GPIOA,GPIO_Pin_1);
	//SysTick_Delay_Ms(DELAY_TIME);
	//GPIO_ResetBits(GPIOA,GPIO_Pin_1);
	
	//GPIO_SetBits(GPIOA,GPIO_Pin_2);
	//SysTick_Delay_Ms(DELAY_TIME);
	//GPIO_ResetBits(GPIOA,GPIO_Pin_2);
	
	//GPIO_SetBits(GPIOA,GPIO_Pin_3);
	//SysTick_Delay_Ms(DELAY_TIME);
	//GPIO_ResetBits(GPIOA,GPIO_Pin_3);
}
void Motor_SW(void)			
{
	GPIO_SetBits(GPIOA,GPIO_Pin_3);
	//SysTick_Delay_Ms(DELAY_TIME);
	GPIO_ResetBits(GPIOA,GPIO_Pin_3);
	
	GPIO_SetBits(GPIOA,GPIO_Pin_2);
	//SysTick_Delay_Ms(DELAY_TIME);
	GPIO_ResetBits(GPIOA,GPIO_Pin_2);
	
	GPIO_SetBits(GPIOA,GPIO_Pin_1);
	//SysTick_Delay_Ms(DELAY_TIME);
	GPIO_ResetBits(GPIOA,GPIO_Pin_1);
	
	GPIO_SetBits(GPIOA,GPIO_Pin_0);
	//SysTick_Delay_Ms(DELAY_TIME);
	GPIO_ResetBits(GPIOA,GPIO_Pin_0);
}

void Motor_ctrl_angle(int dire ,int angle)		//dire??????,angle??????
{
	int j=0;
	if(dire==0)		
	{				
		for(j=0;j<64*angle/45;j++)	
		{
			Motor_SW();
			
		}
		 MotorStop();
	}
	else			
	{		
		for(j=0;j<64*angle/45;j++)
	{
		Motor_CW();
	
	}	
		 MotorStop();

}
}
void Motor_ctrl_motor(int dire,float cycle)			//dire??????;cycle??????,?????
{
	int angle=cycle*360;
	Motor_ctrl_angle(dire , angle);

}
	
	
void MotorStop(void) 
{  
    GPIO_Write(GPIOB,0x0000);  
}

void SysTick_Delay_Ms(__IO uint32_t ms)
{
	uint32_t i;
	SysTick_Config(72000);
	
	for(i=0; i<ms ; i++)
	{
		while(!(SysTick->CTRL)&(1<<16))
			;
	}
	SysTick->CTRL &= SysTick_CTRL_ENABLE_Msk;
}

motor.h

#include "stm32f10x.h"

void motor_init(void);

void motor_45(void);
void motor_180(void);

药品信息管理系统 :

#ifndef __BSP_GPIO_H
#define __BSP_GPIO_H
#include "delay.h"




void Motor_GPIOInit (void);	
void Motor_CW(void);				
void SysTick_Delay_Ms(__IO uint32_t );
void Motor_SW(void);			
void Motor_ctrl_angle(int dire ,int angle);	
void Motor_ctrl_motor(int dire,float cycle);	
void MotorStop(void);	

void Motor_RW(void);


#endif

 2学分

了解RFID应用

了解RFID系统组成

完成完整的实训项目设计


前期LCD参考文章:

LCD12864液晶显示模块的使用与分析_楼上小白_1001号的博客-CSDN博客_lcd12864

STM32 LCD12864使用教程_是along不是alone的博客-CSDN博客_lcd12864复位

引脚介绍
1.一共有20个引脚,重要的只有那么几个;
3~VO就是调节对比度的,相当于调节每个点显示出来的深浅,虽然只有亮与不亮两种选择,但亮的模式下相当于可以调节每个点到底多亮;
4~RS,为1的时候表示发送的发送的数据,为0表示发送命令;
5~RW,就是控制我们是往LCD12864读数据(1)还是写数据(0),我们要控制LCD,当然是往里面写数据(0);
6~E,使能信号;
17~RST复位引脚;
接下来的DB0~DB7就是用来传输我们的数据,一个字节八个位刚好。

一、LCD12864(带字库的)使用教程:_布鲁格若门的博客-CSDN博客_lcd12864

51单片机——LCD12864_小白变形计的博客-CSDN博客_单片机lcd12864

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值