目录
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