打印
[STM8]

3相直流无刷电机控制波形不对 【此贴终结】

[复制链接]
3675|15
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
thor1991|  楼主 | 2015-6-26 11:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 thor1991 于 2015-6-26 15:59 编辑
/* MAIN.C file
摘要:
1.PA6延时反转,指示系统工作。
2.上电,按指定PWM输出延时换相,实现电机基本运转功能。
2013.5.8
*/
#include "stm8s.h"

#define STM8_FREQ_MHZ 16
#define PWM_FREQUENCY 16000

static const u16 hArrPwmVal = ((u16)((STM8_FREQ_MHZ * (u32)1000000)/PWM_FREQUENCY));
//PWM信号周期

#define PWMOUT 20
//按15%占空比输出

const unsigned char PWM_EN1_TAB[6]={0x00,0x00,0x01,0x01,0x10,0x10};
//六步法中,CH1\CH2通道极性及使能配置
const unsigned char PWM_EN2_TAB[6]={0x01,0x01,0x00,0x00,0x00,0x00};
//六步法中,CH3通道极性及使能配置

//上桥臂开关控制端口定义
#define MCO1_PORT GPIOC
#define MCO1_PIN        GPIO_PIN_1
#define MCO3_PORT GPIOC
#define MCO3_PIN        GPIO_PIN_2
#define MCO5_PORT GPIOC
#define MCO5_PIN        GPIO_PIN_3

//下桥臂开关控制端口定义
#define MCO0_PORT GPIOB
#define MCO0_PIN        GPIO_PIN_0
#define MCO2_PORT GPIOB
#define MCO2_PIN        GPIO_PIN_1
#define MCO4_PORT GPIOB
#define MCO4_PIN        GPIO_PIN_2
//下桥臂低电平开关管导通
#define PWM_A_OFF MCO0_PORT->ODR |= (u8)MCO0_PIN;
#define PWM_B_OFF MCO2_PORT->ODR |= (u8)MCO2_PIN;
#define PWM_C_OFF MCO4_PORT->ODR |= (u8)MCO4_PIN;

#define PWM_A_ON MCO0_PORT->ODR &= (u8)(~MCO0_PIN);
#define PWM_B_ON MCO2_PORT->ODR &= (u8)(~MCO2_PIN);
#define PWM_C_ON MCO4_PORT->ODR &= (u8)(~MCO4_PIN);

//换相子函数声明
void Commutation(unsigned char bHallStartStep,unsigned int OutPwmValue);

//初始化按键,指示灯端口
void GPIO_int(void)
{
         /* LEDs */
        GPIO_Init(GPIOA, GPIO_PIN_1, GPIO_MODE_OUT_PP_HIGH_FAST);
}

//系统时钟配置:内部16M
void Clock_init(void)
{
        /* Select fCPU = 16MHz */
  CLK_SYSCLKConfig(CLK_PRESCALER_HSIDIV1);
}

//换相电路开关管IO初始化
void PWM_IO_init(void)
{        
  //PB012 下桥臂0有效 ,配置为高电平
        GPIO_Init(MCO0_PORT, MCO0_PIN,GPIO_MODE_OUT_PP_HIGH_FAST);
        GPIO_Init(MCO2_PORT, MCO2_PIN,GPIO_MODE_OUT_PP_HIGH_FAST);
        GPIO_Init(MCO4_PORT, MCO4_PIN,GPIO_MODE_OUT_PP_HIGH_FAST);
        
        //PC123 上桥臂1有效,配置为低电平        
        GPIO_Init(MCO1_PORT, MCO1_PIN,GPIO_MODE_OUT_PP_LOW_FAST);
        GPIO_Init(MCO3_PORT, MCO3_PIN,GPIO_MODE_OUT_PP_LOW_FAST);
        GPIO_Init(MCO5_PORT, MCO5_PIN,GPIO_MODE_OUT_PP_LOW_FAST);               
}

