打印
[STM32F1]

stm32控制直流无刷电机(带霍尔传感器)的程序,不能进入定时器1触发中断,求指教

[复制链接]
9396|26
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
st_zzy321|  楼主 | 2015-7-7 19:21 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
问下用stm32控制直流无刷电机的程序,这里用定时器2的3个通道捕获霍尔传感器的信号,用定时器1发生6路PWM,然后让定时器2触发定时器1,定时器2为主模式,定时器1为从模式,在定时器1触发中断里发生换相,但是在板子上电机从来没有转过,下面是配置,希望各位高手指点
void BLDC_GPIOConfig(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
         
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10;  //TIM1输出
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;                                                  
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
                         
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;//TIM1输出
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;                                                  
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

       

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2;              //TIM3的霍尔输入
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
}
void BLDC_TIM1Config(void)
{
   
   TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;                           //基本结构体变量定义
   TIM_OCInitTypeDef  TIM_OCInitStructure;                     //输出结构体变量定义
   TIM_BDTRInitTypeDef  TIM_BDTRInitStructure;                                   //死区刹车结构体变量定义

   TIM_DeInit(TIM1);

   TIM_TimeBaseStructure.TIM_Prescaler = 2;                                           //TIM基本初始化
   TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_CenterAligned2;//中央对齐计数模式
   TIM_TimeBaseStructure.TIM_Period = 1499;                                           //PWM 16K
   TIM_TimeBaseStructure.TIM_ClockDivision = 0;
   TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;

   TIM_TimeBaseInit(TIM1,&TIM_TimeBaseStructure);

   TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;                    //TIM输出通道初始化
   TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable;
   TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;                  
   TIM_OCInitStructure.TIM_Pulse =1200;
   TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
   TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;         
   TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
   TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;         
  
   TIM_OC1Init(TIM1,&TIM_OCInitStructure);

   TIM_OCInitStructure.TIM_Pulse =1200;
   TIM_OC2Init(TIM1,&TIM_OCInitStructure);

   TIM_OCInitStructure.TIM_Pulse =1200;
   TIM_OC3Init(TIM1,&TIM_OCInitStructure);

   TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;                    //TIM输出通道4初始化,用来触发AD注入采样
   TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable;                  
   TIM_OCInitStructure.TIM_Pulse =1495;
   TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;           
  
   TIM_OC4Init(TIM1,&TIM_OCInitStructure);

   TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;        //死区刹车初始化
   TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;
   TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_OFF;
   TIM_BDTRInitStructure.TIM_DeadTime = 100;
   TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable;         //如打开,开机无输出且状态紊乱????
   TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_Low;
   TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Disable;

   TIM_BDTRConfig(TIM1,&TIM_BDTRInitStructure);

   TIM_OC1PreloadConfig(TIM1,TIM_OCPreload_Enable);  //使能捕获比较寄存器预装载(通道1)

   TIM_OC2PreloadConfig(TIM1,TIM_OCPreload_Enable);         //使能捕获比较寄存器预装载(通道2)

   TIM_OC3PreloadConfig(TIM1,TIM_OCPreload_Enable);         //使能捕获比较寄存器预装载(通道3)
   
   TIM_SelectInputTrigger(TIM1, TIM_TS_ITR1);        //输入触发源选择TIM3   
  
   TIM_CtrlPWMOutputs(TIM1,ENABLE);

   TIM_Cmd(TIM1,ENABLE);
}
void BLDC_TIM2Config(void)
{
   TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;                           //基本结构体变量定义
   TIM_ICInitTypeDef TIM_ICInitStructure;                      //定义结构体变量
   TIM_OCInitTypeDef  TIM_OCInitStructure;                     //输出结构体变量定义
      
   TIM_DeInit(TIM2);

   TIM_TimeBaseStructure.TIM_Prescaler = 71;                                   //TIM基本初始化
   TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
   TIM_TimeBaseStructure.TIM_Period =65535;
   TIM_TimeBaseStructure.TIM_ClockDivision = 0;
   TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;

   TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure);     
      
   TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;            //选择通道1
   TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //输入上升沿捕获  
   TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_TRC;  //配置通道为输入,并映射到哪里
   TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;       //输入捕获预分频值
   TIM_ICInitStructure.TIM_ICFilter = 10;                      //输入滤波器带宽设置

   TIM_ICInit(TIM2, &TIM_ICInitStructure);                     //输入通道配置

   TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;                     //TIM输出通道初始化
   TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;            
   TIM_OCInitStructure.TIM_Pulse =1023;
   TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;      
  
   TIM_OC2Init(TIM2,&TIM_OCInitStructure);

   TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing;                     //TIM输出通道初始化
   TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable;            
   TIM_OCInitStructure.TIM_Pulse =65535;
   TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;      
  
   TIM_OC4Init(TIM2,&TIM_OCInitStructure);

   TIM_SelectHallSensor(TIM2,ENABLE);                          //使能TIMx的霍尔传感器接口
   
   TIM_SelectInputTrigger(TIM2, TIM_TS_TI1F_ED);               //输入触发源选择   
  
   TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset);             //从模式选择

   TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable);//主从模式选择        
   
   TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_OC2Ref);      //选择输出触发模式(TRGO端)

   TIM_ITConfig(TIM2, TIM_IT_Trigger|TIM_IT_CC4, ENABLE);      //开定时器中断
   }
   
