本文主要粘贴些 使用STM32 控制AMIS-30542 来驱动2相步进电机 的关键程序段。。。
环境说明:
控制器:STM32F101R8T6 STM32固件库版本:V3.5 驱动芯片:AMIS-30542 步进电机:2相步进电机
原理图:
AMIS-30542寄存器地址宏定义:
#define MOTOR_WR 0x00
#define MOTOR_CR0 0x01
#define MOTOR_CR1 0x02
#define MOTOR_CR2 0x03
#define MOTOR_SR0 0x04
#define MOTOR_SR1 0x05
#define MOTOR_SR2 0x06
#define MOTOR_SR3 0x07
#define MOTOR_CR3 0x08
SPI接口及 DIR/STEP 初始:
/*********************************************************************************************************
** 函数名称: SPI_Init_Enable
** 功能描述: SPI1初始化
** 输 入: 无
** 输 出: 无
** 全局变量: 无
** 调用模块: SPI_InitStructure,GPIO_InitTypeDef,SPI_Cmd
**
**-------------------------------------------------------------------------------------------------------
** 修改人:
** 日 期:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void SPI1_Init(void)
{
SPI_InitTypeDef SPI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable SPI1 GPIO clocks */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1 | RCC_APB2Periph_AFIO |
RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC, ENABLE);
/* Configure SPI1 pins: NSS, SCK, MISO and MOSI */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7 ;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_SetBits(GPIOA,GPIO_Pin_0);
//DIR/Step 管脚
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3<span style="font-family: Arial, Helvetica, sans-serif;">;</span>
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_SetBits(GPIOA,GPIO_Pin_2);
//CLR 置低
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOC, &GPIO_InitStructure);
SPI_Cmd(SPI1, DISABLE);
/* Configure PB.02 as Output push-pull, used as Chip select */
/* SPI1 configuration */
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI1, &SPI_InitStructure);
// SPI_I2S_ITConfig(SPI1, SPI_I2S_IT_RXNE | SPI_I2S_IT_TXE, ENABLE);
SPI_Cmd(SPI1, ENABLE);
}
void Write_SPI_One_Byte(unsigned char addr,unsigned char data)
{
GPIO_ResetBits(GPIOA,GPIO_Pin_4);
//SPI_delay (500);
SPI_I2S_SendData(SPI1,0x80|addr);
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE)==RESET);
SPI_I2S_ReceiveData(SPI1);
SPI_I2S_SendData(SPI1,data);
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE)==RESET);
SPI_I2S_ReceiveData(SPI1);
GPIO_SetBits(GPIOA,GPIO_Pin_4);
//SPI_delay (500);
}
这里设置了细分刻度为1/8 ,则电机转动360度需要脉冲数:200 * 8 = 1600,其中200为步进电机的固定参数:整步运行一周需要200个脉冲..................
工作电流大小设置..........等等................
void MotordevInit(void)
{
//CLR 复位
GPIO_SetBits(GPIOC,GPIO_Pin_3);
SPI_delay(1000);
GPIO_ResetBits(GPIOC,GPIO_Pin_3);
Write_SPI_One_Byte(MOTOR_WR,0x00);//关闭看门狗
SPI_delay (1000);
Write_SPI_One_Byte(MOTOR_CR0,0x40);//1/8Micro-Step,Current = 1.39A
SPI_delay (1000);
Write_SPI_One_Byte(MOTOR_CR1,0x84);//DIRCTRL = 1,NXTP = 0,PWMF = 0,PWMJ = 1, EMC = VERY FAST
SPI_delay (1000);
Write_SPI_One_Byte(MOTOR_CR2,0xA0);//MOTEN = ENABLE MOTOR DRIVER,SLP = disable sleep mode,Gain = 0.25,SLA is transparent
SPI_delay (1000);
Write_SPI_One_Byte(MOTOR_CR3,0x84); //模式1’ 4 个PWM 周期 75%占空比 4 个PWM 周期
SPI_delay (1000);
}
TIMER1定时器初始化:中断模式,用于NXT引脚的脉冲输出
void TIM_Configuration1(void)//TIM初始化函数
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //TIM 基本事件结构体
TIM_OCInitTypeDef TIM_OCInitStructure; //TIM 输出控制结构体
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE); //使能TIM 时钟
TIM_DeInit(TIM1);
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
TIM_OCStructInit(&TIM_OCInitStructure);
TIM_TimeBaseStructure.TIM_Prescaler = 449; //TIM 预分频 160KHz
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM 计数模式
TIM_TimeBaseStructure.TIM_Period = 799; //TIM 计数周期
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //TIM 时钟分频
TIM_TimeBaseInit(TIM1,&TIM_TimeBaseStructure);
// TIM_SelectOnePulseMode(TIM1,TIM_OPMode_Repetitive); //连续输出
TIM_ARRPreloadConfig(TIM1, ENABLE); //PWM周期预加载
TIM_Cmd(TIM1,DISABLE); //使能TIM1
NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_IRQChannel; //更新事件
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; //抢占优先级0
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //响应优先级1
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //允许中断
NVIC_Init(&NVIC_InitStructure); //写入设置
TIM_ITConfig(TIM1,TIM_IT_Update,DISABLE);
}
其他I/O初始化配置,略过......
电机部分函数:
使能:
void EnableMotor(void)
{
//ResetEN;
Write_SPI_One_Byte(MOTOR_CR2,0xA0);
}
调速:
void MotorChangeFreq(float freq)
{
TIM1->ARR= 给个值....
}
运行:
void MotorRun(unsigned char Dir,u16 freq)
{
EnableMotor();
TIM_ITConfig(TIM1,TIM_IT_Update,ENABLE); //使能中断
TIM1->ARR = freq;
TIM_Cmd(TIM1,ENABLE);
......
......
}
停止:
将TIM中断禁止了就完了..............
................
中断函数:
/******************************************************************************/
/* STM32F10x Peripherals Interrupt Handlers */
/******************************************************************************/
/**
* @brief This function handles TIM1 global interrupt request.
* @param None
* @retval None
*/
void TIM1_UP_IRQHandler(void)
{
if(TIM_GetITStatus(TIM1,TIM_IT_Update)!= RESET)
{
if (GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_3)==0)
{
GPIO_SetBits(GPIOA,GPIO_Pin_3);
.......
......
}
else
{
GPIO_ResetBits(GPIOA,GPIO_Pin_3);
}
}
TIM_ClearFlag(TIM1,TIM_FLAG_Update);
TIM_ClearITPendingBit(TIM1,TIM_IT_Update);
}
测试函数:
略过............
~~~~~~~~~~~~~凌乱了··~~~~~~~~~~~~~~··