//高级定时器初始化配置
void Tim1_init(void)
{
         /* TIM1 Peripheral Configuration */
  TIM1_DeInit();

  TIM1_TimeBaseInit(0, TIM1_COUNTERMODE_UP, hArrPwmVal, 0);

  TIM1_OC1Init(TIM1_OCMODE_PWM1, TIM1_OUTPUTSTATE_ENABLE, TIM1_OUTPUTNSTATE_DISABLE, hArrPwmVal*0, TIM1_OCPOLARITY_HIGH, TIM1_OCNPOLARITY_LOW, TIM1_OCIDLESTATE_RESET, TIM1_OCNIDLESTATE_SET);

  TIM1_OC2Init(TIM1_OCMODE_PWM1, TIM1_OUTPUTSTATE_ENABLE, TIM1_OUTPUTNSTATE_DISABLE, hArrPwmVal*0, TIM1_OCPOLARITY_HIGH, TIM1_OCNPOLARITY_LOW, TIM1_OCIDLESTATE_RESET, TIM1_OCNIDLESTATE_SET);

  TIM1_OC3Init(TIM1_OCMODE_PWM1, TIM1_OUTPUTSTATE_ENABLE, TIM1_OUTPUTNSTATE_DISABLE, hArrPwmVal*0, TIM1_OCPOLARITY_HIGH, TIM1_OCNPOLARITY_LOW, TIM1_OCIDLESTATE_RESET, TIM1_OCNIDLESTATE_SET);

  TIM1_CCPreloadControl(DISABLE);
        TIM1_Cmd(ENABLE);
}


main()
{
  unsigned int tem_c=0;
        unsigned char step=0;
        unsigned int outpwm=0;
        
        for(tem_c=0;tem_c<50000;tem_c++);//上电延时,等待系统稳定

        Clock_init();//指示灯端口初始化
        GPIO_int();//时钟配置
        
        PWM_IO_init();//开关管控制端口初始化
        Tim1_init();//高级定时器配置        
        outpwm=hArrPwmVal*PWMOUT/100;
        while (1)
        {
                for(tem_c=0;tem_c<7000;tem_c++);//延时时间
                GPIO_WriteReverse(GPIOA,GPIO_PIN_1);//PA6指示灯反转
                step++;
                if(step>=6)step=0;
                Commutation(step,outpwm);
        }
}

//换向输出PWM值,
//bHallStartStep:当前换相步序0-5,OutPwmValue 输出PWM值
void Commutation(unsigned char bHallStartStep,unsigned int OutPwmValue)
{        unsigned int tem_c=0;
   TIM1->BKR &= (uint8_t)(~TIM1_BKR_MOE);//禁止PWM输出
        if(bHallStartStep!=3&&bHallStartStep!=4)
        PWM_A_OFF;
        if(bHallStartStep!=0&&bHallStartStep!=5)
        PWM_B_OFF;
        if(bHallStartStep!=1&&bHallStartStep!=2)
        PWM_C_OFF;
         
        //根据换相步序,打开不同的开关管,并施加正确的PWM信号
        if(bHallStartStep==0)//AB
        {
                TIM1->CCR1H = (uint8_t)(OutPwmValue >> 8);
    TIM1->CCR1L = (uint8_t)(OutPwmValue);
                PWM_B_ON;
               
        }
        
        
  else if(bHallStartStep==1)        //AC
        {
                TIM1->CCR1H = (uint8_t)(OutPwmValue >> 8);
    TIM1->CCR1L = (uint8_t)(OutPwmValue);
          PWM_C_ON;
        }
        else if(bHallStartStep==2)        //BC
        {
                TIM1->CCR2H = (uint8_t)(OutPwmValue >> 8);
    TIM1->CCR2L = (uint8_t)(OutPwmValue);
          PWM_C_ON;
        }
        else if(bHallStartStep==3)        //BA
        {
                TIM1->CCR2H = (uint8_t)(OutPwmValue >> 8);
    TIM1->CCR2L = (uint8_t)(OutPwmValue);
          PWM_A_ON;
               
               
        }
        else if(bHallStartStep==4)//CA
        {
                TIM1->CCR3H = (uint8_t)(OutPwmValue >> 8);
    TIM1->CCR3L = (uint8_t)(OutPwmValue);
          PWM_A_ON;
               
        }
        else if(bHallStartStep==5)        //CB
        {
                TIM1->CCR3H = (uint8_t)(OutPwmValue >> 8);
    TIM1->CCR3L = (uint8_t)(OutPwmValue);
          PWM_B_ON;
        }
        
        TIM1->CCER1=PWM_EN1_TAB[bHallStartStep];
        TIM1->CCER2=PWM_EN2_TAB[bHallStartStep];               
        TIM1->BKR|=TIM1_BKR_MOE;//使能PWM输出
}