void BLDC_Start(void)
{
   TIM1->SMCR|=0x0006;        //开TIM1的输入触发       
   TIM1->DIER=0x0040;         //开TIM1的触发中断
   huanxiang();                              //调用换向函数,启动                                                                   
   TIM2->CR1|=0x0001;                  //开TIM2
   TIM2->DIER|=0x0050;                  //开TIM2中断  
}
void NVIC_Config(void)
{
           NVIC_InitTypeDef NVIC_InitStructure;                                          //复位NVIC寄存器为默认值       


         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);           //设置中断优先级组
          
       /*配置EXTI中断及处理优先级*/
       NVIC_InitStructure.NVIC_IRQChannel = TIM1_TRG_COM_IRQn;//开TIM1触发中断
       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
       NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
       NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
       NVIC_Init(&NVIC_InitStructure);

           NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;                //开TIM2中断
       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;   
       NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
       NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
       NVIC_Init(&NVIC_InitStructure);
}
                                    
                                                                            
评论
lzx199610 2020-8-20 17:27 回复TA
1284085222 
lzx199610 2020-8-20 17:26 回复TA
方便加一下我qq吗 ,我最近也在做这个,方便请教一下吗 
沙发
mmuuss586| | 2015-7-7 19:59 | 只看该作者
正常的是,在定时器2中断里,换向;

使用特权

评论回复
板凳
309030106| | 2015-7-7 21:19 | 只看该作者
是不是优先级的问题

使用特权

评论回复
地板
fanxsd| | 2015-7-7 21:23 | 只看该作者
本帖最后由 fanxsd 于 2015-7-7 21:30 编辑

你买的 泰克工控 的开发板吗?你看的这个程序就是那人写的。BUG一堆。自己完善了,就进一大步了。  TIM1 是输入触发式中断,由TIM2的 通道2 比较产生。

使用特权

评论回复
5
st_zzy321|  楼主 | 2015-7-8 09:24 | 只看该作者
fanxsd 发表于 2015-7-7 21:23
你买的 泰克工控 的开发板吗?你看的这个程序就是那人写的。BUG一堆。自己完善了,就进一大步了。  TIM1 是 ...

对的,就是泰科工控的开发板上的例程,原来例程还有问题啊,可是在开发板上确实可以跑起来,我自己的板子和开发板的区别是霍尔输入捕获用的是TIM2的ch1,ch2,ch3通道,他用的是TIM2的ch1,ch2,ch3通道,还有他用的是MOS管驱动,我用的是IPM模块,芯片都用的是C8T6

使用特权

评论回复
6
st_zzy321|  楼主 | 2015-7-8 11:49 | 只看该作者
fanxsd 发表于 2015-7-7 21:23
你买的 泰克工控 的开发板吗?你看的这个程序就是那人写的。BUG一堆。自己完善了,就进一大步了。  TIM1 是 ...

现在在战舰的开发板上,用普通的三路GPIO模拟霍尔信号,连到TIM2的ch1,c2,ch3,然后可以进入定时器1触发中断了,那是不是问题出现在硬件IPM模块上?

使用特权

评论回复
7
fanxsd| | 2015-7-8 13:35 | 只看该作者
你先看看 IPM 驱动引脚上 有PWM吗?

使用特权

评论回复
8
st_zzy321|  楼主 | 2015-7-8 14:02 | 只看该作者
fanxsd 发表于 2015-7-8 13:35
你先看看 IPM 驱动引脚上 有PWM吗?

在IPM6个驱动引脚上测过了,只有1路是高电平,其他5路都是低电平

使用特权

评论回复
9
xia_318| | 2015-7-8 14:27 | 只看该作者
我是初学者,帮不上;

使用特权

评论回复
10
fanxsd| | 2015-7-8 15:13 | 只看该作者
st_zzy321 发表于 2015-7-8 14:02
在IPM6个驱动引脚上测过了,只有1路是高电平,其他5路都是低电平

