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

[复制链接]
4137|15
 楼主| thor1991 发表于 2015-6-26 11:03 | 显示全部楼层 |阅读模式
本帖最后由 thor1991 于 2015-6-26 15:59 编辑
  1. /* MAIN.C file
  2. 摘要:
  3. 1.PA6延时反转,指示系统工作。
  4. 2.上电,按指定PWM输出延时换相,实现电机基本运转功能。
  5. 2013.5.8
  6. */
  7. #include "stm8s.h"

  8. #define STM8_FREQ_MHZ 16
  9. #define PWM_FREQUENCY 16000

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

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

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

  18. //上桥臂开关控制端口定义
  19. #define MCO1_PORT GPIOC
  20. #define MCO1_PIN        GPIO_PIN_1
  21. #define MCO3_PORT GPIOC
  22. #define MCO3_PIN        GPIO_PIN_2
  23. #define MCO5_PORT GPIOC
  24. #define MCO5_PIN        GPIO_PIN_3

  25. //下桥臂开关控制端口定义
  26. #define MCO0_PORT GPIOB
  27. #define MCO0_PIN        GPIO_PIN_0
  28. #define MCO2_PORT GPIOB
  29. #define MCO2_PIN        GPIO_PIN_1
  30. #define MCO4_PORT GPIOB
  31. #define MCO4_PIN        GPIO_PIN_2
  32. //下桥臂低电平开关管导通
  33. #define PWM_A_OFF MCO0_PORT->ODR |= (u8)MCO0_PIN;
  34. #define PWM_B_OFF MCO2_PORT->ODR |= (u8)MCO2_PIN;
  35. #define PWM_C_OFF MCO4_PORT->ODR |= (u8)MCO4_PIN;

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

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

  41. //初始化按键,指示灯端口
  42. void GPIO_int(void)
  43. {
  44.          /* LEDs */
  45.         GPIO_Init(GPIOA, GPIO_PIN_1, GPIO_MODE_OUT_PP_HIGH_FAST);
  46. }

  47. //系统时钟配置:内部16M
  48. void Clock_init(void)
  49. {
  50.         /* Select fCPU = 16MHz */
  51.   CLK_SYSCLKConfig(CLK_PRESCALER_HSIDIV1);
  52. }

  53. //换相电路开关管IO初始化
  54. void PWM_IO_init(void)
  55. {        
  56.   //PB012 下桥臂0有效 ,配置为高电平
  57.         GPIO_Init(MCO0_PORT, MCO0_PIN,GPIO_MODE_OUT_PP_HIGH_FAST);
  58.         GPIO_Init(MCO2_PORT, MCO2_PIN,GPIO_MODE_OUT_PP_HIGH_FAST);
  59.         GPIO_Init(MCO4_PORT, MCO4_PIN,GPIO_MODE_OUT_PP_HIGH_FAST);
  60.         
  61.         //PC123 上桥臂1有效,配置为低电平        
  62.         GPIO_Init(MCO1_PORT, MCO1_PIN,GPIO_MODE_OUT_PP_LOW_FAST);
  63.         GPIO_Init(MCO3_PORT, MCO3_PIN,GPIO_MODE_OUT_PP_LOW_FAST);
  64.         GPIO_Init(MCO5_PORT, MCO5_PIN,GPIO_MODE_OUT_PP_LOW_FAST);               
  65. }

  66. //高级定时器初始化配置
  67. void Tim1_init(void)
  68. {
  69.          /* TIM1 Peripheral Configuration */
  70.   TIM1_DeInit();

  71.   TIM1_TimeBaseInit(0, TIM1_COUNTERMODE_UP, hArrPwmVal, 0);

  72.   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);

  73.   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);

  74.   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);

  75.   TIM1_CCPreloadControl(DISABLE);
  76.         TIM1_Cmd(ENABLE);
  77. }


  78. main()
  79. {
  80.   unsigned int tem_c=0;
  81.         unsigned char step=0;
  82.         unsigned int outpwm=0;
  83.         
  84.         for(tem_c=0;tem_c<50000;tem_c++);//上电延时,等待系统稳定

  85.         Clock_init();//指示灯端口初始化
  86.         GPIO_int();//时钟配置
  87.         
  88.         PWM_IO_init();//开关管控制端口初始化
  89.         Tim1_init();//高级定时器配置        
  90.         outpwm=hArrPwmVal*PWMOUT/100;
  91.         while (1)
  92.         {
  93.                 for(tem_c=0;tem_c<7000;tem_c++);//延时时间
  94.                 GPIO_WriteReverse(GPIOA,GPIO_PIN_1);//PA6指示灯反转
  95.                 step++;
  96.                 if(step>=6)step=0;
  97.                 Commutation(step,outpwm);
  98.         }
  99. }

  100. //换向输出PWM值,
  101. //bHallStartStep:当前换相步序0-5,OutPwmValue 输出PWM值
  102. void Commutation(unsigned char bHallStartStep,unsigned int OutPwmValue)
  103. {        unsigned int tem_c=0;
  104.    TIM1->BKR &= (uint8_t)(~TIM1_BKR_MOE);//禁止PWM输出
  105.         if(bHallStartStep!=3&&bHallStartStep!=4)
  106.         PWM_A_OFF;
  107.         if(bHallStartStep!=0&&bHallStartStep!=5)
  108.         PWM_B_OFF;
  109.         if(bHallStartStep!=1&&bHallStartStep!=2)
  110.         PWM_C_OFF;
  111.          
  112.         //根据换相步序,打开不同的开关管,并施加正确的PWM信号
  113.         if(bHallStartStep==0)//AB
  114.         {
  115.                 TIM1->CCR1H = (uint8_t)(OutPwmValue >> 8);
  116.     TIM1->CCR1L = (uint8_t)(OutPwmValue);
  117.                 PWM_B_ON;
  118.                
  119.         }
  120.         
  121.         
  122.   else if(bHallStartStep==1)        //AC
  123.         {
  124.                 TIM1->CCR1H = (uint8_t)(OutPwmValue >> 8);
  125.     TIM1->CCR1L = (uint8_t)(OutPwmValue);
  126.           PWM_C_ON;
  127.         }
  128.         else if(bHallStartStep==2)        //BC
  129.         {
  130.                 TIM1->CCR2H = (uint8_t)(OutPwmValue >> 8);
  131.     TIM1->CCR2L = (uint8_t)(OutPwmValue);
  132.           PWM_C_ON;
  133.         }
  134.         else if(bHallStartStep==3)        //BA
  135.         {
  136.                 TIM1->CCR2H = (uint8_t)(OutPwmValue >> 8);
  137.     TIM1->CCR2L = (uint8_t)(OutPwmValue);
  138.           PWM_A_ON;
  139.                
  140.                
  141.         }
  142.         else if(bHallStartStep==4)//CA
  143.         {
  144.                 TIM1->CCR3H = (uint8_t)(OutPwmValue >> 8);
  145.     TIM1->CCR3L = (uint8_t)(OutPwmValue);
  146.           PWM_A_ON;
  147.                
  148.         }
  149.         else if(bHallStartStep==5)        //CB
  150.         {
  151.                 TIM1->CCR3H = (uint8_t)(OutPwmValue >> 8);
  152.     TIM1->CCR3L = (uint8_t)(OutPwmValue);
  153.           PWM_B_ON;
  154.         }
  155.         
  156.         TIM1->CCER1=PWM_EN1_TAB[bHallStartStep];
  157.         TIM1->CCER2=PWM_EN2_TAB[bHallStartStep];               
  158.         TIM1->BKR|=TIM1_BKR_MOE;//使能PWM输出
  159. }

  160. #ifdef USE_FULL_ASSERT

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

  172.   /* Infinite loop */
  173.   while (1)
  174.   {
  175.   }
  176. }
  177. #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了
