主题中讨论的其他器件: DRV8301、 LAUNCHXL-F28027F、 controlSUITE、 TMS320F28379D、 MOTORWARE
大家好、我正在使用午餐板 TMS320F29379D + DRV8305处理 BLDC 含传感器电机。我的问题是:
1. 无故障针脚始终接通,对吧?
2.对于 SPI 接口、需要什么配置? 我删除了 J1P、JP2和 JP3。但无法获取输出。
我从 INSTASPIN BLDC=>DRV8301.h 库获取 DRV8305的参考代码。
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.
大家好、我正在使用午餐板 TMS320F29379D + DRV8305处理 BLDC 含传感器电机。我的问题是:
1. 无故障针脚始终接通,对吧?
2.对于 SPI 接口、需要什么配置? 我删除了 J1P、JP2和 JP3。但无法获取输出。
我从 INSTASPIN BLDC=>DRV8301.h 库获取 DRV8305的参考代码。
Vasanth、您好!
问题:当您提到 nFAULT 引脚始终处于"打开"状态时-您是说它在3.3V/5.0V 时始终处于高电平、还是在0V 时始终处于低电平?
至于 SPI 接口、我认为该器件仅具有 SPI 接口型号、因此我认为 SPI 引脚应默认连接。
问题: 您是否正在使用 BOOSTXL-DRV8305EVM PCB?
请告诉我们这是否能解决您的问题。 谢谢!
此致、
Andrew
感谢您的回复。
问题:当您提到 nFAULT 引脚始终处于"打开"状态时-您是说它在3.3V/5.0V 时始终处于高电平、还是在0V 时始终处于低电平?
ANS:故障引脚始终为"打开"、表示在3.3v 下为高电平。
问题: 您是否正在使用 BOOSTXL-DRV8305EVM PCB?
答:是的。
当通过寄存器配置将 ENGATE 置为高电平时、nFAULT LED 变为关闭表示低电平。
Vasanth、您好!
nFAULT 低电平有效、这意味着当 nFAULT = 0V 时指示故障、而当 nFAULT = 3.3V 时指示无故障。 此外、 在 BOOSTXL-DRV8305EVM 上、nFAULT LED 在 nFAULT 为0V 时亮起、而 nFAULT 为3.3V 时 LED 熄灭。
nFAULT LED 在 ENABLE 被拉至高电平前处于开启状态是正常的、因此这是预期的行为。
BOOSTXL-DRV8305EVM 专为无传感器 FOC 控制而设计、因此可能需要对代码进行重大修改以支持霍尔传感器控制。 您是否计划使用传感梯形控制? 您能否提供指向您正在使用的确切参考代码的链接?
此致、
Anthony Lodi
感谢你的答复。
问:您是否计划使用传感梯形控制? =>是的。
正如您提到的"为支持霍尔传感器控制而对代码进行重要修改"、您能详细说明如何实现这一点吗?
参考代码链接:(除了生成两个 PWM、而不是使用1个 PWM 和其他上的 PWM)
controlSUITE
C:\ti\controlSUITE\development_kits\HVMotorCtrl+PfcKit_v2.1\HVBLDC_Sensored
我的代码是:
// // Included Files // #include "F28x_Project.h" //#include "Example_posspeed.h" //#define u 1; //#define v 0; __interrupt void cpu_timer0_isr(void); // // Globals // #define EPWM1_MAX_DB 0x01 #define EPWM2_MAX_DB 0x01 #define EPWM3_MAX_DB 0x01 #define val 600 #define ISRFRQ 100 #define ISRTIME 100 // // Globals // //POSSPEED qep_posspeed = POSSPEED_DEFAULTS; Uint16 InterruptCount = 0; //Uint16 u; int cnttt; int pin; unsigned int pos16bval; unsigned int temp1; float angle; float var; int mechthe; volatile long i; Uint16 A = 0; //unsigned int x1; //unsigned int x2; float x1; float x2; float diff; float speed; float speed_1; //unsigned int diff; //unsigned int speed; Uint16 GPIO_54; Uint16 GPIO_55; Uint16 GPIO_57; Uint16 CmtnTrigHall = 0; // Output: Commutation trigger for Mod6cnt input (0 or 0x7FFF) Uint16 CapCounter = 0; // Variable: Running count of detected edges on ECAP1,2,3 Uint16 DebounceCount = 0; // Variable: Counter/debounce delay current value Uint16 DebounceAmount = 10; // Parameter: Counter delay amount to validate/debounce GPIO readings Uint16 HallGpio = 0; // Variable: Most recent logic level on ECAP/GPIO Uint16 HallGpioBuffer = 0; // Variable: Buffer of last logic level on ECAP/GPIO while being debounced Uint16 HallGpioAccepted = 0; // Variable: Debounced logic level on ECAP/GPIO Uint16 EdgeDebounced = 0; // Variable: Trigger from Debounce function to Hall_Drv, if = 0x7FFF edge is debounced Uint16 HallMap[6] = { 0, 0, 0, 0, 0, 0 }; // Variable: ECAP/GPIO logic levels for HallMapPointer = 0-5 Uint16 CapFlag = 0; // Variable: ECAP flags, indicating which ECAP detected the edge Uint16 StallCount = 0xFFFF; // Variable: If motor stalls, this counter overflow triggers // commutation to start rotation. Rotation is defined as // an edge detection of a hall signal. Uint16 HallMapPointer = 0; // Input/Output (see note below): During hall map creation, this variable points to the // current commutation state. After map creation, it // points to the next commutation state. int16 Revolutions = -10; // Parameter: Running counter, with a revolution defined as 1-cycle // of the 6 hall states Uint16 CmtnPointer = 0; // Uint16 Hall_SeqArray[50]; // Function Prototypes // //void initEpwm(); //__interrupt void prdTick(void); void InitEPwmExample(); void HALL3_CREATE_MAP( void); void HALL3_NEXT_STATE_MACRO(); void HALL3_DETERMINE_STATE_MACRO(); void HALL3_READ_MACRO(); void HALL3_DEBOUNCE_MACRO(); void comm(void); // // Main // void main(void) { // static int idx = 0; // // Step 1. Initialize System Control: // PLL, WatchDog, enable Peripheral Clocks // This example function is found in the F2837xD_SysCtrl.c file. // InitSysCtrl(); // // Step 2. Initialize GPIO: // This example function is found in the F2837xD_Gpio.c file and // illustrates how to set the GPIO to its default state. // InitGpio(); GPIO_SetupPinMux(34, GPIO_MUX_CPU1, 1); GPIO_SetupPinOptions(34, GPIO_OUTPUT, GPIO_PUSHPULL); GPIO_SetupPinMux(54, GPIO_MUX_CPU1, 5); GPIO_SetupPinOptions(54, GPIO_INPUT, GPIO_PUSHPULL); GPIO_SetupPinMux(55, GPIO_MUX_CPU1, 5); GPIO_SetupPinOptions(55, GPIO_INPUT, GPIO_PUSHPULL); GPIO_SetupPinMux(57, GPIO_MUX_CPU1, 5); GPIO_SetupPinOptions(57, GPIO_INPUT, GPIO_PUSHPULL); EALLOW; GpioCtrlRegs.GPBMUX1.bit.GPIO34 = 0; GpioCtrlRegs.GPBDIR.bit.GPIO34 = 1; EDIS; // For this case only init GPIO for eQEP1 and ePWM1 // This function is found in F2837xD_EQep.c // CpuSysRegs.PCLKCR2.bit.EPWM1 = 1; CpuSysRegs.PCLKCR2.bit.EPWM2 = 1; CpuSysRegs.PCLKCR2.bit.EPWM3 = 1; InitEQep1Gpio(); InitEPwm1Gpio(); InitEPwm2Gpio(); InitEPwm3Gpio(); // // Step 3. Clear all __interrupts and initialize PIE vector table: // Disable CPU __interrupts // DINT; // // Initialize the PIE control registers to their default state. // The default state is all PIE __interrupts disabled and flags // are cleared. // This function is found in the F2837xD_PieCtrl.c file. // InitPieCtrl(); // // Disable CPU __interrupts and clear all CPU __interrupt flags: // IER = 0x0000; IFR = 0x0000; // // Initialize the PIE vector table with pointers to the shell Interrupt // Service Routines (ISR). // This will populate the entire table, even if the __interrupt // is not used in this example. This is useful for debug purposes. // The shell ISR routines are found in F2837xD_DefaultIsr.c. // This function is found in F2837xD_PieVect.c. // InitPieVectTable(); // // Interrupts that are used in this example are re-mapped to // ISR functions found within this file. // EALLOW; // This is needed to write to EALLOW protected registers PieVectTable.TIMER0_INT = &cpu_timer0_isr; // PieVectTable.TIMER1_INT = &cpu_timer1_isr; // PieVectTable.TIMER2_INT = &cpu_timer2_isr; EDIS; InitCpuTimers(); ConfigCpuTimer(&CpuTimer0, ISRFRQ, ISRTIME); // 50000 =50ms , 100000=100ms, 10000=10ms CpuTimer0Regs.TCR.all = 0x4001; // Step 5. User specific code, enable __interrupts: // Enable CPU INT1 which is connected to CPU-Timer 0: // //IER |= M_INT3; IER |= M_INT1; // // Enable TINT0 in the PIE: Group 3 __interrupt 1 // // PieCtrlRegs.PIEIER3.bit.INTx1 = 1; PieCtrlRegs.PIEIER1.bit.INTx7 = 1; // // Enable global Interrupts and higher priority real-time debug events: // EINT; // Enable Global __interrupt INTM ERTM; // Enable Global realtime __interrupt DBGM // qep_posspeed.init(&qep_posspeed); //POSSPEED_Init(); // InitECapture(); DebounceAmount = 0; Revolutions = -3; HALL3_DETERMINE_STATE_MACRO(); HallGpioBuffer = HallGpio; /* Init with current ECAP/GPIO logic levels*/ HallGpioAccepted = HallGpio; /* Init with current ECAP/GPIO logic levels*/ // GpioDataRegs.GPADAT.bit.GPIO0=u; EALLOW; CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0; EDIS; InitEPwmExample(); EALLOW; CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1; EDIS; for (;;) { } } __interrupt void cpu_timer0_isr(void) { GpioDataRegs.GPBTOGGLE.bit.GPIO34 = 1; HALL3_READ_MACRO(); if (HallGpioAccepted == 5) { CmtnPointer = 0; } else if (HallGpioAccepted == 1) { CmtnPointer = 1; } else if (HallGpioAccepted == 3) { CmtnPointer = 2; } else if (HallGpioAccepted == 2) { CmtnPointer = 3; } else if (HallGpioAccepted == 6) { CmtnPointer = 4; } else if (HallGpioAccepted == 4) { CmtnPointer = 5; } comm(); PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; } // InitEPwm1Example - Initialize EPWM1 configuration // void InitEPwmExample() { EPwm1Regs.TBPRD = 1200; // Set timer period EPwm2Regs.TBPRD = 1200; // Set timer period EPwm3Regs.TBPRD = 1200; // Set timer period EPwm1Regs.TBPHS.bit.TBPHS = 0x0000; // Phase is 0 EPwm2Regs.TBPHS.bit.TBPHS = 0x0000; // Phase is 0 EPwm3Regs.TBPHS.bit.TBPHS = 0x0000; // Phase is 0 EPwm1Regs.TBCTR = 0x0000; // Clear counter EPwm2Regs.TBCTR = 0x0000; // Clear counter EPwm3Regs.TBCTR = 0x0000; // Clear counter // // Setup TBCLK // EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count up EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV2; // Clock ratio to SYSCLKOUT EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV2; // Slow so we can observe on EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count up EPwm2Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV2; // Clock ratio to SYSCLKOUT EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV2; // Slow so we can observe on EPwm3Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count up EPwm3Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading EPwm3Regs.TBCTL.bit.HSPCLKDIV = TB_DIV2; // Clock ratio to SYSCLKOUT EPwm3Regs.TBCTL.bit.CLKDIV = TB_DIV2; // Slow so we can observe on // the scope EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_IMMEDIATE; // Load registers every ZERO EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_IMMEDIATE; EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_IMMEDIATE; // Load registers every ZERO EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_IMMEDIATE; EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; EPwm3Regs.CMPCTL.bit.SHDWAMODE = CC_IMMEDIATE; // Load registers every ZERO EPwm3Regs.CMPCTL.bit.SHDWBMODE = CC_IMMEDIATE; EPwm3Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; EPwm3Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // // // Setup compare // EPwm1Regs.CMPA.bit.CMPA = val; EPwm1Regs.CMPB.bit.CMPB = val; EPwm2Regs.CMPA.bit.CMPA = val; EPwm2Regs.CMPB.bit.CMPB = val; EPwm3Regs.CMPA.bit.CMPA = val; EPwm3Regs.CMPB.bit.CMPB = val; } void comm() { static Uint16 CmtnPointer_Prev = 0x0; static int idx=0; // Uint16 HallGpioBitA, HallGpioBitB, HallGpioBitC; // // HallGpioBitA = GPIO_ReadPin(54); // HallGpioBitB = GPIO_ReadPin(55); // HallGpioBitC = GPIO_ReadPin(57); // // HallGpio = (HallGpioBitA << 2) + (HallGpioBitB << 1) + HallGpioBitC; if(CmtnPointer != CmtnPointer_Prev) { Hall_SeqArray[idx] = HallGpioAccepted; if (idx <= 49) { idx = idx + 1; } else { idx = 0; } if (CmtnPointer == 0) { /* InitEPwm1Example(); //1&6 // InitEPwm2Example(); InitEPwm3Example();*/ EPwm1Regs.AQCSFRC.bit.CSFB = 1; //2 EPwm3Regs.AQCSFRC.bit.CSFA = 1; //5 EPwm2Regs.AQCSFRC.bit.CSFB = 1; //4 EPwm2Regs.AQCSFRC.bit.CSFA = 1; //3 EPwm1Regs.AQCSFRC.bit.CSFA = 0; //1 EPwm3Regs.AQCSFRC.bit.CSFB = 0; //6 EPwm1Regs.AQCTLA.bit.CAU = 2; /* Set high when CTR = CMPA on UP-count */ EPwm1Regs.AQCTLA.bit.ZRO = 1; EPwm3Regs.AQCTLB.bit.CBU = 2; /* Set high when CTR = CMPA on UP-count */ EPwm3Regs.AQCTLB.bit.ZRO = 1; } if (CmtnPointer == 1) { /* // InitEPwm1Example(); //1&4 InitEPwm2Example(); InitEPwm3Example();*/ EPwm2Regs.AQCSFRC.bit.CSFB = 1; //4 EPwm3Regs.AQCSFRC.bit.CSFA = 1; //5 EPwm1Regs.AQCSFRC.bit.CSFB = 1; //2 EPwm1Regs.AQCSFRC.bit.CSFA = 1; //1 EPwm3Regs.AQCSFRC.bit.CSFB = 0; //6 EPwm2Regs.AQCSFRC.bit.CSFA = 0; //3 EPwm2Regs.AQCTLA.bit.CAU = 2; //3 EPwm2Regs.AQCTLA.bit.ZRO = 1; EPwm3Regs.AQCTLB.bit.CBU = 2; //6 EPwm3Regs.AQCTLB.bit.ZRO = 1; } if (CmtnPointer == 2) { EPwm2Regs.AQCSFRC.bit.CSFA = 1; //3 EPwm3Regs.AQCSFRC.bit.CSFB = 1; //6 EPwm1Regs.AQCSFRC.bit.CSFB = 1; //2 EPwm1Regs.AQCSFRC.bit.CSFA = 1; //1 EPwm3Regs.AQCSFRC.bit.CSFA = 0; //5 EPwm2Regs.AQCSFRC.bit.CSFB = 0; //4 EPwm2Regs.AQCTLB.bit.CBU = 2; //4 EPwm2Regs.AQCTLB.bit.ZRO = 1; EPwm3Regs.AQCTLA.bit.CAU = 2; //5 EPwm3Regs.AQCTLA.bit.ZRO = 1; } if (CmtnPointer == 3) { EPwm1Regs.AQCSFRC.bit.CSFB = 1; //2 EPwm2Regs.AQCSFRC.bit.CSFA = 1; //3 EPwm3Regs.AQCSFRC.bit.CSFB = 1; //6 EPwm3Regs.AQCSFRC.bit.CSFA = 1; //5 EPwm1Regs.AQCSFRC.bit.CSFA = 0; //1 EPwm2Regs.AQCSFRC.bit.CSFB = 0; //4 EPwm1Regs.AQCTLA.bit.CAU = 2; /* Set high when CTR = CMPA on UP-count */\ EPwm1Regs.AQCTLA.bit.ZRO = 1; EPwm2Regs.AQCTLB.bit.CBU = 2; /* Set high when CTR = CMPA on UP-count */\ EPwm2Regs.AQCTLB.bit.ZRO = 1; } if (CmtnPointer == 4) { EPwm1Regs.AQCSFRC.bit.CSFA = 1; //1 EPwm2Regs.AQCSFRC.bit.CSFB = 1; //4 EPwm3Regs.AQCSFRC.bit.CSFB = 1; //5 EPwm3Regs.AQCSFRC.bit.CSFA = 1; //6 EPwm1Regs.AQCSFRC.bit.CSFB = 0; //2 EPwm2Regs.AQCSFRC.bit.CSFA = 0; //3 EPwm2Regs.AQCTLA.bit.CAU = 2; //3 EPwm2Regs.AQCTLA.bit.ZRO = 1; EPwm1Regs.AQCTLB.bit.CBU = 2; //2 EPwm1Regs.AQCTLB.bit.ZRO = 1; } if (CmtnPointer == 5) { EPwm1Regs.AQCSFRC.bit.CSFA = 1; //1 EPwm3Regs.AQCSFRC.bit.CSFB = 1; //6 EPwm2Regs.AQCSFRC.bit.CSFB = 1; //4 EPwm2Regs.AQCSFRC.bit.CSFA = 1; //3 EPwm1Regs.AQCSFRC.bit.CSFB = 0; //2 EPwm3Regs.AQCSFRC.bit.CSFA = 0; //5 EPwm3Regs.AQCTLA.bit.CAU = 2; //5 EPwm3Regs.AQCTLA.bit.ZRO = 1; EPwm1Regs.AQCTLB.bit.CBU = 2; //2 EPwm1Regs.AQCTLB.bit.ZRO = 1; } } CmtnPointer_Prev = CmtnPointer; } void HALL3_DETERMINE_STATE_MACRO() { //Uint32 temp; Uint16 HallGpioBitA, HallGpioBitB, HallGpioBitC; HallGpioBitA = GPIO_ReadPin(54); HallGpioBitB = GPIO_ReadPin(55); HallGpioBitC = GPIO_ReadPin(57); HallGpio = (HallGpioBitA << 2) + (HallGpioBitB << 1) + HallGpioBitC; } void HALL3_READ_MACRO() { CmtnTrigHall = 0; /* Reset trigger, it only handshakes with calling program.*/ if (EdgeDebounced == 0) /* Debounce current position. */ { HALL3_DEBOUNCE_MACRO(); CmtnTrigHall = EdgeDebounced; /* Set Commutation trigger here*/ } else { /* If current position is debounced, find match in table */ HALL3_NEXT_STATE_MACRO(); /* and return pointer to current state. Ptr to be incremented*/ } /* by MOD6CNT after RET.*/ // EdgeDebounced = 0; /* Reset trigger*/ } void HALL3_DEBOUNCE_MACRO() /* read HallGpio*/ { HALL3_DETERMINE_STATE_MACRO(); if (HallGpio == HallGpioAccepted) /* GPIO_UNCHANGED: Current GPIO reading == debounced ..*/ /*..GPIO reading, no change in state (no edge yet) */ { if (Revolutions <= 0) /* Only create hall map during initial Revolutions*/ { HALL3_CREATE_MAP( ); } StallCount -= 1; /* Decrement stall counter*/ if (StallCount == 0) { EdgeDebounced = 0x7FFF; /* 0x7FFF If motor has stalled, then user trigger to commutate*/\ StallCount = 0xFFFF; /* Reset counter to starting value*/ } DebounceCount = 0; } else /* GPIO_CHANGED: Motor might have moved to a new position.*/ { if (HallGpio == HallGpioBuffer) /* Current GPIO reading == previous GPIO reading?*/ { if (DebounceCount >= DebounceAmount) /* If equal, is current GPIO reading debounced?*/ { HallGpioAccepted = HallGpioBuffer; /* Current GPIO reading is now debounced*/ EdgeDebounced = 0x7FFF; /*Edge/position debounced, trigger commutation*/\ StallCount = 0xFFFF; /* On new edge, reset stall counter*/ CapCounter += 1; /* Increment running edge detection counter*/ DebounceCount = 0; /* Reset debounce counter*/ if (HallMapPointer == 0) Revolutions += 1; /* Increment on every rev (HallMapPointer = 0)*/ } else /* DEBOUNCE_MORE*/ DebounceCount += 1; /* Increment debounce counter*/ } else /* NEW_READING*/ { HallGpioBuffer = HallGpio; /* Save new reading and reset debounce counter*/ DebounceCount = 0; } } } void HALL3_NEXT_STATE_MACRO() { if (Revolutions > 0) /* Only run function after map has been created.*/ { int16 i, HallPointer; for (i = 0; i <= 5; i++) /* Search for a match of current debounced GPIO position*/ { /* and the table entries.*/ if (HallMap[i] == HallGpioAccepted) /* Match_Found*/ { HallPointer = i; } } HallMapPointer = HallPointer; /* On match, save pointer position. Pointer will be incremented */ } /* by 1 since MOD6CNT will receive a positive trigger*/ } void HALL3_CREATE_MAP(void) { HallMap[HallMapPointer] = HallGpioAccepted; /* Save debounced GPIO to table.*/ //return HallGpioAccepted ; }
提供进一步的援助将是有益的。
DRV8305和 TMS320F28379D SPI 接口的代码为:(仅生成 PWM)
// // Included Files // #include "F28x_Project.h" // Device Header file and Examples Include File // // Defines // #define PWM_PERIOD 2500 //2500 for 20kHz //1000 for 50kHz // Period register #define DEAD_TIME 0// results in a deadtime of 500ns @20kHz #define nFAULT GpioDataRegs.GPADAT.bit.GPIO13 #define nSLEEP 37 #define HALLA 58 #define HALLB 30 #define HALLC 40 #define EN_GATE 124 #define WAKE 125 #define EPWM1_MAX_DB 0x01 #define EPWM2_MAX_DB 0x01 #define EPWM3_MAX_DB 0x01 #define val 2500 #define EPWM1_MIN_DB 0 #define EPWM2_MIN_DB 0 #define EPWM3_MIN_DB 0 #define DB_UP 1 #define DB_DOWN 0 // // Globals // Uint32 EPwm1TimerIntCount; Uint32 EPwm2TimerIntCount; Uint32 EPwm3TimerIntCount; Uint16 EPwm1_DB_Direction; Uint16 EPwm2_DB_Direction; Uint16 EPwm3_DB_Direction; // // Typedef // //typedef struct //{ // volatile struct EPWM_REGS *EPwmRegHandle; //} EPWM_INFO; // // Globals // float pwmDutyCycle; int pwmTrip; int current_duty_cycle; int rampCounter; int accelDelay; int hall_state; int hall_read; //EPWM_INFO epwm1_info; //EPWM_INFO epwm2_info; //EPWM_INFO epwm3_info; bool OutputEnable = 1; bool FaultLED = 0; bool FAULT_BIT = 0; bool resetFault = 0; Uint16 FaultCounter = 0; Uint16 FaultLimit = 5; bool spiWrite = false; bool spiRead = false; bool spiReadAll = false; bool clear_fault = false; Uint16 spi_addr = 0; Uint16 spi_data = 0; //Global Status Regs struct drv8305regs { Uint16 WARNINGS_WDRST_ADDR; Uint16 OV_VDS_STATUS_ADDR; Uint16 IC_STATUS_ADDR; Uint16 VGS_STATUS_ADDR; Uint16 HS_GATE_DRIVE_ADDR; Uint16 LS_GATE_DRIVE_ADDR; Uint16 GATE_DRIVE_CTRL_ADDR; Uint16 IC_OPERATION_ADDR; Uint16 SHUNT_AMP_CTRL_ADDR; Uint16 VREG_CTRL_ADDR; Uint16 VDS_SENSE_CTRL_ADDR; } drv8305regs; Uint16 spiData; // // Function Prototypes // void DRV_InitGpio(void); void DRV_InitGpioInput(void); void DRV_InitGpioOutput(void); void Config_evm_spi(void); Uint16 spi_xmit(Uint16 spiFrame); Uint16 spi_write(Uint16 addr, Uint16 data); Uint16 spi_read(Uint16 addr); //void EPWM_Init(void); void error(void); void InitEPwm1Example(void); //void Set_HS0_LS1(EPWM_INFO *epwm_info); //void Set_HS0_LS0(EPWM_INFO *epwm_info); //void Set_PWM(EPWM_INFO *epwm_info, int duty_cycle); void clearFault(void); void resetDRV(void); void readStatusRegisters(void); void readAllRegisters(void); void main(void) { // // Initialize System Control: // PLL, WatchDog, enable Peripheral Clocks // InitSysCtrl(); // // Initialize GPIO: // These GPIOs control LEDs, AFE GPIOS. // // InitGpio(); DRV_InitGpioInput(); DRV_InitGpioOutput(); InitSpiaGpio(); InitEPwm1Gpio(); // // Initialize SPI // Config_evm_spi(); // // Initialize PIE vector table: // //DINT; // // Initialize PIE control registers to their default state: // //InitPieCtrl(); // Disable and clear all CPU interrupts IER = 0x0000; IFR = 0x0000; // // Initialize the PIE vector table with pointers to the shell Interrupt // Service Routines (ISR). // This will populate the entire table, even if the interrupt // is not used in this example. This is useful for debug purposes. // //InitPieVectTable(); // // Interrupts that are used in this example are re-mapped to // ISR functions found within this file. // //EALLOW; //PieVectTable.EPWM2_INT = &epwm3_isr; //EDIS; // //initialize the ePWM // //Initialize and Setup DRV resetDRV(); GPIO_WritePin(WAKE, 1); //set WAKE high to wake up device GPIO_WritePin(EN_GATE, 1); //set EN_GATE high to enable device // int i; // for(i=0;i<30000;i++) // { // if (GpioDataRegs.GPBDAT.bit.GPIO35 == 1) //Once nFAULT goes low, device has completed power-up sequence // { // break; // } // } readAllRegisters(); clearFault(); //Clear faults command //Read All SPI Registers readAllRegisters(); //Align /* Set_PWM(&epwm1_info, current_duty_cycle); Set_HS0_LS1(&epwm3_info); Set_HS0_LS1(&epwm3_info); for(i=0;i<30000;i++) { } */ //Commutation Code and Settings InitEPwm1Example(); while (1) { if(nFAULT == 0) { FaultCounter++; if(FaultCounter >= FaultLimit) { FaultCounter = 0; FaultLED = 1; //Fault has occurred readStatusRegisters(); resetDRV(); // unlockSPI(); clearFault(); readAllRegisters(); } } if (spiWrite) { spi_write(spi_addr,spi_data); spiWrite = false; } if (spiRead) { spi_data = spi_read(spi_addr); spiRead = false; } if (spiReadAll) { readAllRegisters(); spiReadAll = false; } if (clear_fault) { clearFault(); clear_fault = false; } } } // // DRV_InitGpio - Initialize the GPIOs on launchpad and boosterpack // void DRV_InitGpioInput() { EALLOW; // below registers are "protected", allow access. // GPIO DRV Hall A // GPIO_SetupPinMux(54, GPIO_MUX_CPU1, 5); // GPIO_SetupPinOptions(54, GPIO_INPUT, GPIO_PUSHPULL); // // GPIO_SetupPinMux(55, GPIO_MUX_CPU1, 5); // GPIO_SetupPinOptions(55, GPIO_INPUT, GPIO_PUSHPULL); // // GPIO_SetupPinMux(57, GPIO_MUX_CPU1, 5); // GPIO_SetupPinOptions(57, GPIO_INPUT, GPIO_PUSHPULL); // nFAULT GPIO_SetupPinMux(35, GPIO_MUX_CPU1, 0); GPIO_SetupPinOptions(35, GPIO_INPUT, GPIO_PULLUP); EDIS; // Disable register access } void DRV_InitGpioOutput() { //MCU LED GPIO_SetupPinMux(59, GPIO_MUX_CPU1, 0); GPIO_SetupPinOptions(59, GPIO_OUTPUT, GPIO_PUSHPULL); //WAKE GPIO_SetupPinMux(WAKE, GPIO_MUX_CPU1, 0); GPIO_SetupPinOptions(WAKE, GPIO_OUTPUT, GPIO_PUSHPULL); //EN_GATE GPIO_SetupPinMux(EN_GATE, GPIO_MUX_CPU1, 0); GPIO_SetupPinOptions(EN_GATE, GPIO_OUTPUT, GPIO_PUSHPULL); } //void EPWM_Init() //{ //// //// enable PWM6, PWM5 and PWM3 //// // CpuSysRegs.PCLKCR2.bit.EPWM1 = 1; // CpuSysRegs.PCLKCR2.bit.EPWM2 = 1; // CpuSysRegs.PCLKCR2.bit.EPWM3 = 1; //// //// Setup TBCLK //// //// EPwm6Regs.TBPRD = PWM_PERIOD; // Set timer period 16000 TBCLKs //// EPwm6Regs.TBPHS.bit.TBPHS = 0x0000; // Phase is 0 //// EPwm6Regs.TBCTR = 0x0000; // Clear counter // EPwm1Regs.TBPRD = PWM_PERIOD; // Set timer period // EPwm2Regs.TBPRD = PWM_PERIOD; // Set timer period // EPwm3Regs.TBPRD = PWM_PERIOD; // Set timer period // // EPwm1Regs.TBPHS.bit.TBPHS = 0x0000; // Phase is 0 // EPwm2Regs.TBPHS.bit.TBPHS = 0x0000; // Phase is 0 // EPwm3Regs.TBPHS.bit.TBPHS = 0x0000; // Phase is 0 // // EPwm1Regs.TBCTR = 0x0000; // Clear counter // EPwm2Regs.TBCTR = 0x0000; // Clear counter // EPwm3Regs.TBCTR = 0x0000; //// Clear counter // //// //// Setup TBCLK //// // EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count up // EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading // EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // Clock ratio to SYSCLKOUT // EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1; // Slow so we can observe on // EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count up // EPwm2Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading // EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // Clock ratio to SYSCLKOUT // EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV1; // Slow so we can observe on // EPwm3Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count up // EPwm3Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading // EPwm3Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // Clock ratio to SYSCLKOUT // EPwm3Regs.TBCTL.bit.CLKDIV = TB_DIV1; // Slow so we can observe on // // the scope // EPwm1Regs.DBRED.bit.DBRED = EPWM1_MAX_DB; // EPwm2Regs.DBRED.bit.DBRED = EPWM1_MAX_DB; // EPwm3Regs.DBRED.bit.DBRED = EPWM1_MAX_DB; // // EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // Load registers every ZERO // EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; // EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // // EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // Load registers every ZERO // EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; // EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // // EPwm3Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // Load registers every ZERO // EPwm3Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; // EPwm3Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // EPwm3Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; //// // //// Setup compare //// // EPwm1Regs.CMPA.bit.CMPA = val; // EPwm1Regs.CMPB.bit.CMPB = val; // EPwm2Regs.CMPA.bit.CMPA = val; // EPwm2Regs.CMPB.bit.CMPB = val; // EPwm3Regs.CMPA.bit.CMPA = val; // EPwm3Regs.CMPB.bit.CMPB = val; // // //// ////Disable Interrupt //// // EPwm1Regs.ETSEL.bit.INTEN = 0; // disable INT // EPwm2Regs.ETSEL.bit.INTEN = 0; // disable INT // EPwm3Regs.ETSEL.bit.INTEN = 0; // disable INT // //} void Config_evm_spi(void) { //Pin Config // EALLOW; //// SPI_MOSI // GPIO_SetupPinOptions(16, GPIO_INPUT, GPIO_ASYNC | GPIO_PULLUP); //// SPI_MISO // GPIO_SetupPinOptions(17, GPIO_INPUT, GPIO_ASYNC | GPIO_PULLUP); //// SPI_CS // GPIO_SetupPinOptions(61, GPIO_INPUT, GPIO_ASYNC | GPIO_PULLUP); //// SPI_CLK // GPIO_SetupPinOptions(60, GPIO_INPUT, GPIO_ASYNC | GPIO_PULLUP); // // GPIO_SetupPinMux(16, GPIO_MUX_CPU1, 1); // GPIO_SetupPinMux(17, GPIO_MUX_CPU1, 1); // GPIO_SetupPinMux(61, GPIO_MUX_CPU1, 6); // GPIO_SetupPinMux(60, GPIO_MUX_CPU1, 6); // EDIS; EALLOW; ClkCfgRegs.LOSPCP.all = 0; EDIS; // Initialize SPI FIFO registers SpiaRegs.SPIFFTX.all = 0xE040; SpiaRegs.SPIFFRX.all = 0x2044; SpiaRegs.SPIFFCT.all = 0x0; //SPI Settings SpiaRegs.SPICCR.bit.SPISWRESET = 0; //SPI Reset On SpiaRegs.SPICCR.bit.CLKPOLARITY = 0; //SCLK Active High SpiaRegs.SPICCR.bit.SPICHAR = 0xF; //16-bit SPI char SpiaRegs.SPICCR.bit.SPILBK = 0; SpiaRegs.SPICTL.bit.OVERRUNINTENA = 0; //No overrun interrupt SpiaRegs.SPICTL.bit.CLK_PHASE = 0; //Phase 0 SpiaRegs.SPICTL.bit.MASTER_SLAVE = 1; //Master mode SpiaRegs.SPICTL.bit.TALK = 1; //nSCS enabled SpiaRegs.SPICTL.bit.SPIINTENA = 0; //TX/RX Interrupt Disabled SpiaRegs.SPIBRR.bit.SPI_BIT_RATE = ((200E6 / 4) / 500E3) - 1; //Set baud rate to 1MHz // SpiaRegs.SPIBRR.bit.SPI_BIT_RATE = ((25000000 / 1000000) - 1); //Set baud rate to 1MHz SpiaRegs.SPIPRI.bit.FREE = 1; //Set so breakpoints don't disturb transmission SpiaRegs.SPICCR.bit.SPISWRESET = 1; //Exit SPI reset } Uint16 spi_xmit(Uint16 spiFrame) { SpiaRegs.SPITXBUF = spiFrame; //Wait for RX flag to indicate SPI frame completion while (SpiaRegs.SPIFFRX.bit.RXFFST != 1) { } return SpiaRegs.SPIRXBUF; } Uint16 spi_read(Uint16 addr) { Uint16 commandword = (0x8000 | (addr << 11)); return spi_xmit(commandword); } Uint16 spi_write(Uint16 addr, Uint16 data) { Uint16 commandword = ((addr << 11) | data); return spi_xmit(commandword); } void clearFault(void) { Uint16 temp = spi_read(0x09); temp |= 0x02; //write CLR_FLTS bit spi_write(0x09, temp); } void resetDRV(void) { //set nSLEEP low for 100us GPIO_WritePin(WAKE, 0); int i; for (i = 0; i < 10000; i++) ; GPIO_WritePin(WAKE, 1); } void readAllRegisters(void) { drv8305regs.WARNINGS_WDRST_ADDR = spi_read(0x01) & 0xFF; drv8305regs.OV_VDS_STATUS_ADDR = spi_read(0x02) & 0xFF; drv8305regs.IC_STATUS_ADDR = spi_read(0x03) & 0xFF; drv8305regs.VGS_STATUS_ADDR = spi_read(0x04) & 0xFF; drv8305regs.HS_GATE_DRIVE_ADDR = spi_read(0x05) & 0xFF; drv8305regs.LS_GATE_DRIVE_ADDR = spi_read(0x06) & 0xFF; drv8305regs.GATE_DRIVE_CTRL_ADDR = spi_read(0x07) & 0xFF; drv8305regs.IC_OPERATION_ADDR = spi_read(0x09) & 0xFF; drv8305regs.SHUNT_AMP_CTRL_ADDR = spi_read(0x0A) & 0xFF; drv8305regs.VREG_CTRL_ADDR = spi_read(0x0B) & 0xFF; drv8305regs.VDS_SENSE_CTRL_ADDR = spi_read(0x0C) & 0xFF; } void readStatusRegisters(void) { drv8305regs.WARNINGS_WDRST_ADDR = spi_read(0x01) & 0xFF; drv8305regs.OV_VDS_STATUS_ADDR = spi_read(0x02) & 0xFF; drv8305regs.IC_STATUS_ADDR = spi_read(0x03) & 0xFF; drv8305regs.VGS_STATUS_ADDR = spi_read(0x04) & 0xFF; } // // error - Halt debugger when called // void error(void) { ESTOP0; // Stop here and handle error } // // End of file // void InitEPwm1Example() { EPwm1Regs.TBPRD = 6000; // Set timer period EPwm1Regs.TBPHS.bit.TBPHS = 0x0000; // Phase is 0 EPwm1Regs.TBCTR = 0x0000; // Clear counter // // Setup TBCLK // EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV4; // Clock ratio to SYSCLKOUT EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV4; EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // Load registers every ZERO EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // // Setup compare // EPwm1Regs.CMPA.bit.CMPA = 3000; // // Set actions // EPwm1Regs.AQCTLA.bit.CAU = AQ_SET; // Set PWM1A on Zero EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR; EPwm1Regs.AQCTLB.bit.CAU = AQ_CLEAR; // Set PWM1A on Zero EPwm1Regs.AQCTLB.bit.CAD = AQ_SET; // // Active Low PWMs - Setup Deadband // EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_LO; EPwm1Regs.DBCTL.bit.IN_MODE = DBA_ALL; EPwm1Regs.DBRED.bit.DBRED = EPWM1_MIN_DB; EPwm1Regs.DBFED.bit.DBFED = EPWM1_MIN_DB; EPwm1_DB_Direction = DB_UP; }
Vasanth、您好!
只是关注这个讨论-想要分享一些更多信息来帮助调试
要检查的项目:
在上面的描述中、我们看到 EN_GATE = H 会导致 nFAULT 下拉为低电平、这可能是由于系统中存在一些故障(例如某些稳压器未正确加电)。 我建议尝试访问 SPI 寄存器并读取前4个寄存器地址、以检查系统中发生的故障类型
请尝试上述步骤、并告知我们是否需要进一步的支持。 谢谢!
此致、
Andrew
您可以下载并安装 MotorWare 、其中包含一些示例项目、可支持具有 SPI 的 DRV8305。 尽管这些示例基于其他 C2000器 件、如 F2806x 或 F2802x、但您可以参阅这些示例、了解如何将 DRV8305与 TMS320F29379D 搭配使用。
在以下文件夹中查找 LAUNCHXL-F28069M 和 BOOSTXL-DRV8305EVM 的示例实验室项目
C:\ti\motorware\motorware_1_01_00_18\sw\solutions\instaspin_foc\boards\boostxldrv8305_revA\f28x\f2806xF
您也可以参考 http://www.ti.com/tool/CONTROLSUITE 中的示例。
C:\ti\controlSUITE\development_kits\TIDM-SERVO-LAUNCHXs\MonoMtrServo_377s_v1_00_00_00