那不用说了  果断不转啊!

使用特权

评论回复
11
st_zzy321|  楼主 | 2015-7-8 15:51 | 只看该作者
fanxsd 发表于 2015-7-8 15:13
那不用说了  果断不转啊!

可是那个开发板的例程,好像就是每次换相时让一路导通,可是在开发板上能转起来

使用特权

评论回复
12
fanxsd| | 2015-7-8 16:40 | 只看该作者
st_zzy321 发表于 2015-7-8 15:51
可是那个开发板的例程,好像就是每次换相时让一路导通,可是在开发板上能转起来 ...

上三桥 下三桥,怎么能只让一桥导通。电流都没有回路。

使用特权

评论回复
13
可可球| | 2015-7-8 17:26 | 只看该作者
有PWM输出吗

使用特权

评论回复
14
米尔豪斯| | 2015-7-8 17:43 | 只看该作者
什么是上三桥 下三桥

使用特权

评论回复
15
董自祝| | 2015-7-8 17:49 | 只看该作者
表示你的太麻烦,不需要这样控制的;

使用特权

评论回复
16
lwsn| | 2015-7-8 19:37 | 只看该作者
只有1路是高电平,其他5路都是低电平,这怎么能行

使用特权

评论回复
17
st_zzy321|  楼主 | 2015-7-8 22:05 | 只看该作者
fanxsd 发表于 2015-7-8 16:40
上三桥 下三桥,怎么能只让一桥导通。电流都没有回路。

原来例程是
switch(irq_zhuanzi)                                 //根据转子位置,决定CCER输出相位和转子字偏移量
    {
    //*
           case 0x02:{                                                                               
                            TIM1->CCER=0x3810;//3,6        cb
                            };break;
          case 0x06:{
                                  TIM1->CCER=0x3018;//2,3                 ab                   
                    };break;                                                       
          case 0x04:{
                                  TIM1->CCER=0x3108;//2,5    ac
                            };break;
          case 0x05:{
                                  TIM1->CCER=0x3180;//4,5                  bc                       
                    };break;
          case 0x01:{
                                  TIM1->CCER=0x3081;//1,4                  ba                       
                    };break;
          case 0x03:{                                              
                                  TIM1->CCER=0x3801;//1,6                  ca                       
                    };break;
          default:break;
          //*/
                 
    }
现在我把它改成
switch(irq_zhuanzi)                                 //根据转子位置,决定CCER输出相位和转子字偏移量
    {
           case 0x02:{                                                                               
                                                                                                                     
                            TIM1->CCER=0x3401;//3,6        cb
                                };break;
          case 0x06:{
                                  TIM1->CCER=0x3410;//2,3                 ab                   
                    };break;                                                       
          case 0x04:{
                                  TIM1->CCER=0x3014;//2,5    ac
                            };break;
          case 0x05:{
                                  TIM1->CCER=0x3104;//4,5                  bc                       
                    };break;
          case 0x01:{
                                  TIM1->CCER=0x3140;//1,4                  ba                       
                    };break;
          case 0x03:{                                              
                                  TIM1->CCER=0x3041;//1,6                  ca                       
                    };break;
          default:break;
现在测IPM的驱动引脚,有2路有高电平了,不过都是2.3v,不是3.3v,而且电机还是没有转

使用特权

评论回复
18
fanxsd| | 2015-7-8 22:20 | 只看该作者
st_zzy321 发表于 2015-7-8 22:05
原来例程是
switch(irq_zhuanzi)                                 //根据转子位置,决定CCER输出相位和转子字偏移量
    {

推荐你看 STM32F10X 参考手册 高级定时器 那个 章节,讲解的非常的详细的。

使用特权

评论回复
19
st_zzy321|  楼主 | 2015-7-9 10:15 | 只看该作者
董自祝 发表于 2015-7-8 17:49
表示你的太麻烦,不需要这样控制的;

你有什么更好,更简单的方法吗

使用特权

评论回复
20
st_zzy321|  楼主 | 2015-7-9 11:42 | 只看该作者
fanxsd 发表于 2015-7-8 22:20
推荐你看 STM32F10X 参考手册 高级定时器 那个 章节,讲解的非常的详细的。

看过手册了,例程把寄存器TIM1->CCER配置成0x3108,除了把一路输出通道使能外,还把另外一路互补的通道设置它极性,可是他前面配置定时器1时已经设好互补通道的极性了,而我改的时候是每次把对应的一路通道和另外一路互补的通道使能,按照换相顺序来的,找不出问题在哪里,求指教

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

4

主题

22

帖子

0

粉丝