[求助] 无刷直流电机不转

thor1991   2015-7-9 10:18 楼主
  1. /* MAIN.C file
  2. *
  3. * Copyright (c) 2002-2005 STMicroelectronics
  4. */


  5. /* MAIN.C file
  6. 摘要:
  7. 1.PD7延时反转,指示系统工作。
  8. 2.上电,按指定PWM输出换相,实现电机基本运转功能。
  9. 3.换相依据为HALl信号,采用PORTD中断功能完成.
  10. 总之,上电根据HALL状态换相,并在输出PWM信号后,电机会转动,
  11. 同时HALL信号不断改变,然后进入捕获中断,进行及时换相。
  12. 如此实现电机的运转控制。
  13. 2013.5.8
  14. */
  15. #include "stm8s.h"

  16. #define STM8_FREQ_MHZ 16
  17. #define PWM_FREQUENCY 16000

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

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

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

  26. //上桥臂开关控制端口定义
  27. #define MCO1_PORT GPIOC
  28. #define MCO1_PIN        GPIO_PIN_1
  29. #define MCO3_PORT GPIOC
  30. #define MCO3_PIN        GPIO_PIN_2
  31. #define MCO5_PORT GPIOC
  32. #define MCO5_PIN        GPIO_PIN_3

  33. //下桥臂开关控制端口定义
  34. #define MCO0_PORT GPIOB
  35. #define MCO0_PIN        GPIO_PIN_0
  36. #define MCO2_PORT GPIOB
  37. #define MCO2_PIN        GPIO_PIN_1
  38. #define MCO4_PORT GPIOB
  39. #define MCO4_PIN        GPIO_PIN_2
  40. //下桥臂低电平开关管导通
  41. #define PWM_A_OFF MCO0_PORT->ODR |= (u8)MCO0_PIN;
  42. #define PWM_B_OFF MCO2_PORT->ODR |= (u8)MCO2_PIN;
  43. #define PWM_C_OFF MCO4_PORT->ODR |= (u8)MCO4_PIN;

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

  47. //霍尔引脚定义
  48. #define H1_PORT GPIOD->IDR
  49. #define H1_PIN  BIT2

  50. #define H2_PORT GPIOD->IDR
  51. #define H2_PIN  BIT3

  52. #define H3_PORT GPIOD->IDR
  53. #define H3_PIN  BIT4

  54. unsigned char bHallSteps[2][8]={
  55. {7,5,3,4,1,0,2,7},//正转
  56. {7,2,0,1,4,3,5,7}//反转
  57. };

  58. /* Private vars and define */
  59. #define BIT0 0x01
  60. #define BIT1 0x02
  61. #define BIT2 0x04
  62. #define BIT3 0x08
  63. #define BIT4 0x10
  64. #define BIT5 0x20
  65. #define BIT6 0x40
  66. #define BIT7 0x80

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

  69. unsigned int outpwm=0;
  70.        

  71. //初始化按键,指示灯端口
  72. void GPIO_int(void)
  73. {
  74.          /* LEDs */
  75.         GPIO_Init(GPIOD, GPIO_PIN_7, GPIO_MODE_OUT_PP_HIGH_FAST);
  76. }

  77. //系统时钟配置:内部16M
  78. void Clock_init(void)
  79. {
  80.         /* Select fCPU = 16MHz */
  81.   CLK_SYSCLKConfig(CLK_PRESCALER_HSIDIV1);
  82. }

  83. //换相电路开关管IO初始化
  84. void PWM_IO_init(void)
  85. {       
  86.   //PB012 下桥臂0有效 ,配置为高电平
  87.         GPIO_Init(MCO0_PORT, MCO0_PIN,GPIO_MODE_OUT_PP_HIGH_FAST);
  88.         GPIO_Init(MCO2_PORT, MCO2_PIN,GPIO_MODE_OUT_PP_HIGH_FAST);
  89.         GPIO_Init(MCO4_PORT, MCO4_PIN,GPIO_MODE_OUT_PP_HIGH_FAST);
  90.        
  91.         //PC123 上桥臂1有效,配置为低电平
  92.         GPIO_Init(MCO1_PORT, MCO1_PIN,GPIO_MODE_OUT_PP_LOW_FAST);
  93.         GPIO_Init(MCO3_PORT, MCO3_PIN,GPIO_MODE_OUT_PP_LOW_FAST);
  94.         GPIO_Init(MCO5_PORT, MCO5_PIN,GPIO_MODE_OUT_PP_LOW_FAST);       
  95. }

  96. void Tim1_init(void)
  97. {
  98.          /* TIM1 Peripheral Configuration */
  99.   TIM1_DeInit();

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

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

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

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

  104.   TIM1_CCPreloadControl(DISABLE);
  105.         TIM1_Cmd(ENABLE);
  106. }

  107. //初始化HALL捕获输入定义器,采用PD口外部中断捕获输入
  108. void HALLEXTI_INIT(void)
  109. {
  110.         GPIO_Init(GPIOD, GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4,GPIO_MODE_IN_PU_IT);        //HALL端口模式配置
  111. }

  112. //根据HALL状态换相,启动电机运行
  113. void HALL_START(void)
  114. {
  115.         u8 bHStatus = 0,bHallStartStep;
  116.                        
  117.                 // Read status of H1
  118.         if (H1_PORT & H1_PIN)
  119.         {
  120.                 bHStatus |= BIT2;
  121.         }
  122.        
  123.         // Read status of H2
  124.         if (H2_PORT & H2_PIN)
  125.         {
  126.                 bHStatus |= BIT1;
  127.         }
  128.                
  129.                 // Read status of H3
  130.         if (H3_PORT & H3_PIN)
  131.         {                       
  132.                         bHStatus |= BIT0;
  133.         }
  134.        
  135.         bHallStartStep = bHallSteps[1][bHStatus];//得到换相步序

  136.         if (bHallStartStep == 7)//不该出现的HALL状态
  137.         {                       
  138.                         return;
  139.         }
  140.                
  141.                
  142.                 GPIOD->CR2|=BIT3|BIT2|BIT4;
  143.                 EXTI->CR1|=BIT6|BIT7;
  144.                 Commutation(bHallStartStep,outpwm);//输出PWM信号,启动电机
  145. }

  146. @far @interrupt void EXTI_PORTD_IRQHandler(void)
  147. {
  148.         /* in order to detect unexpected events during development,
  149.            it is recommended to set a breakpoint on the following instruction
  150.         */
  151.         u8 bHStatus =0,i,bHallStartStep;
  152.                
  153.         bHStatus=(GPIO_ReadInputData(GPIOD)>>2)&0x07;
  154.         for(i=0;i<50;i++);//滤波时间
  155.         i=(GPIO_ReadInputData(GPIOD)>>2)&0x07;
  156.         if(bHStatus!=i)return;
  157.        
  158.         bHStatus=0;       
  159.                 // Read status of H1
  160.         if (H1_PORT & H1_PIN)
  161.         {
  162.                 bHStatus |= BIT2;
  163.         }
  164.        
  165.         // Read status of H2
  166.         if (H2_PORT & H2_PIN)
  167.         {
  168.                 bHStatus |= BIT1;
  169.         }
  170.                        
  171.         // Read status of H3
  172.         if (H3_PORT & H3_PIN)
  173.         {
  174.                         bHStatus |= BIT0;
  175.         }

  176.                 bHallStartStep = bHallSteps[1][bHStatus];//得到换相步序

  177.                 if (bHallStartStep == 7)
  178.                 { //故障,停止输出
  179.                         TIM1->BKR &= (uint8_t)(~TIM1_BKR_MOE);//禁止PWM输出
  180.                         PWM_A_OFF;
  181.                         PWM_B_OFF;
  182.                         PWM_C_OFF;
  183.                         return;
  184.                 }
  185.                
  186.                
  187.                 EXTI->CR1|=BIT6|BIT7;
  188.                 Commutation(bHallStartStep,outpwm);//输出PWM信号,启动电机
  189.         return;
  190. }

  191. void ChongD(void)
  192. {       
  193.   unsigned int tem_c=0;
  194.         PWM_A_ON;PWM_B_ON;PWM_C_ON;
  195.         for(tem_c=0;tem_c<50000;tem_c++);
  196.         PWM_A_OFF;PWM_B_OFF;PWM_C_OFF;
  197. }

  198. main()
  199. {
  200.   unsigned int tem_c=0;
  201.         unsigned char step=0;
  202.        
  203.         for(tem_c=0;tem_c<50000;tem_c++);//上电延时,等待系统稳定

  204.         Clock_init();//指示灯端口初始化
  205.         GPIO_int();//时钟配置
  206.        
  207.         PWM_IO_init();//开关管控制端口初始化
  208.         Tim1_init();//高级定时器配置       
  209.         HALLEXTI_INIT();//HALL端口初始化配置
  210.         ChongD();
  211.         outpwm=hArrPwmVal*PWMOUT/100;//固定占空比的PWM值
  212.         HALL_START();//根据HALL状态输出PWM状态,启动电机运行
  213.         enableInterrupts();
  214.        
  215.         while (1);
  216.         {
  217.                 for(tem_c=0;tem_c<50000;tem_c++);//延时时间
  218.                 GPIO_WriteReverse(GPIOD,GPIO_PIN_7);//PD7指示灯反转
  219.         }
  220. }

  221. //换向输出PWM值,
  222. //bHallStartStep:当前换相步序0-5,OutPwmValue 输出PWM值
  223. void Commutation(unsigned char bHallStartStep,unsigned int OutPwmValue)
  224. {       
  225.    TIM1->BKR &= (uint8_t)(~TIM1_BKR_MOE);//禁止PWM输出
  226.         if(bHallStartStep!=3&&bHallStartStep!=4)
  227.         PWM_A_OFF;
  228.         if(bHallStartStep!=0&&bHallStartStep!=5)
  229.         PWM_B_OFF;
  230.         if(bHallStartStep!=1&&bHallStartStep!=2)
  231.         PWM_C_OFF;
  232.          
  233.         //根据换相步序,打开不同的开关管,并施加正确的PWM信号
  234.         if(bHallStartStep==0)//AB
  235.         {
  236.                 TIM1->CCR3H = (uint8_t)(OutPwmValue >> 8);
  237.     TIM1->CCR3L = (uint8_t)(OutPwmValue);
  238.                 PWM_B_ON;
  239.         }
  240.   else if(bHallStartStep==1)        //AC
  241.         {
  242.                 TIM1->CCR3H = (uint8_t)(OutPwmValue >> 8);
  243.     TIM1->CCR3L = (uint8_t)(OutPwmValue);
  244.           PWM_C_ON;
  245.         }
  246.         else if(bHallStartStep==2)        //BC
  247.         {
  248.                 TIM1->CCR2H = (uint8_t)(OutPwmValue >> 8);
  249.     TIM1->CCR2L = (uint8_t)(OutPwmValue);
  250.           PWM_C_ON;
  251.         }
  252.         else if(bHallStartStep==3)        //BA
  253.         {
  254.                 TIM1->CCR2H = (uint8_t)(OutPwmValue >> 8);
  255.     TIM1->CCR2L = (uint8_t)(OutPwmValue);
  256.           PWM_A_ON;
  257.         }
  258.         else if(bHallStartStep==4)//CA
  259.         {
  260.                 TIM1->CCR1H = (uint8_t)(OutPwmValue >> 8);
  261.     TIM1->CCR1L = (uint8_t)(OutPwmValue);
  262.           PWM_A_ON;
  263.         }
  264.         else if(bHallStartStep==5)        //CB
  265.         {
  266.                 TIM1->CCR1H = (uint8_t)(OutPwmValue >> 8);
  267.     TIM1->CCR1L = (uint8_t)(OutPwmValue);
  268.           PWM_B_ON;
  269.         }
  270.        
  271.         TIM1->CCER1=PWM_EN1_TAB[bHallStartStep];
  272.         TIM1->CCER2=PWM_EN2_TAB[bHallStartStep];               
  273.         TIM1->BKR|=TIM1_BKR_MOE;//使能PWM输出
  274. }

  275. #ifdef USE_FULL_ASSERT

  276. /**
  277.   * @brief  Reports the name of the source file and the source line number
  278.   *   where the assert_param error has occurred.
  279.   * @param file: pointer to the source file name
  280.   * @param line: assert_param error line source number
  281.   * @retval : None
  282.   */
  283. void assert_failed(u8* file, u32 line)
  284. {
  285.   /* User can add his own implementation to report the file name and line number,
  286.      ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  287.   /* Infinite loop */
  288.   while (1)
  289.   {
  290.   }
  291. }
  292. #endif



程序控制三相120°无刷直流电机,芯片为stm8s207rb其中有六状态,本应该是下面六种相序
UH WL           UH VL
WH  VL         WH UL
VH UL          VH  WL
用PD口外部中断捕获霍尔信号,却出现
UH VL WL       UH UL WL   
WH WL UL      WH WL UL
VH VL UL       VH VL WL
写的程序出现了上下桥同时导通的情况
请问各位大神,这个该怎么解决?????

回复评论

暂无评论,赶紧抢沙发吧
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复