Problem with LDOK signal on S12ZVM

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Problem with LDOK signal on S12ZVM

1,235 Views
erikwieser
Contributor I

Hello,

 

I'm using the MC9S12ZVM to control a BLDC motor with one pole pair. As the sample project didn't work out so well, I tried to make a simple project to have basic rotation.

I can move the rotor to every of the 6 possible hall sectors, I do this by simply just changing the PMFVAL0..6 with the corresponding PMFOUTB and PMFOUTC registers. Unfortunately when I try to put all the 6 stages into a loop, it seems that only two of the six stages can be applied.

In the reference manual I read that PMFVALx is buffered and needs the LDOK Signal. Inserted that after every change of PMFVALx but it doesnt make a difference. PMFOUTB and PMFOUTC are unbuffered, because PMFFCG1_ENCE is set to 0.

I also watched some the registers I'm writing to. It seems that every register gets its proper value, except for PMFOUTB which only seems to know two values.

 

What am I doing wrong? Or what did I forget?

 

I would really appreciate your help, many thanks in advance.

Labels (1)
0 Kudos
4 Replies

654 Views
erikwieser
Contributor I

Hi again,

I moved on a little further. Now I get a nice rotation and have ground where I have to have ground. The only thing now is, that always only two phases can have ground and PWM and not connected stages properly. The third phase seems to have PWM on the high gate but not on the low gate and there is never a ground stage on this phase. And on reset this "not properly looking" phase is working as it should but another is having that problem. Why is that?

I hope you understand my issue. If not I could eventually attach a screenshot from the oscillator.

Here is how the interrupt looks now (the rest of the code is still the same):

unsigned char outc[6] = {0x7, 0xD, 0x1C, 0x34, 0x31, 0x13};

unsigned char msk[6] = {0xC, 0x03, 0x30, 0x0C, 0x03, 0x30};

