实验内容:上电后,按下启动按键,步进电机开始运转
实验目的:掌握简单的步进电机的控制,熟悉其工作原理
不足之处:电机步进无法调速
下一步优化:使用PWM对电机进行控制
#include "Type.h"
#include "inc\hw_ints.h"
#include "inc\hw_memmap.h"
#include "inc\hw_types.h"
#include "driverlib\sysctl.h"
#include "driverlib\gpio.h"
#define KEY GPIO_PIN_4
#define PHRA1 GPIO_PIN_0
#define PHRA2 GPIO_PIN_1
#define PHRB1 GPIO_PIN_2
#define PHRB2 GPIO_PIN_3
#define PHLA1 GPIO_PIN_4
#define PHLA2 GPIO_PIN_5
#define PHLB1 GPIO_PIN_6
#define PHLB2 GPIO_PIN_7
/* jtag protect key */
#define PROTECT_KEY_PERIPH SYSCTL_PERIPH_GPIOC
#define PROTECT_KEY_PORT GPIO_PORTC_BASE
#define PROTECT_KEY_PIN GPIO_PIN_4
struct motor //电机的状态和方向
{
int8 cState;
int8 cDir;
typedef struct motor MOTOR;
static int8 cStep=0;
void delay (uint32 uiD) //延时函数
{
for (; uiD; uiD--);
}
void rightMotor(void) //右电机时序
{
switch (cStep) {
case 0: /* A2B2 */
GPIOPinWrite(GPIO_PORTD_BASE,
PHRA1 | PHRA2 | PHRB1 | PHRB2,
PHRA1 | PHRA2 | PHRB1 | PHRB2);
break;
case 1: /* A2 */
GPIOPinWrite(GPIO_PORTD_BASE,
PHRA1 | PHRA2 | PHRB1 | PHRB2,
PHRA1 | PHRA2);
break;
case 2: /* A2B1 */
GPIOPinWrite(GPIO_PORTD_BASE,
PHRA1 | PHRA2 | PHRB1 | PHRB2,
PHRA1 | PHRA2 | PHRB2);
break;
case 3: /* B1 */
GPIOPinWrite(GPIO_PORTD_BASE,
PHRA1 | PHRA2 | PHRB1 | PHRB2,
PHRB2);
break;
case 4: /* A1B1 */
GPIOPinWrite(GPIO_PORTD_BASE,
PHRA1 | PHRA2 | PHRB1 | PHRB2,
PHRA2 | PHRB2);
break;
case 5: /* A1 */
GPIOPinWrite(GPIO_PORTD_BASE,
PHRA1 | PHRA2 | PHRB1 | PHRB2,
PHRA2);
break;
case 6: /* A1B2 */
GPIOPinWrite(GPIO_PORTD_BASE,
PHRA1 | PHRA2 | PHRB1 | PHRB2,
PHRA2 | PHRB1 | PHRB2);
break;
case 7: /* B2 */
GPIOPinWrite(GPIO_PORTD_BASE,
PHRA1 | PHRA2 | PHRB1 | PHRB2,
PHRB1 | PHRB2);
break;
default:
break;
}
}
void leftMotor(void) //左电机时序
{
switch (cStep) {
case 0: /* A2B2 */
GPIOPinWrite(GPIO_PORTD_BASE,
PHLA1 | PHLA2 | PHLB1 | PHLB2,
PHLA1 | PHLA2 | PHLB1 | PHLB2);
break;
case 1: /* B2 */
GPIOPinWrite(GPIO_PORTD_BASE,
PHLA1 | PHLA2 | PHLB1 | PHLB2,
PHLB1 | PHLB2);
break;
case 2: /* A1B2 */
GPIOPinWrite(GPIO_PORTD_BASE,
PHLA1 | PHLA2 | PHLB1 | PHLB2,
PHLA2 | PHLB1 | PHLB2);
break;
case 3: /* A1 */
GPIOPinWrite(GPIO_PORTD_BASE,
PHLA1 | PHLA2 | PHLB1 | PHLB2,
PHLA2);
break;
case 4: /* A1B1 */
GPIOPinWrite(GPIO_PORTD_BASE,
PHLA1 | PHLA2 | PHLB1 | PHLB2,
PHLA2 | PHLB2);
break;
case 5: /* B1 */
GPIOPinWrite(GPIO_PORTD_BASE,
PHLA1 | PHLA2 | PHLB1 | PHLB2,
PHLB2);
break;
case 6: /* A2B1 */
GPIOPinWrite(GPIO_PORTD_BASE,
PHLA1 | PHLA2 | PHLB1 | PHLB2,
PHLA1 | PHLA2 | PHLB2);
break;
case 7: /* A2 */
GPIOPinWrite(GPIO_PORTD_BASE,
PHLA1 | PHLA2 | PHLB1 | PHLB2,
PHLA1 | PHLA2);
break;
default:
break;
}
}
uint8 keyCheck (void) //检测按键
{
if (GPIOPinRead(GPIO_PORTC_BASE, KEY) == 0) {
delay(50);
while(GPIOPinRead(GPIO_PORTC_BASE, KEY) == 0);
return(true);
}else {
return(false);
}
}
void StepMotor_Iint (void) //步进电机初始化
{
GPIODirModeSet(GPIO_PORTD_BASE,
PHRA1 |
PHRA2 |
PHRB1 |
PHRB2 |
PHLA1 |
PHLA2 |
PHLB1 |
PHLB2,
GPIO_DIR_MODE_OUT);
}
void keyInit (void) //按键初始化
{
GPIODirModeSet(GPIO_PORTC_BASE, KEY, GPIO_DIR_MODE_IN);
}
void ProtectJtag(void) //JTAG保护函数
{
SysCtlPeripheralEnable(PROTECT_KEY_PERIPH);
GPIOPadConfigSet(PROTECT_KEY_PORT, PROTECT_KEY_PIN, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);
GPIODirModeSet(PROTECT_KEY_PORT, PROTECT_KEY_PIN, GPIO_DIR_MODE_IN);
while(GPIOPinRead(PROTECT_KEY_PORT, PROTECT_KEY_PIN) == 1)
{
;
}
}
//主函数 循环调用电机的驱动时序,使电机连续步进
main (void)
{
ProtectJtag();
SysCtlClockSet( SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |
SYSCTL_XTAL_6MHZ );
SysCtlPeripheralEnable( SYSCTL_PERIPH_GPIOC );
SysCtlPeripheralEnable( SYSCTL_PERIPH_GPIOD );
keyInit();
StepMotor_Iint();
while(!keyCheck ())
{
delay(5000);
}
cStep=0;
while(1)
{
rightMotor();
leftMotor();
// delay(1250000); //0.025s 50Hz
delay(1250000*1/32); //781.25us
cStep = (cStep + 1) % 8;
}
}
/*关于延时时间的计算经历了无数的试验,起初未加延时函数,
发现电机能够进行单步调试,
一旦连续运行则电机无反应,且迅速升温,
此时期驱动芯片温度亦立即飙升,
试想可能是其驱动时序变换太快,后随加上一秒钟的延时函数,
发现此时能正常运作,只是动作过于缓慢,
接下来就是调试延时函数的问题了,
几经试验终于找到满意的延时值*/