#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "usart.h"
#include "timer.h"
#define MasterFrequency 0x100000//最高频率限制100K
long Current; //当前位置脉冲数
long Target; //目标位置脉冲数
long StartSave; //定位指令刚开始启动时的当前值
long DownStartSave; //开始进入减速时的当前值
/* TIME3——CH4 的通道 PB1 ,PB0 方向
**
** 先设置启动频率200HZ 然后对所需频率 进行分级 比如 2k 分10级 则 (2k-2000)/10 计算出每次所加频率
**程序先72M/(ARR+1)=6M psc=6M/(加速等级频率)-1 计算出所需的PSC值, 每次进中断改变PSC的值
**
**
**
**
**
**
*/
typedef enum
{
OFF = 0,
ON = 1,
}STATUS_Type;
typedef enum
{
us=1,
ms=1000,
sce=1000000,
}DELAY_Type;
STATUS_Type RunFlag; //定位指令脉冲输出执行标志
STATUS_Type StopCommand;//定位指令脉冲输出停止命令标志
STATUS_Type PlusMinus; //正负方向标志
u32 StartFreq; //启动频率
u32 TargetFreq; //目标频率
u32 UDTimer=1000; //加减速时间
u32 LadderFreq[102];
u16 LadderPSC[202]; //加减速0至9级速度/频率预分频值
u16 LadderNum; //加减速速度级数
u16 LadderOrderNum; //加减速速度编号
long LadderTarget[202]; //各速度等级目标值
void TIM3_IRQHandler() //定时器3全局中断函数
{
long temp;
if(TIM3->SR&0x0001)
{
if(PlusMinus==ON) //方向
{
temp=Current;
//如果方向为正,当前值加一
temp++;
Current=temp;
}
else
{
temp=Current;
temp--; //否则方向为负,当前值减一 倒着走
Current=temp;
}
if(Current==LadderTarget[LadderOrderNum])
{
if(LadderOrderNum< (LadderNum<<1))//加减速在这儿实现 。等级标号<2倍等级
{
LadderOrderNum++; //等级标号++;
TIM3->PSC=LadderPSC[LadderOrderNum];//改变你PSC的值
}
else //关闭步进电机
{
TIM3->CR1&=~(1<<0);
TIM3->CNT=0x0000;
RunFlag=OFF;
}
}
TIM3->SR=0x0000;
}
}
void Pluse_start()
{
RunFlag=ON; //脉冲输出定位指令执行标志置ON
StartSave=Current;
LadderOrderNum=0;//加减速级数序号为0
TIM3->PSC=LadderPSC[0];
delay_ms(2); //脉冲信号比方向信号滞后,以提高可靠性
TIM3->CR1|=1<<0; //启动定时器TIMER2计数
}
/*********************************************************************************
函数名称:DRVI
函数功能:相对定位
入口参数:long offset相对偏移脉冲,u32 frequency最高频率
返回值:无
*********************************************************************************/
void DRVI(long offset,u32 frequency)
{
u16 h;
u16 i;
u32 j;
if((offset!=0)&&(RunFlag==OFF)&&((GPIOC->IDR&0x01)==0))//相对偏移值为0则不接受命令,脉冲输出已执行,不接受命令
{
Target=Current+offset; //目标值等于当前值加上相对偏移值
if(frequency<StartFreq) //如果设定目标频率小于启动频率
{
frequency=StartFreq;
}
else if(frequency>MasterFrequency)//否则如果设定目标频率高于最高限制频率
{
frequency=MasterFrequency;
}
LadderNum=UDTimer/10;//加减速级数
j=(frequency-StartFreq)/LadderNum;//等差
for(i=0;i<LadderNum;i++)
{
LadderFreq[i]=i*j+StartFreq;//加减速各阶梯频率
LadderPSC[i]=(6000000/LadderFreq[i])-1;//加减速各阶梯频率对应定时器预分频值
}
LadderFreq[LadderNum]=frequency;//目标频率,最高频率
LadderPSC[LadderNum]=6000000/frequency-1;//目标频率(最高频率)对应定时器预分频值
if(offset>0)//相对偏移值为正数
{
GPIOB->BSRR=1<<0;//相对偏移值为正数,方向为正,方向信号高电平
PlusMinus=ON;//正负方向标志置ON
LadderTarget[0]=Current+StartFreq/100;//加速第一段目标脉冲值
for(i=1;i<LadderNum;i++)
{
LadderTarget[i]=LadderTarget[i-1]+LadderFreq[i]/100;//加速各段目标脉冲值
}
while(offset<=((LadderTarget[LadderNum-1]-Current)<<1))//如果偏移量小于二倍加速增量
{
LadderNum--;//加速等级数减一 频率设定过高、实际输出脉冲数过少的情况下不必加速至设定频率,避免过冲
}
for(i=0,h=LadderNum<<1; i<LadderNum; i++,h--)
{
LadderPSC[h]=LadderPSC[i];//减速各段定时器重装值
}
LadderTarget[LadderNum<<1]=Target;//减速最后一段目标脉冲值
for(i=(LadderNum<<1)-1,h=0;i>LadderNum;i--,h++)
{
LadderTarget[i]=LadderTarget[i+1]-LadderFreq[h]/100;//减速各段目标脉冲值
}
}
else//否则相对偏移值为负数
{
GPIOB->BRR=1<<0;//相对偏移值为负数,方向为负,方向信号低电平
PlusMinus=OFF;//正负方向标志OFF
LadderTarget[0]=Current-StartFreq/100;//加速第一段目标脉冲值
for(i=1;i<LadderNum;i++)
{
LadderTarget[i]=LadderTarget[i-1]-LadderFreq[i]/100;//加速各段目标脉冲值
}
while(offset>=((LadderTarget[LadderNum-1]-Current)<<1))//如果偏移量小于二倍加速增量
{
LadderNum--;//加速等级数减一 频率设定过高、实际输出脉冲数过少的情况下不必加速至设定频率,避免过冲
}
for(i=0,h=LadderNum<<1; i<LadderNum; i++,h--)
{
LadderPSC[h]=LadderPSC[i];
}
LadderTarget[LadderNum<<1]=Target;//减速最后一段目标脉冲值
for(i=(LadderNum<<1)-1,h=0;i>LadderNum;i--,h++)
{
LadderTarget[i]=LadderTarget[i+1]+LadderFreq[h]/100;//减速各段目标脉冲值
}
}
LadderTarget[LadderNum]=Target + Current - LadderTarget[LadderNum-1];
Pluse_start();//脉冲输出正式启动
}
}
/*********************************************************************************
函数名称:DRVA
函数功能:绝对定位
入口参数:long target目标位置脉冲,u32 frequency最高频率
返回值:无
*********************************************************************************/
void DRVA(long target,u32 frequency)//3200 2khz
{
u16 h;
u16 i;
u32 j;
long offset=target-Current;// 目标脉冲-当前脉冲
if((offset!=0)&&(RunFlag==OFF)&&((GPIOC->IDR&0x01)==0)) //目标位置等于当前位置,则不接受命令
{
///////////////////////////////////////////////////////////////////////////////////////////////////////
Target=target; //目标位置设定(等于参数)
if(frequency<StartFreq) //如果设定目标频率小于启动频率
{
frequency=StartFreq;
}
else if(frequency>MasterFrequency)//否则如果设定目标频率高于最高限制频率
{
frequency=MasterFrequency;
}
LadderNum=UDTimer/10;//加减速级数 分成100级
j=(frequency-StartFreq)/LadderNum;//等差 每个阶段所加的频率数
for(i=0;i<LadderNum;i++) //获取每个阶段的速度值
{
LadderFreq[i]=i*j+StartFreq;//加减速各阶梯频率 每个阶段的速度 等级到J
LadderPSC[i]=(6000000/LadderFreq[i])-1;//加减速各阶梯频率对应定时器初值
}
LadderFreq[LadderNum]=frequency;
LadderPSC[LadderNum]=6000000/frequency-1;//
///////////////////////////////////////////////////////////////////////////////////////////////////
if(offset>0)//目标位置值大于当前位置值
{
GPIOB->BSRR=1<<0;//则方向为正,方向信号高电平
PlusMinus=ON;//正负方向标志置ON
LadderTarget[0]=Current+StartFreq/100;
for(i=1;i<LadderNum;i++)
{
LadderTarget[i]=LadderTarget[i-1]+LadderFreq[i]/100;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
while(offset<=((LadderTarget[LadderNum-1]-Current)<<1))//如果偏移量小于二倍加速增量
{
LadderNum--;//加速等级数减一 频率设定过高、实际输出脉冲数过少的情况下不必加速至设定频率,避免过冲
}
for(i=0,h=LadderNum<<1; i<LadderNum; i++,h--)
{
LadderPSC[h]=LadderPSC[i]; //把频率倒着走
}
LadderTarget[LadderNum<<1]=Target;//减速最后一段目标脉冲值
for(i=(LadderNum<<1)-1,h=0;i>LadderNum;i--,h++)
{
LadderTarget[i]=LadderTarget[i+1]-LadderFreq[h]/100;//减速各段目标脉冲值
}
}
else//否则目标位置值小于当前位置值,
{
GPIOB->BRR=1<<0;//则方向为负,方向信号低电平
PlusMinus=OFF;//正负方向标志OFF
LadderTarget[0]=Current-StartFreq/100;
for(i=1;i<LadderNum;i++)
{
LadderTarget[i]=LadderTarget[i-1]-LadderFreq[i]/100;
}
while(offset>=((LadderTarget[LadderNum-1]-Current)<