interrupt VectorNumber_Vtim0ch1 void TIMch1_ISR(void) {

hall_pattern = 0x07 & (PTIT >> 1);/* Capture Hall sensor pattern */

hall_a_input = 0x01 & (hall_pattern>>0);

hall_b_input = 0x01 & (hall_pattern>>1);

hall_c_input = 0x01 & (hall_pattern>>2);

switch(hall_pattern) {

case 0x6:

PMFCFG2_MSK = 0x40 +msk[0];

PMFOUTC = outc[0]; break;

case 0x4:

PMFCFG2_MSK = 0x40 + msk[1];

PMFOUTC = outc[1]; break;

case 0x5:

PMFCFG2_MSK = 0x40 + msk[2];

PMFOUTC = outc[2]; break;

case 0x1:

PMFCFG2_MSK = 0x40 + msk[3];

PMFOUTC = outc[3]; break;

case 0x3:

PMFCFG2_MSK = 0x40 + msk[4];

PMFOUTC = outc[4]; break;

case 0x2:

PMFCFG2_MSK = 0x40 + msk[5];

PMFOUTC = outc[5]; break;

default:

PMFOUTB = 0x0;

PMFOUTC = 0x3f; break; }

Many thanks in advance again.

Regards,

Erik

0 Kudos

654 Views
iggi
NXP Employee
NXP Employee

Hi Erik,

It’s not clear what the value of OUTB is. This is necessary to know to understand what output is there in the SW controlled channels.

Compared to our Hall sensor example code, the MSK and OUTC settings are reversed. Attached is the excel sheet with comparison.

Please note that the settings for each sector are actually shifted, if you compare the tables below.

This may be just due to a different assignment of the Hall sensor patterns.


Regards,

iggi




0 Kudos

654 Views
iggi
NXP Employee
NXP Employee

Hi Erik,

If possible, kindly attach your project here. It would be good to look in the source code.

Regards,

iggi

0 Kudos

654 Views
erikwieser
Contributor I

Hi iggi,

in the meantime I managed to move on a bit. The motor is now rotating. The only thing is that on every phase in each sector where there should be ground there is 12V now. Also I don't have a NC stage on the phases, only 12V or Complementary PWMs.

My Code (had some difficulties to copy it into this editor):

#include <hidef.h> /* for EnableInterrupts macro */

#include "derivative.h" /* include peripheral declarations */

#define PWM_MODULO 1200

#define PWM_DEADTIME 10

#define PWM_PRSCA 0

#define LED1 PTS_PTS4

#define LED2 PTS_PTS5

#define PWM 300

#define HIGH 1300

unsigned int period = 30;

unsigned char hall_pattern = 0;

unsigned char hall_a_input = 0;

unsigned char hall_b_input = 0;

unsigned char hall_c_input = 0;

//CW

unsigned char outb[6] = {0x7, 0xD, 0x1C, 0x34, 0x31, 0x13};

unsigned char outctl[6] = {0x0C, 0x03, 0x30, 0x0C, 0x03, 0x30};

unsigned int pmf0[6] = {PWM, HIGH, HIGH, HIGH, HIGH, PWM};

unsigned int pmf2[6] = {HIGH, PWM, PWM, HIGH, HIGH, HIGH};

unsigned int pmf4[6] = {HIGH, HIGH, HIGH, PWM, PWM, HIGH};

interrupt VectorNumber_Vtim0ch1 void TIMch1_ISR(void) {

hall_pattern = 0x07 & (PTIT >> 1);/* Capture Hall sensor pattern */

hall_a_input = 0x01 & (hall_pattern>>0);

hall_b_input = 0x01 & (hall_pattern>>1);

hall_c_input = 0x01 & (hall_pattern>>2);

switch(hall_pattern) {

case 0x6:

PMFOUTB = outb[0];

PMFOUTC = outctl[0];

PMFVAL0 = pmf0[0];

PMFVAL2 = pmf2[0];

PMFVAL4 = pmf4[0]; break;

case 0x4:

PMFOUTB = outb[1];

PMFOUTC = outctl[1];

PMFVAL0 = pmf0[1];

PMFVAL2 = pmf2[1];

PMFVAL4 = pmf4[1]; break;

case 0x5:

PMFOUTB = outb[2];

PMFOUTC = outctl[2];

PMFVAL0 = pmf0[2];

PMFVAL2 = pmf2[2];

PMFVAL4 = pmf4[2]; break;

case 0x1:

PMFOUTB = outb[3];

PMFOUTC = outctl[3];

PMFVAL0 = pmf0[3];

PMFVAL2 = pmf2[3];

PMFVAL4 = pmf4[3]; break;

case 0x3:

PMFOUTB = outb[4];

PMFOUTC = outctl[4];

PMFVAL0 = pmf0[4];

PMFVAL2 = pmf2[4];

PMFVAL4 = pmf4[4]; break;

case 0x2:

PMFOUTB = outb[5];

PMFOUTC = outctl[5];

PMFVAL0 = pmf0[5];

PMFVAL2 = pmf2[5];

PMFVAL4 = pmf4[5]; break;

default:

PMFOUTB = 0x0;

PMFOUTC = 0x3f; break; }

// Clear flag

TIM0TFLG1 = TIM0TFLG1_C1F_MASK;

}

void main(void) {

/*********CPMU Init**************/

// Wait for stable supply after power up

while (GDUF_GLVLSF) {

GDUF_GLVLSF = 1; }

CPMUREFDIV_REFDIV = 0;

CPMUREFDIV_REFFRQ = 0;

CPMUSYNR_SYNDIV = 24;

CPMUSYNR_VCOFRQ = 1;

CPMUPOSTDIV_POSTDIV = 1;

while (CPMUIFLG_LOCK == 0) {}

//Clear PORF and LVRF

CPMURFLG  = 0x60;

/*********PIM Init**************/

// TIM0 input capture channel 1 is connected to logic XOR of PT1, PT2, PT3

MODRR2_T0IC1RR = 1;

// Hall sensor PT1, PT2, PT3 pull-ups enabled

PERT = 0x0E;

// Enable EVDD1

// PP0 +5V

PTP_PTP0 = 1;

// PP0 output

DDRP_DDRP0 = 1;

// PS4 output

DDRS_DDRS4 = 1;

// PS5 output

DDRS_DDRS5 = 1;

PTP_PTP1 = 1;

PTP_PTP2 = 1;

/*********TIM Init**************/

// TIM ch1 input capture

TIM0TIOS_IOS1 = 0;

// Precision timer disabled

TIM0TSCR1_PRNT = 0;

// TIM ch1 input capture on any edge

TIM0TCTL4_EDG1A = 1;

TIM0TCTL4_EDG1B = 1;

// Load prescaler value 

TIM0TSCR2_PR = 7; 

// Disconnect all output compare pins

TIM0OCPD = 0xFF;

// TIM ch1 interrupt enable TIM0TIE_C1I = 1;   

// TIM global enable

TIM0TSCR1_TEN = 1;

/**********PMF Init************/

PMFCFG0_EDGEA = 1;

// Reload every PWM cycle

PMFFQCA = 0;

// PWM clock = core clock / PWM_PRSCA = 25MHz / PWM_PRSCA

PMFFQCA_PRSCA = PWM_PRSCA;

// Load modulo timer A

PMFMODA = PWM_MODULO;

// Load dead time timer A

PMFDTMA = PWM_DEADTIME;

PMFOUTC = 0x3F;

PMFENCA_PWMENA = 1;

/**********GDU Init************/

// Enable Charge pump GDUE_GCPE = 1;

// Set coil current limit to maximum 750mA

GDUBCL = 0x0F;

// Set boost frequency ~ 1MHz

GDUCLK1_GBOCD = 0b01100;

// Set duty cycle to 75%

GDUCLK1_GBODC = 0b11;

// Enable boost GDUE_GBOE = 1;

// Charge pump clock = fbus / 32

GDUCLK2_GCPCD = 2;

// Blanking time ~13us

GDUCTR = 0x13;

// GDU High level set to 26V

GDUCTR_GHHDLVL = 1;

// Desaturation level 1.35V

GDUDSLVL = 0x77;

// Enable pre-driver

GDUE_GFDE = 1;

EnableInterrupts;

for(;;) {

__RESET_WATCHDOG(); /* feeds the dog */

for(int i = 0; i < period; i++){}

if(PMFENCA_LDOKA == 0)   

PMFENCA_LDOKA = 1;

} /* loop forever */

/* please make sure that you never leave main */

}

As mentioned in OP I just want to create a simple rotation and fuly understand how the PMF works with all dependencies like PMFOUTC, PMFOUTB and PMFCFG_MSK and so on.

Thanks in advance.

Regards,

Erik

0 Kudos