简介
单片机控制步进电机一般采用定时器比较中断的方式控制步进电机的速度,但是采用这种方法有一个缺点,电机的运行速度比较快的时候,单片机频繁进入中断。但是如果使用IO复用,定时器的比较翻转输出,用DMA把加速表的数据传输到捕获比较寄存器的方式控制电机,这样就可以大大减少中断的数量.
步进电机控制原理
给步进电机发一个脉冲(一个高电平,一个低电平),步进电机走一个步距角。步进电机的控制的基本需求:运行速度。运行速度取决于电机发脉冲的频率,这个频率与定时器有关。可以每隔一段时间,发生一个定时器中断,在定时器中断处理函数里面,翻转电机脉冲IO端口的高低电平,以及设置下一次定时的间隔。这个定时间隔用查表法从加速表数组中获取。对于stm32可以使用DMA的方式控制,定时间隔一到,DMA自动从加速表数组中获取定时间隔,然后自动把这个数值传输到定时器的比较寄存器。
DMA设置
电机控制DMA的主要功能是把加速表的数据传输到定时器的捕获比较器。初始化设置代码:
DMA_InitTypeDef DMA_Struct;
DMA_Struct.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //DMA传输完之后,内存地址不增加
DMA_Struct.DMA_MemoryInc = DMA_MemoryInc_Enable; //DMA传输完之后,内存地址增加
DMA_Struct.DMA_DIR = DMA_DIR_PeripheralDST; //DMA的传输方向为内存传数据到外设
DMA_Struct.DMA_BufferSize = nLen; //电机加速表长度
DMA_Struct.DMA_Mode = DMA_Mode_Circular; //循环传输
DMA_Struct.DMA_MemoryDataSize =DMA_MemoryDataSize_HalfWord; //内存一次DMA传输2字节
DMA_Struct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //外设一次DMA传输2字节
DMA_Struct.DMA_Priority = DMA_Priority_High;
DMA_Struct.DMA_M2M= DMA_M2M_Disable;
DMA_Cmd(DMA1_Channel1, DISABLE);
DMA_DeInit(DMA1_Channel1);
DMA_Struct.DMA_PeripheralBaseAddr = (u32)&TIM4->CCR1; //捕获寄存器外设地址
DMA_Struct.DMA_MemoryBaseAddr = (u32)&pDataBuffer; //加速表作为内存地址
DMA_Init(DMA1_Channel1,&DMA_Struct);
DMA_Cmd(DMA1_Channel1,ENABLE);
DMA_ITConfig(DMA1_Channel1, DMA_IT_TC,ENABLE); //开启传输完成中断
定时器设置
把定时器的工作模式设置为比较翻转输出,使能定时器DMA即可.
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle; //翻转输出
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 0;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
TIM_OC3Init(TIM3, &TIM_OCInitStructure);
TIM_OC3PreloadConfig(TIM3,TIM_OCPreload_Disable);
TIM_DMAConfig(TIM3,TIM_DMABase_CCR3,TIM_DMABurstLength_2Bytes);
TIM_DMACmd(TIM3,TIM_DMA_CC3,ENABLE);
结束
按照这个思路,可以达到DMA方式控制电机。当然还有其他一些其他的基础知识:IO复用,加减步数规划…