专家
公告
财富商城
电子网
旗下网站
首页
问题库
专栏
标签库
话题
专家
NEW
门户
发布
提问题
发文章
STM32
加急,函数嵌套后程序运行不正常
2019-10-16 02:50
发布
×
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
站内问答
/
STM32/STM8
15412
13
1333
在main函数里直接调用函数comm2(),运行正常;在main函数里调用comm1(),在comm1()函数再调用comm2(),就运行不正常了,如果函数comm1()里代码很长也运行不正常,请问这是什么问题?好像是堆栈问题,但是堆栈已经设置很大了,堆栈设置:Stack_Size设置成0x0000A000,Heap_Size设置成0x00000500,还是运行不正常,求原子哥和大侠们指点!!
友情提示:
此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
13条回答
sqsnlg
2019-10-17 05:15
用定时器8的四个通道的PWM驱动四个步进电机,现在的问题是中断服务函数不是中断一次就进去一次,而是比定时时间延后很多才进去一次,我无法计算输出的脉冲个数,而且是有的时候是按设定时间进入中断服务函数的,有的时候是延时一倍时间后进入中断服务函数的,同样的程序,进入中断服务的时间不一样,有时感觉和外面其他函数的嵌套多少有关系,请各位大神帮忙啊
void MOTOR_TIM8_NVIC_CHX_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO, ENABLE); //使能GPIOC外设和AFIO复用功能模块时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8, ENABLE); //使能定时器8时钟
TIM_ITConfig(TIM8,TIM_IT_Update,ENABLE); //使能指定的TIM8中断,允许更新中断
NVIC_InitStructure.NVIC_IRQChannel = TIM8_UP_IRQn; //TIM8中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //先占优先级0级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //从优先级0级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
//设置该引脚为复用输出功能,输出TIM8 CH3的PWM脉冲波形 GPIOC.8
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure); //GPIOC.8=CLK1 水平电机PWM输出引脚初始化
//设置该引脚为复用输出功能,输出TIM8 CH4的PWM脉冲波形 GPIOC.9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure); //GPIOC.9=CLK2 点针电机PWM输出引脚初始化
//设置该引脚为复用输出功能,输出TIM8 CH2的PWM脉冲波形 GPIOC.7
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure); //GPIOC.7=CLK3 上升电机PWM输出引脚初始化
//设置该引脚为复用输出功能,输出TIM8 CH1的PWM脉冲波形 GPIOC.6
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure); //GPIOC.6=CLK4 下降电机PWM输出引脚初始化
}
//TIM3 PWM部分初始化
//PWM输出初始化
//arr:自动重装值
//psc:时钟预分频数
void MOTOR_TIM8_PwmInit(u16 arr,u16 psc,u16 PWM_Compare,MOTOR_TypeFlag MotorType)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
MOTOR_arr=arr;
//初始化TIM8
TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
//清空TIM8四个通道PWM设置
TIM_OCStructInit(&TIM_OCInitStructure);//结构体初始化
TIM_OC1Init(TIM8, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM8 OC1
TIM_OC2Init(TIM8, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM8 OC2
TIM_OC3Init(TIM8, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM8 OC3
TIM_OC4Init(TIM8, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM8 OC4
TIM_OC1PreloadConfig(TIM8, TIM_OCPreload_Disable); //不使能TIM8在CCR1上的预装载寄存器
TIM_OC2PreloadConfig(TIM8, TIM_OCPreload_Disable); //不使能TIM8在CCR2上的预装载寄存器
TIM_OC3PreloadConfig(TIM8, TIM_OCPreload_Disable); //不使能TIM8在CCR3上的预装载寄存器
TIM_OC4PreloadConfig(TIM8, TIM_OCPreload_Disable); //不使能TIM8在CCR4上的预装载寄存器
//配置TIM8通道参数
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
switch(MotorType)
{
case MOTOR_RISE:
TIM_OC2Init(TIM8, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM3 OC3
TIM_OC2PreloadConfig(TIM8, TIM_OCPreload_Enable); //使能TIM3在CCR3上的预装载寄存器
TIM_SetCompare2(TIM8,PWM_Compare); //设置比较值
break;
case MOTOR_LEVEL:
TIM_OC3Init(TIM8, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM3 OC3
TIM_OC3PreloadConfig(TIM8, TIM_OCPreload_Enable); //使能TIM3在CCR3上的预装载寄存器
TIM_SetCompare3(TIM8,PWM_Compare); //设置比较值
break;
case MOTOR_DROP:
TIM_OC4Init(TIM8, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM3 OC3
TIM_OC4PreloadConfig(TIM8, TIM_OCPreload_Enable); //使能TIM3在CCR3上的预装载寄存器
TIM_SetCompare4(TIM8,PWM_Compare); //设置比较值
break;
case MOTOR_FALL:
TIM_OC1Init(TIM8, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM3 OC3
TIM_OC1PreloadConfig(TIM8, TIM_OCPreload_Enable); //使能TIM3在CCR3上的预装载寄存器
TIM_SetCompare1(TIM8,PWM_Compare); //设置比较值
break;
}
TIM_CtrlPWMOutputs(TIM8,ENABLE); //MOE 主输出使能
TIM_ARRPreloadConfig(TIM8,ENABLE);//启动定时器前重装载周期值
//TIM_Cmd(TIM8,ENABLE); //启动定时器
}
void TIM8_UP_IRQHandler(void) //TIM8中断 电机PWM输出
{
TIM_ClearITPendingBit(TIM8, TIM_IT_Update); //清除TIMx的中断待处理位:TIM 中断源
MOTOR_PWM_Count++;
if(MOTOR_TYPE_CURRENT==MOTOR_RISE)
{
if(MOTOR_DIRECT_CURRENT==MOTOR_Forward)
MOTOR_ENCODE_Count=TIM5->CNT;
else
MOTOR_ENCODE_Count=64000-TIM5->CNT;
}
else if(MOTOR_TYPE_CURRENT==MOTOR_LEVEL)
{
if(MOTOR_DIRECT_CURRENT==MOTOR_Forward)
MOTOR_ENCODE_Count=TIM1->CNT;
else
MOTOR_ENCODE_Count=64000-TIM1->CNT;
}
else if(MOTOR_TYPE_CURRENT==MOTOR_DROP)
{
if(MOTOR_DIRECT_CURRENT==MOTOR_Forward)
MOTOR_ENCODE_Count=TIM4->CNT;
else
MOTOR_ENCODE_Count=64000-TIM4->CNT;
}
else if(MOTOR_TYPE_CURRENT==MOTOR_FALL)
{
if(MOTOR_DIRECT_CURRENT==MOTOR_Forward)
MOTOR_ENCODE_Count=TIM3->CNT;
else
MOTOR_ENCODE_Count=64000-TIM3->CNT;
}
if(MOTOR_TYPE_CURRENT==MOTOR_LEVEL)
{
MOTOR_ENCODE_Run=(float)MOTOR_ENCODE_Count*0.006; //一个编码器脉冲对应0.006mm = 12mm/2000(编码器一圈的脉冲) 导程=12mm
MOTOR_PWM_Run=(float)MOTOR_PWM_Count*0.00375; //一个PWM周期对应0.001875mm=12mm/6400(32分频一圈的脉冲) 导程=12mm
}
else
{
MOTOR_ENCODE_Run=(float)MOTOR_ENCODE_Count*0.001; //一个编码器脉冲对应0.001mm = 2mm/2000
MOTOR_PWM_Run=(float)MOTOR_PWM_Count*0.00125; //一个PWM周期对应0.00125mm=2mm/1600
}
if(MOTOR_PWM_Count>=MOTOR_PWM_Num) //脉冲数到了
{
TIM_Cmd(TIM8,DISABLE); //关闭PWM
MOTOR_ChipEnable(MOTOR_TYPE_CURRENT,DISABLE);//电机芯片不使能
if(MOTOR_ENCODE_Run<MOTOR_PWM_Run) //判断丢步 编码器的运行距离小于设置的距离
{
MOTOR_PWM_ENCODE_DIF=(MOTOR_PWM_Run-MOTOR_ENCODE_Run)*100; //差值放大100倍 精确到0.01mm
if(MOTOR_PWM_ENCODE_DIF>=1) //判断差值是否大于0.01mm
{
if(MOTOR_TYPE_CURRENT==MOTOR_LEVEL)
{
MOTOR_PWM_Count_Cnt=(float)((MOTOR_PWM_ENCODE_DIF/100)/0.00375);
MOTOR_PWM_ENCODE_DIF=MOTOR_PWM_Count_Cnt;
MOTOR_PWM_Count_Cnt-=MOTOR_PWM_ENCODE_DIF;
if(MOTOR_PWM_Count_Cnt>=0.5)
MOTOR_PWM_ENCODE_DIF++;
MOTOR_PWM_Count=MOTOR_PWM_Count-MOTOR_PWM_ENCODE_DIF;
}
else
MOTOR_PWM_Count=MOTOR_PWM_Count-MOTOR_PWM_ENCODE_DIF*8; //减去丢掉的脉冲个数,继续计数
MOTOR_ChipEnable(MOTOR_TYPE_CURRENT,ENABLE); //使能电机
TIM_Cmd(TIM8,ENABLE); //开启PWM
}
else
{
MOTOR_CurRun=MOTOR_ENCODE_Run*100; //放大100倍,精确到0.01mm
MOTOR_SaveMotorPlace(MOTOR_CurRun,MOTOR_TYPE_CURRENT,MOTOR_DIRECT_CURRENT); //保存电机位置
}
}
else //标志电机位置
{
MOTOR_CurRun=MOTOR_ENCODE_Run*100; //放大100倍,精确到0.01mm
MOTOR_SaveMotorPlace(MOTOR_CurRun,MOTOR_TYPE_CURRENT,MOTOR_DIRECT_CURRENT); //保存电机位置
}
}
else if((MOTOR_PWM_Run-MOTOR_ENCODE_Run)>=1) //PWM的距离-编码器的距离大于1MM,认为堵转
{
TIM_Cmd(TIM8,DISABLE); //关闭PWM
MOTOR_ChipEnable(MOTOR_TYPE_CURRENT,DISABLE); //不使能电机
MOTOR_CurRun=MOTOR_ENCODE_Run*100; //放大100倍,精确到0.01mm
MOTOR_SaveMotorPlace(MOTOR_CurRun,MOTOR_TYPE_CURRENT,MOTOR_DIRECT_CURRENT); //保存电机位置
}
}
加载中...
查看其它13个回答
一周热门
更多
>
相关问题
STM32F4上I2C(在PROTEUS中模拟)调试不通的问题
6 个回答
芯片供应紧张,准备换个MCU,MM32L系列替换STM32L系列的怎么样?
7 个回答
STM32同时使用两个串口进行数据收发时数据丢包的问题
5 个回答
STM32F103串口通信死机问题
4 个回答
STM32WLE5CC连接SX1268在LoRa模式下能与 SX1278互通吗?
2 个回答
相关文章
ST公司第一款无线低功耗单片机模块有效提高物联网设计生产效率
0个评论
如何实现对单片机寄存器的访问
0个评论
通过USB用STM32片内自带Bootloader下载程序及注意事项
0个评论
欲练此功必先自宫之STM32汇编启动,放慢是为了更好的前行
0个评论
×
关闭
采纳回答
向帮助了您的知道网友说句感谢的话吧!
非常感谢!
确 认
×
关闭
编辑标签
最多设置5个标签!
STM32
保存
关闭
×
关闭
举报内容
检举类型
检举内容
检举用户
检举原因
广告推广
恶意灌水
回答内容与提问无关
抄袭答案
其他
检举说明(必填)
提交
关闭
×
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
×
付费偷看金额在0.1-10元之间
确定
×
关闭
您已邀请
0
人回答
查看邀请
擅长该话题的人
回答过该话题的人
我关注的人
void MOTOR_TIM8_NVIC_CHX_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO, ENABLE); //使能GPIOC外设和AFIO复用功能模块时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8, ENABLE); //使能定时器8时钟
TIM_ITConfig(TIM8,TIM_IT_Update,ENABLE); //使能指定的TIM8中断,允许更新中断
NVIC_InitStructure.NVIC_IRQChannel = TIM8_UP_IRQn; //TIM8中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //先占优先级0级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //从优先级0级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
//设置该引脚为复用输出功能,输出TIM8 CH3的PWM脉冲波形 GPIOC.8
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure); //GPIOC.8=CLK1 水平电机PWM输出引脚初始化
//设置该引脚为复用输出功能,输出TIM8 CH4的PWM脉冲波形 GPIOC.9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure); //GPIOC.9=CLK2 点针电机PWM输出引脚初始化
//设置该引脚为复用输出功能,输出TIM8 CH2的PWM脉冲波形 GPIOC.7
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure); //GPIOC.7=CLK3 上升电机PWM输出引脚初始化
//设置该引脚为复用输出功能,输出TIM8 CH1的PWM脉冲波形 GPIOC.6
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure); //GPIOC.6=CLK4 下降电机PWM输出引脚初始化
}
//TIM3 PWM部分初始化
//PWM输出初始化
//arr:自动重装值
//psc:时钟预分频数
void MOTOR_TIM8_PwmInit(u16 arr,u16 psc,u16 PWM_Compare,MOTOR_TypeFlag MotorType)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
MOTOR_arr=arr;
//初始化TIM8
TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
//清空TIM8四个通道PWM设置
TIM_OCStructInit(&TIM_OCInitStructure);//结构体初始化
TIM_OC1Init(TIM8, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM8 OC1
TIM_OC2Init(TIM8, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM8 OC2
TIM_OC3Init(TIM8, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM8 OC3
TIM_OC4Init(TIM8, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM8 OC4
TIM_OC1PreloadConfig(TIM8, TIM_OCPreload_Disable); //不使能TIM8在CCR1上的预装载寄存器
TIM_OC2PreloadConfig(TIM8, TIM_OCPreload_Disable); //不使能TIM8在CCR2上的预装载寄存器
TIM_OC3PreloadConfig(TIM8, TIM_OCPreload_Disable); //不使能TIM8在CCR3上的预装载寄存器
TIM_OC4PreloadConfig(TIM8, TIM_OCPreload_Disable); //不使能TIM8在CCR4上的预装载寄存器
//配置TIM8通道参数
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
switch(MotorType)
{
case MOTOR_RISE:
TIM_OC2Init(TIM8, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM3 OC3
TIM_OC2PreloadConfig(TIM8, TIM_OCPreload_Enable); //使能TIM3在CCR3上的预装载寄存器
TIM_SetCompare2(TIM8,PWM_Compare); //设置比较值
break;
case MOTOR_LEVEL:
TIM_OC3Init(TIM8, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM3 OC3
TIM_OC3PreloadConfig(TIM8, TIM_OCPreload_Enable); //使能TIM3在CCR3上的预装载寄存器
TIM_SetCompare3(TIM8,PWM_Compare); //设置比较值
break;
case MOTOR_DROP:
TIM_OC4Init(TIM8, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM3 OC3
TIM_OC4PreloadConfig(TIM8, TIM_OCPreload_Enable); //使能TIM3在CCR3上的预装载寄存器
TIM_SetCompare4(TIM8,PWM_Compare); //设置比较值
break;
case MOTOR_FALL:
TIM_OC1Init(TIM8, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM3 OC3
TIM_OC1PreloadConfig(TIM8, TIM_OCPreload_Enable); //使能TIM3在CCR3上的预装载寄存器
TIM_SetCompare1(TIM8,PWM_Compare); //设置比较值
break;
}
TIM_CtrlPWMOutputs(TIM8,ENABLE); //MOE 主输出使能
TIM_ARRPreloadConfig(TIM8,ENABLE);//启动定时器前重装载周期值
//TIM_Cmd(TIM8,ENABLE); //启动定时器
}
void TIM8_UP_IRQHandler(void) //TIM8中断 电机PWM输出
{
TIM_ClearITPendingBit(TIM8, TIM_IT_Update); //清除TIMx的中断待处理位:TIM 中断源
MOTOR_PWM_Count++;
if(MOTOR_TYPE_CURRENT==MOTOR_RISE)
{
if(MOTOR_DIRECT_CURRENT==MOTOR_Forward)
MOTOR_ENCODE_Count=TIM5->CNT;
else
MOTOR_ENCODE_Count=64000-TIM5->CNT;
}
else if(MOTOR_TYPE_CURRENT==MOTOR_LEVEL)
{
if(MOTOR_DIRECT_CURRENT==MOTOR_Forward)
MOTOR_ENCODE_Count=TIM1->CNT;
else
MOTOR_ENCODE_Count=64000-TIM1->CNT;
}
else if(MOTOR_TYPE_CURRENT==MOTOR_DROP)
{
if(MOTOR_DIRECT_CURRENT==MOTOR_Forward)
MOTOR_ENCODE_Count=TIM4->CNT;
else
MOTOR_ENCODE_Count=64000-TIM4->CNT;
}
else if(MOTOR_TYPE_CURRENT==MOTOR_FALL)
{
if(MOTOR_DIRECT_CURRENT==MOTOR_Forward)
MOTOR_ENCODE_Count=TIM3->CNT;
else
MOTOR_ENCODE_Count=64000-TIM3->CNT;
}
if(MOTOR_TYPE_CURRENT==MOTOR_LEVEL)
{
MOTOR_ENCODE_Run=(float)MOTOR_ENCODE_Count*0.006; //一个编码器脉冲对应0.006mm = 12mm/2000(编码器一圈的脉冲) 导程=12mm
MOTOR_PWM_Run=(float)MOTOR_PWM_Count*0.00375; //一个PWM周期对应0.001875mm=12mm/6400(32分频一圈的脉冲) 导程=12mm
}
else
{
MOTOR_ENCODE_Run=(float)MOTOR_ENCODE_Count*0.001; //一个编码器脉冲对应0.001mm = 2mm/2000
MOTOR_PWM_Run=(float)MOTOR_PWM_Count*0.00125; //一个PWM周期对应0.00125mm=2mm/1600
}
if(MOTOR_PWM_Count>=MOTOR_PWM_Num) //脉冲数到了
{
TIM_Cmd(TIM8,DISABLE); //关闭PWM
MOTOR_ChipEnable(MOTOR_TYPE_CURRENT,DISABLE);//电机芯片不使能
if(MOTOR_ENCODE_Run<MOTOR_PWM_Run) //判断丢步 编码器的运行距离小于设置的距离
{
MOTOR_PWM_ENCODE_DIF=(MOTOR_PWM_Run-MOTOR_ENCODE_Run)*100; //差值放大100倍 精确到0.01mm
if(MOTOR_PWM_ENCODE_DIF>=1) //判断差值是否大于0.01mm
{
if(MOTOR_TYPE_CURRENT==MOTOR_LEVEL)
{
MOTOR_PWM_Count_Cnt=(float)((MOTOR_PWM_ENCODE_DIF/100)/0.00375);
MOTOR_PWM_ENCODE_DIF=MOTOR_PWM_Count_Cnt;
MOTOR_PWM_Count_Cnt-=MOTOR_PWM_ENCODE_DIF;
if(MOTOR_PWM_Count_Cnt>=0.5)
MOTOR_PWM_ENCODE_DIF++;
MOTOR_PWM_Count=MOTOR_PWM_Count-MOTOR_PWM_ENCODE_DIF;
}
else
MOTOR_PWM_Count=MOTOR_PWM_Count-MOTOR_PWM_ENCODE_DIF*8; //减去丢掉的脉冲个数,继续计数
MOTOR_ChipEnable(MOTOR_TYPE_CURRENT,ENABLE); //使能电机
TIM_Cmd(TIM8,ENABLE); //开启PWM
}
else
{
MOTOR_CurRun=MOTOR_ENCODE_Run*100; //放大100倍,精确到0.01mm
MOTOR_SaveMotorPlace(MOTOR_CurRun,MOTOR_TYPE_CURRENT,MOTOR_DIRECT_CURRENT); //保存电机位置
}
}
else //标志电机位置
{
MOTOR_CurRun=MOTOR_ENCODE_Run*100; //放大100倍,精确到0.01mm
MOTOR_SaveMotorPlace(MOTOR_CurRun,MOTOR_TYPE_CURRENT,MOTOR_DIRECT_CURRENT); //保存电机位置
}
}
else if((MOTOR_PWM_Run-MOTOR_ENCODE_Run)>=1) //PWM的距离-编码器的距离大于1MM,认为堵转
{
TIM_Cmd(TIM8,DISABLE); //关闭PWM
MOTOR_ChipEnable(MOTOR_TYPE_CURRENT,DISABLE); //不使能电机
MOTOR_CurRun=MOTOR_ENCODE_Run*100; //放大100倍,精确到0.01mm
MOTOR_SaveMotorPlace(MOTOR_CurRun,MOTOR_TYPE_CURRENT,MOTOR_DIRECT_CURRENT); //保存电机位置
}
}
一周热门 更多>