#ifdef USE_FULL_ASSERT

/**
  * [url=home.php?mod=space&uid=247401]@brief[/url]  Reports the name of the source file and the source line number
  *   where the assert_param error has occurred.
  * @param file: pointer to the source file name
  * @param line: assert_param error line source number
  * @retval : None
  */
void assert_failed(u8* file, u32 line)
{
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  /* Infinite loop */
  while (1)
  {
  }
}
#endif






通过TIM1的PWM输出控制上管,通过GPIO输出控制下管

根据换向步序,打开不同的开关管,并施加正确的PWM信号


但是同相的波形会有重合现象,怎么解决啊
沙发
fanxsd| | 2015-6-26 11:09 | 只看该作者
你都用 TIM1 定时器了,直接用 TIM1 定时器的 互补引脚做 多好啊,还有 死区时间。

使用特权

评论回复
板凳
thor1991|  楼主 | 2015-6-26 11:55 | 只看该作者
fanxsd 发表于 2015-6-26 11:09
你都用 TIM1 定时器了,直接用 TIM1 定时器的 互补引脚做 多好啊,还有 死区时间。 ...

可是不知道怎么写啊,求教

使用特权

评论回复
地板
qinweixing| | 2015-6-26 12:31 | 只看该作者
LZ基本思路就错了,TIM1上下管全搞定,不需要什么GPIO了

使用特权

评论回复
5
mmuuss586| | 2015-6-26 12:55 | 只看该作者
这样也可以的;

切换的时候,输出先全部关断;
再打开响应的PWM通道和GPIO;

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
thor1991 + 1 你说的对,最后我发现是相序不对.
6
gaoyang9992006| | 2015-6-26 13:27 | 只看该作者
不对就调整跟波形有关的代码啊。

使用特权

评论回复
7
fanxsd| | 2015-6-26 13:36 | 只看该作者
thor1991 发表于 2015-6-26 11:55
可是不知道怎么写啊,求教

你看 STM32参考手册 里边对高级定时器的 描述非常的详细的。

使用特权

评论回复
8
thor1991|  楼主 | 2015-6-26 13:56 | 只看该作者
mmuuss586 发表于 2015-6-26 12:55
这样也可以的;

切换的时候,输出先全部关断;

我是按照《无刷直流电机控制应用——基于stm8s系列单片机》7.7.1的例子来的,但是波形并不对啊,不知道如何下手

使用特权

评论回复
9
thor1991|  楼主 | 2015-6-26 13:58 | 只看该作者
qinweixing 发表于 2015-6-26 12:31
LZ基本思路就错了,TIM1上下管全搞定,不需要什么GPIO了

用这个也可以整吧

使用特权

评论回复
10
thor1991|  楼主 | 2015-6-26 13:58 | 只看该作者
gaoyang9992006 发表于 2015-6-26 13:27
不对就调整跟波形有关的代码啊。

正在调

使用特权

评论回复
11
thor1991|  楼主 | 2015-6-26 14:03 | 只看该作者
fanxsd 发表于 2015-6-26 13:36
你看 STM32参考手册 里边对高级定时器的 描述非常的详细的。

我用的STM8的单片机

使用特权

评论回复
12
fanxsd| | 2015-6-26 15:24 | 只看该作者
哦  那就不清楚了 STM8 研究的 比较少

使用特权

评论回复
13
fanxsd| | 2015-6-26 15:25 | 只看该作者
你也可以看看 参考手册,我估计高级定时器 都是有介绍的。

使用特权

评论回复
14
598330983| | 2015-6-26 20:27 | 只看该作者

你看 STM32参考手册 里边对高级定时器的 描述非常的详细的。??我是没看懂。

使用特权

评论回复
15
可可球| | 2015-6-30 21:19 | 只看该作者
先关断输出,再打开响应的PWM通道和GPIO;

使用特权

评论回复
16
冰河w| | 2015-6-30 22:14 | 只看该作者
你说的对,最后我发现是相序不对

什么相序不对,错在哪儿了

使用特权

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

本版积分规则

2

主题

14

帖子

0

粉丝