This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] CCS/MSP430FR2355:BLDC 的无传感器控制设计指南 TIDA-010056

Guru**** 667810 points
Other Parts Discussed in Thread: TIDA-010056, MSP430FR2355
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/864998/ccs-msp430fr2355-sensorless-control-of-bldc-design-guide-tida-010056

器件型号:MSP430FR2355
主题中讨论的其他器件:TIDA-010056

工具/软件:Code Composer Studio

您好!

我之前介绍了设计指南 TIDA-010056中提到的使用 MSP430fr2355对 BLDC 进行无传感器控制的代码。 设计指南中给出了它可用于无传感器应用、但在示例代码中、我无法找到运行无传感器 BLDC 的代码部分。 有人能解释一下示例代码、以便我可以将其用于我的应用。


//器件型号:MSP430FR2355 //编译器 :Code Composer Studio v8.3.0 //振荡器频率:24MHz,使用内部 DCO // PWM 生成 :定时器:TB3.1–TB.6,时钟= 25MHz,PWM 频率设置为20kHz 20kHz // 位置反馈:霍尔传感器信号 // HA -> P3.0 // HB -> P3.1 // HC -> P3.2 * // ADC :A0 ->外部电位计/触发 器的速度参考// A6 ->相位 A 反电动势感应、用于无传感器 // A5 ->用于无传感器的 B 相反电动势感应 // A4 ->用于无传感器的 C 相反电动势感应 // A7 ->直流总线电压感测 // A8 ->低侧直流总线电流感应 // A9 -> PCB 或 FET 温度反馈 * //用于反电动势过零检测的比较器配置 :CB2/P1.2 -> IDC // COMP0.O (P2.0)-相位 A 反电动势过零比较器 // COMP1.O (P2.1)-相位 C 反电动势过零比较器 // OA1O (P1.5)-相位 C 反电动势过零比较器。 智能 COMPO 模块的//opamp 配置为比较 器* //DRV8350RS - SPI 编程引脚连接 // P4.4 -> SCS // P4.5 -> SCLK // P4.6 -> SDO // P4.7 -> SDI * //UART 通信 // P4.2 -> UART RX 引脚 // P4.3 -> UART TX 引脚 //MCU 数字输入/输出 // P5.4 ->电机旋转方向 // P4.1 ->为 DRV8350R 启用连接// P4.0 -> DRV8350R 的 FAULT 引脚连接 // P2.6 -> LED 输出 // 头文件// #include "msp430fr2355.h" #include "stdint.h" #define CALTDH0CTL1_256 *((unsigned int *) 0x1A36) /********* InstaSPIN 代码 / #definePWM_PERIOD600 // PWM 频率(Hz)= 25MHz/((2 * PWM_PERIOD)-1) #defineMAX_DUTYCYCLE600 //相对于 PWM_PERIOD #defineMIN_DUTYCYCLE5 //相对于 PWM_PERIOD #defineACCEL_RATE100 //斜升至满量程占空比的时间=* PWM_RATE #define PWM_RATE =* PWM_RATE ( * PWM_FREQUENCY PWM_RATE DEAD_TIME_MCU1 // MSP430的死区时间= DEAD_TIME* 0.0625us (对于16MHz 时钟) #define BLOCK_Rotor_Duration800 // blocked_but 关闭时间(s)= Block_Rotor_Duration*30000 /计时器时钟频率 ***** 程序变量******** / unsigned int dc_fbus_current = 0; unsigned int dc_BUST_Voltage = 0; unsigned int speed_REF = 0; unsigned int Temperature_feed反馈= 0; unsigned int start_count = 0; unsigned int softstart_counter = 0; unsigned int CurrentDutyCycle = 100; unsigned int direction = 0;unsigned int unsigned int FirstADC_flag = 1; unsigned int ADC_Selection_FLAG = 1; unsigned int Block_Rotor_Counter = 0; unsigned int Block_Rotor_Counter_1 = 0; unsigned int ADC_Result = 0; unsigned int 换向_time = 0; unsigned int 换向_time_counter = 0;unsigned int Adv_time_time = 0;unsigned int Adv_time_time = 0;unsigned int Adv_int_time_angle = 0;unsigned unsigned int sorting_done = 0; unsigned int previous_State = 0; unsigned int prese_State = 0; unsigned int PWM_Duty = PWM_Period; /********* ADC 信道选择********* / #define measure_speed\ ADCCTL0 |= ADCSHT_2 | ADCON;\ ADCCTL1 |= ADCSHP;\ ADCCTL2 &=~ADCRES;\ ADCCTL2 |= ADCRES_2;\ ADCMCTL0 |= ADCINCH_0; \ ADCIE = ADCIE0; #define measure_TEMP \ ADCCTL0 |= ADCSHT_2 | ADCON; \ ADCCTL1 |= ADCSHP; \ ADCCTL2 &=~ADCRES; \ ADCCTL2 |= ADCRES_2; \ ADCMCTL0 |= ADCINCH_9; \ ADCIE = ADCIE0; #define measure_VDC \ ADCCTL0 |= ADCSHT_2 | ADCON; \ ADCCTL1 |= ADCSHP; \ ADCCTL2 &=~ADCRES; \ ADCCTL2 |= ADCRES_2; \ ADCMCTL0 |= ADCINCH_7; \ ADCIE = ADCIE0; #define measure_IDC \ ADCCTL0 |= ADCSHT_2 | ADCON; \ ADCCTL1 |= ADCSHP; \ ADCCTL2 &=~ADCRES; \ ADCCTL2 |= ADCRES_2; \ ADCMCTL0 |= ADCINCH_8; \ ADCIE = ADCIE0; #define measure_BEMF_A \ ADCCTL0 |= ADCSHT_2 | ADCON; \ ADCCTL1 |= ADCSHP; \ ADCCTL2 &=~ADCRES; \ ADCCTL2 |= ADCRES_2; \ ADCMCTL0 |= ADCINCH_6; \ ADCIE = ADCIE0; #define measure_BEMF_B \ ADCCTL0 |= ADCSHT_2 | ADCON; \ ADCCTL1 |= ADCSHP; \ ADCCTL2 &=~ADCRES; \ ADCCTL2 |= ADCRES_2; \ ADCMCTL0 |= ADCINCH_5; \ ADCIE = ADCIE0; #define measure_BEMF_C \ ADCCTL0 |= ADCSHT_2 | ADCON; \ ADCCTL1 |= ADCSHP; \ ADCCTL2 &=~ADCRES; \ ADCCTL2 |= ADCRES_2; \ ADCMCTL0 |= ADCINCH_4; \ ADCIE = ADCIE0; #define conversion:enable \ ADCCTL0 |= ADCENC | ADCSC; #define conversion:disable \ ADCCTL0 &=~ADCENC;\ ADCCTL1 = 0; /********* ADC 通道选择结束 / int LPM3_on = 0; void Init_clocks (void); void init_io (void); void init_wdt (void); void init_adc (void); void init_TimerB (void); void Hall_State_Change_Forward (void); void Hall_State_Change_Reverse (void); void A_PWM (void); void B_PWM (void); void C_PWM (void); void A_low (void); void B_low (void); void C_low (void); void A_Z (void); void B_Z (void); void C_Z (void); void A_high (void); void B_high (void); void C_high (void); void main (void) { WDTCTL = WDTPW + WDTHOLD;//停止 WDT _delay_cycles (1000000); Init_clocks ();//初始化25MHz init_adc 的时钟(); init_TimerB (); init_WDT (); init_io (); A_Z(); B_Z(); C_Z(); _delay_cycles (1000000); /********* 启用 DRV8323 / P4OUT &=~BIT1; _delay_cycles (2500);//100us 延迟 P4OUT |= BIT1; _delay_cycles (250);//10us 延迟 方向=(P5IN 和 BIT4); HALL_State =((P3IN 和 BIT0)+(P3IN 和 BIT1)+(P3IN 和 BIT2)); while (1) { if (softstart_counter >= ACCEL_RATE) }{ iDusycle+ (如果为 CurrentREF+)*、则为0);CurrentDutyCycle (如果为0)+ DutyCycle +(Current0+) if (CurrentDutyCycle >= MAX_DUTYCYCLE) { CurrentDutyCycle = MAX_DUTYCYCLE; } 否则(CurrentDutyCycle <= MIN_DUTYCYCLE) { CurrentDutyCycle = MIN_DUTYCYCLE; } if (DIRECTION ==0) { HALL_State_Change_Forward (); } 其他 { HALL_State_Change_Reverse (); } } } //结束 main // WDT 以重新启动 ADC void init_WDT (void) { WDTCTL = WDT_MDLY_32;// WDT 32ms 从1MHz 开始,SMCLK,间隔定时器 SFRIE1 |= WDTIE;//启用 WDT 中断 } void init_TimerB (void) { TB3CTL = TBSSEL_SMCLK | MC_3 | TBCLR; // SMCLK、UP_DOWN 模式、清除 TBR TB3CCR0 = PWM_PERIOD; // PWM 周期 TB3CCR1 = PWM_PERIOD; // CCR1 PWM 占空比 TB3CCR2 = PWM_PERIOD; // CCR2 PWM 占空比 TB3CCR3 = PWM_PERIOD; // CCR3 PWM 占空比 TB3CCR4 = PWM_PERIOD; // CCR4 PWM 占空比 TB3CCR5 = PWM_PERIOD; // CCR3 PWM 占空比 TB3CCR6 = PWM_PERIOD; // CCR4 PWM 占空比 TB3CCTL1 = OUTMOD_6; // CCR1复位/置位 TB3CCTL2 = OUTMOD_2; // CCR2复位/置位 TB3CCTL3 = OUTMOD_6; // CCR3复位/置位 TB3CCTL4 = OUTMOD_2; // CCR4复位/置位 TB3CCTL5 = OUTMOD_6; // CCR4复位/置位 TB3CCTL6 = OUTMOD_2; // CCR4复位/置位 TB3CCTL0 |= CCIE; __bis_SR_register (GIE); //启用中断 __no_operation(); //对于调试 器_EINT(); //启用中断 } //时钟和 Vcore void Init_clocks (void) { FRCTL0 = FRCTLPW | NWAITS_2; _bis_SR_register (SCG0); //禁用 FLL CSCTL3 |= SELREF_REFOCLK; //将 REFO 设置为 FLL 基准源 CSCTL0 = 0; //清除 DCO 和 MOD 寄存器 CSCTL1 |= DCORSEL_7; //设置 DCO = 24MHz CSCTL2 = FLLD_0 + 731; // DCOCLKDIV = 24MHz _DELAY_CYCLES (3); _BIC_SR_register (SCG0); //启用 FLL while (CSCTL7 &(FLLUNLOCK0 | FLLUNLOCK1)); // FLL 锁定 CSCTL4 = SELMS_DCOCLKDIV | SELA_REFOCLK; //将默认 REFO (~32768Hz)设置为 ACLK 源,ACLK = 32768Hz //默认 DCOCLKDIV 作为 MCLK 和 SMCLK 源 } // IO 初始化// void init_io (void) { //霍尔传感器输入 P3SEL0 &=~(BIT0+BIT1 + BIT1);// GPIO -霍尔传感器 P3DIR &=~ ~(BIT0+1+1+BIT0);// BIT3+ 2–BIT1 (BIT1)/ BIT1 / BIT3+ BIT1);/BIT1 / BIT3+ BIT1 / BIT1 / BIT1 (BIT2)输出 //Output-LED3// 方向控制 P5SEL0 &=~(BIT4);//GPIO - DIR P5DIR &=~(BIT4);//输入- DIR //启用栅极驱动器 P4SEL0 &=~(BIT1); //GPIO - DIR P4DIR |=(BIT1); //输入-方向 //故障输入 P4SEL0 &=~(BIT0); //GPIO - DIR P4DIR &=~(BIT0); //输入-方向 //为霍尔传感器端口启用边沿中断 P3IES |=((BIT0)+(BIT1)+(BIT2)); //将霍尔中断更改为下降边沿以检测两个边沿 P3IE |=(BIT0 | BIT1 | BIT2); PM5CTL0 &=~LOCKLPM5; P3IFG &=~(BIT0| BIT1 | BIT2); _bis_SR_register (GIE); } void init_ADC (void) { //配置 ADC12 ADCCTL0 |= ADCSHT_2 | ADCON; // ADCON、S&H=16 ADC 时钟 ADCCTL1 |= ADCSHP; // ADCCLK = MODOSC;采样定时器 ADCCTL2 &=~ADCRES; //清除 ADCCTL 中的 ADCRES ADCCTL2 |= ADCRES_2; // 12位转换结果 ADCMCTL0 |= ADCINCH_0; // A1 ADC 输入选择;Vref=AVCC ADCIE |= ADCIE0; //启用 ADC 转换完成中断 }/******** TIMERD0.1中断************* // Timer B1中断服务例程 #if defined (__TI_Compiler_version__)|| defined (__IAR_systems_ICC__) #pragma vector = TIMER3_B0_Vector __interrupt void Timer3_B0_ISR (void) #Elif defined (__GINC_)#pragma vector = TIMER3_B0_(TI_COMPLETE )(TI_BINOT_BIST_3)#BIMER 0!(NOT_BINOT_ERROR) #endif { PWM_Duty =(PWM_Period - CurrentDutyCycle); TB3CCR1 = PWM_Duty; // CCR1 PWM 占空比 TB3CCR2 = PWM_DUTY; TB3CCR3 = PWM_DUTY; // CCR1 PWM 占空比 TB3CCR4 = PWM_DUTY; TB3CCR5 = PWM_DUTY; // CCR1 PWM 占空比 TB3CCR6 = PWM_DUTY; 测量速度 转换_ENABLE softstart_counter ++; Block_Rotor_Counter_1_+; IF (Block_Rotter_Counter_1_=30000) { Block_Rotor_Counter++; } IF (Block_Rotor_Counter > Block_Rotor_Duration) { A_Z(); B_Z(); C_Z(); disable_interrupt (); while (1); } } /******** TIMERD0.1中断结束********* / /******** ADC 中断********* // ADC 中断服务例程 #if defined (__TI_Compiler_version__)|| defined (__IAR_systems_ICC__) #pragma vector=ADC_vector __interrupt void ADC_ISR (void) #Elif defined (__GNU__) void __attribute__((interrupt (ADC_vector))))) ADC_ISR #else error! #endif { switch (__evo_in_range (ADCIV、ADCIV_ADCIFG)) { 案例 ADCIV_NONE: 中断; ADCIV_ADCOVIFG 案例: 中断; 案例 ADCIV_ADCTOVIFG: 中断; ADCIV_ADCHIIFG 案例: 中断; ADCIV_ADCLOIFG 案例: 中断; ADCIV_ADCINIFG 案例: 中断; ADCIV_ADCIFG 案例: ADC_RESULT = ADCMEM0; SPEED_REF =(ADC_RESULES>>2); 中断; 默认值: 中断; } } /******** 端口1中断服务例程********* / #if defined (__TI_Compiler_version__)|| Defined (__IAR_systems_ICC__) #pragma vector=PORT3_vector __interrupt void Port_3 (void) #Elif Defined (__GNU__) void __attribute__((interrupt (PORT3_vector)))) Port_3 (void 编译器#else 不支持! #endif { HALL_STATE =((P3IN & BIT0)+(P3IN & BIT1)+(P3IN & BIT2)); if (DIRECTION ==0) { HALL_State_Change_Forward (); } 其他 { HALL_State_Change_Reverse (); } Block_Rotor_Counter = 0; Block_Rotor_Counter_1 = 0; P3IES ^=(BIT0)+(BIT1)+(BIT2); P3IFG &=~(BIT0| BIT1 | BIT2); } /******** ADC 中断结束********* // 看门狗定时器中断服务例程 #pragma vector=WDT_vector __interrupt void WDT_ISR (void) { } /********* 换向序列前进 / void Hall_State_Change_Forward (void) { switch (HALL_State) { case 2: c_Z (); A_PWM (); B_LOW (); break; case 6: b_Z (); A_PWM (); C_LOW (); break; case 3: A_Z (); C_PWM (); b_low (); break; case 1: b_Z (); C_PWM (); a_low (); break; case 4: A_Z (); B_PWM (); C_LOW (); break; 情况5: C_Z (); B_PWM (); A_low (); break; 默认值: A_Z (); B_Z (); C_Z (); break; } / ********* 换向序列反向 / void HALL_State_Change_Reverse (void) { switch (HALL_State) { case 2: c_Z (); B_PWM (); A_low (); break; case 6: b_Z (); c_PWM (); A_low (); break; case 3: A_Z (); B_PWM (); c_low (); break; case 1: b_Z (); a_pwm (); C_low (); break; case 4: A_Z (); C_PWM (); B_LOW (); break; 情况5: C_Z (); A_PWM (); B_LOW (); break; 默认值: A_Z (); B_Z (); C_Z (); break; } / ********* PWM GPIO 的定义 / void A_PWM (void) { P6SEL0 |= BIT0; P6SEL0 |= BIT1; } void B_PWM (void) { P6SEL0 |= BIT2; P6SEL0 |= BIT3; } void C_PWM (void) { P6SEL0 |= BIT4; P6SEL0 ~P0 和 BIT0 |= B0 ~BIT0;P6SIB0 ~B0 BIT0 | P0 = BIT0 void B_LOW (void)~P6SEL0 &=~BIT2;P6OUT &=~BIT2;P6SEL0 &=~BIT3;P6OUT |= BIT3;}void C_LOW (void){P6SEL0 &=~BIT4;P6OUT &=~BIT4;P6OUT 和 P6OUT 和 PIT0 =~B0;P6BIT0和 P6B0和 P6BIT0;P6B0 ~BIT0和 P6B0 ~ ~BITL0 void B_Z (void)~P6SEL0 &=~BIT2;P6OUT &=~BIT2;P6SEL0 &=~BIT3;P6OUT &=~BIT3;}void C_Z (void){P6SEL0 &=~BIT4;P6OUT &=~BIT4;P6OUT &=~BIT4;P6OUT &BIT5 = BIT5;P6OUT & PIT5 =高电平 P6SEL0 &=~BIT0; P6OUT |= BIT0; P6SEL0 &=~BIT1; P6OUT &=~BIT1; } void B_HIGH (void) { P6SEL0 &=~BIT2; P6OUT |= BIT2; P6SEL0 &=~BIT3; P6OUT &=~BIT3; } void C_HIGH (void) { P6SEL0 &=~BIT4; P6OUT |= BIT4; P6SEL0 &=~BIT4; P6OUT &=~BIT4; }/********* 结束 /

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、SOURAV、

    霍尔传感器使用 P3.0 P3.1 P3.2 I/O、您可以在程序或 TIDA-010056用户指南中查看注释。

    此致

    Johnson

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你(们)好,约翰逊

    我在设计手册 TIDA-010056中的程序代码中找到如下所示的注释

    //Comparator configuration for back EMF zero crossing detection             : CB2/P1.2 -> IDC
    //                      COMP0.O (P2.0) – Phase A back EMF zero cross comparator
    //                      COMP1.O(P2.1) – Phase C back EMF zero cross comparator
    //                      OA1O (P1.5) - Phase C back EMF zero cross comparator. The
    //opamp of smart compo module is configured as a comparator
    但 P2.0、P2.1、P1.5绝不用于无传感器应用。
    我认为该代码不适合无传感器 应用。
    请确认此设计是否适用于传感器或无传感器应用?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Ajeet,

    我浏览过此程序。 该程序使用霍尔传感器检测。

     程序中未给出另一个无传感器检测。 如果您想在这个电路板上使用这个方法、 也许您需要自己执行这些程序。

    此致

    Johnson