步进电机(也称脉冲电机)(将电脉冲转换为相应的角位移或线位移的电磁机械装置,具有快速启动,停能力,在电机的负荷不超过它能提供的动态转矩时,可以通过输入脉冲来控制它在一瞬间的启动或者停止。在非超载的情况下,步距角和转速只和输入的脉冲频率有关,和环境温度,气压,振动无关,也不受电网电压的波动和负载变化的影响,因此,控制较为精准)即给电机一个脉冲信号,电机则转过一个步距角
步进电机是一种感应电机,它的工作原理:利用电子电路,将直流电变成分时供电的,多相时序控制电流,用这种电流为步进电机供电,步进电机才能正常工作,驱动器就是为步进电机分时供电的,多相时序控制器,就是说:必须用由双环形脉冲信号功率驱动电路等组成的控制系统方可使用。
步距角:控制系统每发一个步进脉冲信号,电机所转动的角度。电机出厂时给了一个步距角的值,如:86BYG250A型 电机的值为0.9、1.8(表示半步工作时为0.9,整步为1.8),被称之为“电机的固有步距角”,但是不一定是 电机实际工作时的真正步距角,真正的步距角和驱动器有关
相数:电机内部的线圈组数,目前常用的有二相,三相,四相,五相步进电机。电机相数不同,其步距角也就不同了, 一般二相电机的步距角为0.9/1,8,三相为0.36/0.72,五相为0.36/0.72。在没有细分驱动器的情况下,用户主要 靠选择不同相数的步进电机来满足自己步距角的要求。如果使用细分驱动器,那么相数好像也就没有了意义
拍数:完成一个磁场周期性变化所需脉冲数或导电状态,或指电机转过一个步距角所需脉冲数。以如下的四相电机为 例,有四相四拍运行方式,AB-BC-CD-DA-AB;四相八拍:A-AB-B-BC-C-CD-D-DA-A
失步:电机运转时运转的步数不等于理论上的步数,称之为失步
开环控制与闭环控制:(主要看系统中有没有反馈环节)(反馈指的是动作所引起的效果)
(反馈简单的理解就是:“你打了别人一巴掌,我们看到了它的脸是红的,嗯嗯,这就是眼睛所得到的反馈”)
闭环控制:存在反馈环节的控制,就是当前的系统能够实时的检测控制的输出结果,并将检测到的信息通过反馈环节反映到输入端,调整输入量,达到修正控制误差,提高控制精度的目的,(对外部扰动和系统参数变化不敏感)如:
(闭环)
全自动洗衣机,给洗衣机加水时,里边有一个红外传感器,扫描到水位高低,当水位合适时,洗衣机自动停止加水
家用空调根据传感器采集到当前的温度,然后比较设定温度,通过设定指令,控制室内外机的工作情况,改变频率,压缩机的转速等进行简单的调节,然后不断地进行控制
寻迹小车时,两边的红外传感器不断的检测黑线,将返回的结果输入到相应i/o口上,我们对这些i/o口进行中断检测就可以知道,当前时刻的位置,然后可以执行相应的操作(左转,右转);
调节平衡天平的时候,其中一种方法就是利用mpu6050获取当前所处位置的角度,调用PID算法,对当前的位置或者角度进行处理,然后对调整后的角度再次进行反馈处理
(家用空调调节温度)
家用空调调节指定的温度,靠的是电子传感器,(电子传感器就是一个热敏电阻,不同的温度会有不同的阻值),利用也可以理解为电子膨胀,不同的温度会有不同的阻值。利用对入风口的空气进行取样,把数据传输到控制板上,然后,在与设定的温度进行比较,产生一个指令来实现控制。(制冷的话,比较之后:输出室内风机和室外机的开机指令,内外机开始工作(室外机包括压缩机,室外风机,四通阀等部件),工作一定温度的话,室内温度将会:1,(定频空调)达到设定值,室外机停止工作,室内机保持工作,保证空气循环,当室内温度逐渐上升,大于设定值2-3度时,室外机重新启动制冷,室内温度将又开始下降,重复这个过程,室内温度就能保持在设定温度值上下1度左右范围内波动; 2,(变频空调)接近设定值,室外机的变频板输出的频率下降,压缩机转速下降,制冷量也相应降低,室内温度保持在与设定值相同的数值下。随着室内热源的变化,室内机温度传感器实时检测温度的变化,主控板输出的控制信号使变频器跟随变化调节压缩机工作频率,从而改变瞬时制冷量,确保室内温度稳定)
开环控制:不存在反馈环节的控制,也就是控制器与被控制对象间只有顺序作业而无反方向联系且控制单方向进行,
,无自动纠偏能力,不用取输出量变化信号控制输入量。
如:在开车的过程中,我们来控制方向盘
人工转换电扇的档位实现转速的控制,不用反馈回来实际的转速
给洗衣机加水时:我们通过来观察水位来确定什么时候关掉水龙头
(所以,简单的说:就是看有没有反馈:开环没有,闭环有,对于用到机器上来说,每一件事都是有反馈的,只是情况不同而已,当反馈是人自己来判断的话,那么这个系统就是开环的,如果反馈是机器自己来判断的话,那么这个系统就是闭环的)
从整体的角度来看:
主控程序+按键+步进电机
主控程序(test.c)
- #include "sys.h"
- #include "usart.h"
- #include "delay.h"
- #include "led.h"
- #include "key.h"
- #include "motor.h"
- int main(void)
- {
- u8 t;
- Stm32_Clock_Init(9); //系统时钟设置
- delay_init(72); //延时初始化
- LED_Init(); //初始化与LED连接的硬件接口
- KEY_Init(); //初始化与按键连接的硬件接口
- LED0=0; //点亮LED
- MOTOR_Init();
- while(1)
- {
- MOTOR();
- }
- }
整体截图:
然后接下来就是:led.c
- #include "sys.h"
- #include "led.h"
- //////////////////////////////////////////////////////////////////////////////////
- //LED IO初始化
- void LED_Init(void)
- {
- RCC->APB2ENR|=1<<2; //使能PORTA时钟
- RCC->APB2ENR|=1<<5; //使能PORTD时钟
- GPIOA->CRH&=0XFFFFFFF0;
- GPIOA->CRH|=0X00000003;//PA8 推挽输出
- GPIOA->ODR|=1<<8; //PA8 输出高
- GPIOD->CRL&=0XFFFFF0FF;
- GPIOD->CRL|=0X00000300;//PD.2推挽输出
- GPIOD->ODR|=1<<2; //PD.2输出高
- }
led.h- #ifndef __LED_H
- #define __LED_H
- #include "sys.h"
- //////////////////////////////////////////////////////////////////////////////////
- //LED端口定义
- #define LED0 PAout(8) // PA8
- #define LED1 PDout(2) // PD2
- void LED_Init(void); //初始化
- #endif
- #include "key.h"
- #include "delay.h"
- //////////////////////////////////////////////////////////////////////////////////
- //本程序只供学习使用,未经作者许可,不得用于其它任何用途
- //ALIENTEK Mini STM32开发板
- //按键输入 驱动代码
- //正点原子@ALIENTEK
- //技术论坛:www.openedv.com
- //修改日期:2014/3/06
- //版本:V1.0
- //版权所有,盗版必究。
- //Copyright(C) 广州市星翼电子科技有限公司 2009-2019
- //All rights reserved
- //////////////////////////////////////////////////////////////////////////////////
- //按键初始化函数
- //PA0.15和PC5 设置成输入
- void KEY_Init(void)
- {
- RCC->APB2ENR|=1<<2; //使能PORTA时钟
- RCC->APB2ENR|=1<<4; //使能PORTC时钟
- JTAG_Set(SWD_ENABLE); //关闭JTAG,开启SWD
- GPIOA->CRL&=0XFFFFFFF0; //PA0设置成输入
- GPIOA->CRL|=0X00000008;
- GPIOA->CRH&=0X0FFFFFFF; //PA15设置成输入
- GPIOA->CRH|=0X80000000;
- GPIOA->ODR|=1<<15; //PA15上拉,PA0默认下拉
- GPIOC->CRL&=0XFF0FFFFF; //PC5设置成输入
- GPIOC->CRL|=0X00800000;
- GPIOC->ODR|=1<<5; //PC5上拉
- }
- //按键处理函数
- //返回按键值
- //mode:0,不支持连续按;1,支持连续按;
- //返回值:
- //0,没有任何按键按下
- //KEY0_PRES,KEY0按下
- //KEY1_PRES,KEY1按下
- //WKUP_PRES,WK_UP按下
- //注意此函数有响应优先级,KEY0>KEY1>WK_UP!!
- u8 KEY_Scan(u8 mode)
- {
- static u8 key_up=1;//按键按松开标志
- if(mode)key_up=1; //支持连按
- if(key_up&&(KEY0==0||KEY1==0||WK_UP==1))
- {
- delay_ms(10);//去抖动
- key_up=0;
- if(KEY0==0)return KEY0_PRES;
- else if(KEY1==0)return KEY1_PRES;
- else if(WK_UP==1)return WKUP_PRES;
- }else if(KEY0==1&&KEY1==1&&WK_UP==0)key_up=1;
- return 0;// 无按键按下
- }
- #ifndef __KEY_H
- #define __KEY_H
- #include "sys.h"
- //////////////////////////////////////////////////////////////////////////////////
- //本程序只供学习使用,未经作者许可,不得用于其它任何用途
- //ALIENTEK Mini STM32开发板
- //按键输入 驱动代码
- //正点原子@ALIENTEK
- //技术论坛:www.openedv.com
- //修改日期:2014/3/06
- //版本:V1.0
- //版权所有,盗版必究。
- //Copyright(C) 广州市星翼电子科技有限公司 2009-2019
- //All rights reserved
- //////////////////////////////////////////////////////////////////////////////////
- #define KEY0_PRES 1 //KEY0按下
- #define KEY1_PRES 2 //KEY1按下
- #define WKUP_PRES 3 //WK_UP按下
- #define KEY0 PCin(5) //PC5
- #define KEY1 PAin(15) //PA15
- #define WK_UP PAin(0) //PA0 WK_UP
- void KEY_Init(void); //IO初始化
- u8 KEY_Scan(u8 mode); //按键扫描函数
- #endif
- #include "motor.h"
- #include "delay.h"
- //////////////////////////////////////////////////////////////////////////////////
- //电机初始化函数
- //PA0.15和PC5 设置成输入
- void MOTOR_Init(void)
- {
- RCC->APB2ENR|=1<<2; //使能PORTA时钟
- GPIOA->CRL&=0XFFFF0000; //PA0设置成输出
- GPIOA->CRL|=0X00003333;
- //小车左轮
- GPIOA->ODR|=0<<0; //PA0上拉
- GPIOA->ODR|=0<<1; //PA1上拉
- GPIOA->ODR|=0<<2; //PA2上拉
- GPIOA->ODR|=0<<3; //PA3上拉
- RCC->APB2ENR|=1<<4; //使能PORTC时钟
- //小车右轮
- GPIOC->CRL&=0X00FFFFFF; //PC6,7
- GPIOC->CRL|=0X33000000;
- GPIOC->CRH&=0XFFFFFF00; //PC8,9
- GPIOC->CRH|=0X00000033;
- GPIOC->ODR|=0<<6; //PC6上拉
- GPIOC->ODR|=0<<7; //PC7上拉
- GPIOC->ODR|=0<<8; //PC7上拉
- GPIOC->ODR|=0<<9; //PC5上拉
- }
- void MOTOR(void) //IO初始化
- {
- while(1)
- {
- // L_A1 = 1; L_A2 = 0; L_A3 = 0; L_A4 = 0;
- // delay_ms(10);
- // L_A1 = 1; L_A2 = 1; L_A3 = 0; L_A4 = 0;
- // delay_ms(10);
- // L_A1 = 0; L_A2 = 1; L_A3 = 0; L_A4 = 0;
- // delay_ms(10);
- // L_A1 = 0; L_A2 = 1; L_A3 = 1; L_A4 = 0;
- // delay_ms(10);
- //
- //
- // L_A1 = 0; L_A2 = 0; L_A3 = 1; L_A4 = 0;
- // delay_ms(10);
- // L_A1 = 0; L_A2 = 0; L_A3 = 1; L_A4 = 1;
- // delay_ms(10);
- // L_A1 = 0; L_A2 = 0; L_A3 = 0; L_A4 = 1;
- // delay_ms(10);
- // L_A1 = 1; L_A2 = 0; L_A3 = 0; L_A4 = 1;
- // delay_ms(10);
- L_A1 = 1; L_A3 = 0; L_A2 = 0; L_A4 = 0;
- delay_ms(10);
- L_A1 = 0; L_A3 = 1; L_A2 = 0; L_A4 = 0;
- delay_ms(10);
- L_A1 = 0; L_A3 = 0; L_A2 = 1; L_A4 = 0;
- delay_ms(10);
- L_A1 = 0; L_A3 = 0; L_A2 = 0; L_A4 = 1;
- delay_ms(10);
- }
- }
- #ifndef __MOTOR_H
- #define __MOTOR_H
- #include "sys.h"
- #include "delay.h"
- //////////////////////////////////////////////////////////////////////////////////
- //All rights reserved
- //////////////////////////////////////////////////////////////////////////////////
- #define L_A1 PAout(0) //PA0
- #define L_A2 PAout(1) //PA1
- #define L_A3 PAout(2) //PA2
- #define L_A4 PAout(3) //PA3
- #define R_A1 PCout(6) //PC6
- #define R_A2 PCout(7) //PC7
- #define R_A3 PCout(8) //PC8
- #define R_A4 PCout(9) //PC9
- void MOTOR_Init(void);
- void MOTOR(void);
- #endif
好了,以上就是我们的程序了,,,,,截图:
如上,是我们要加载的程序
本文大部分实例借鉴与:原子stm32
联系客服