加急,函数嵌套后程序运行不正常

2019-10-16 02:50发布

在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); //保存电机位置                       
        }       
       
}

一周热门 更多>