mmuuss586 发表于 2015-6-26 12:55 | 显示全部楼层
这样也可以的;

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

评分

参与人数 1威望 +1 收起 理由
thor1991 + 1 你说的对,最后我发现是相序不对.

查看全部评分

gaoyang9992006 发表于 2015-6-26 13:27 | 显示全部楼层
不对就调整跟波形有关的代码啊。
fanxsd 发表于 2015-6-26 13:36 | 显示全部楼层
thor1991 发表于 2015-6-26 11:55
可是不知道怎么写啊,求教

你看 STM32参考手册 里边对高级定时器的 描述非常的详细的。
 楼主| thor1991 发表于 2015-6-26 13:56 | 显示全部楼层
mmuuss586 发表于 2015-6-26 12:55
这样也可以的;

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

我是按照《无刷直流电机控制应用——基于stm8s系列单片机》7.7.1的例子来的,但是波形并不对啊,不知道如何下手
 楼主| thor1991 发表于 2015-6-26 13:58 | 显示全部楼层
qinweixing 发表于 2015-6-26 12:31
LZ基本思路就错了,TIM1上下管全搞定,不需要什么GPIO了

用这个也可以整吧
 楼主| thor1991 发表于 2015-6-26 13:58 | 显示全部楼层
gaoyang9992006 发表于 2015-6-26 13:27
不对就调整跟波形有关的代码啊。

正在调
 楼主| thor1991 发表于 2015-6-26 14:03 | 显示全部楼层
fanxsd 发表于 2015-6-26 13:36
你看 STM32参考手册 里边对高级定时器的 描述非常的详细的。

我用的STM8的单片机
fanxsd 发表于 2015-6-26 15:24 | 显示全部楼层
哦  那就不清楚了 STM8 研究的 比较少
fanxsd 发表于 2015-6-26 15:25 | 显示全部楼层
你也可以看看 参考手册,我估计高级定时器 都是有介绍的。
598330983 发表于 2015-6-26 20:27 | 显示全部楼层

你看 STM32参考手册 里边对高级定时器的 描述非常的详细的。??我是没看懂。
可可球 发表于 2015-6-30 21:19 | 显示全部楼层
先关断输出,再打开响应的PWM通道和GPIO;
冰河w 发表于 2015-6-30 22:14 | 显示全部楼层
你说的对,最后我发现是相序不对

什么相序不对,错在哪儿了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

14

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部