Wednesday, February 15, 2006

Servo HCS08 working

First lesson learned, you can't manipulate the duty of the TPM within a keyboard interrupt:

void interrupt Vkeyboard intSWITCH1(){
if(SWITCH1 == DOWN){

TPM2C0V = ZERO;

}
if(SWITCH2 == DOWN){
TPM2C0V = ONE_EIGHTY;

}
if(SWITCH3 == DOWN){
TPM2C0V = TPM2C0V -1;
}
if(SWITCH4 == DOWN){
TPM2C0V = TPM2C0V+1;
}
timer2chnl0 = TPM2C0V;*/
KBI1SC_KBACK = 1;//ack

}
This will not work! Wish I knew why, but it won't. In order to properly affect the duty cycle the code must be in the main for loop. Hope I have time to investigate why the software interrupt doesn't function...

Secondly, the original configuration of flipping the bit on PTDF2, again with an interrupt (timer 2 channel 0) was producing aberrations in the PWM! The aberrations were rhythmic in nature and we blamed them on internal software latency; again, wish I knew more about this, but the fact of the matter is that the code was simply this:

void interrupt VTimer2Chnl0 intTimer2Chnl0(){

PTFD_PTFD2 = ~PTFD_PTFD2;

TPM2C0SC_CH0F = 0;
}
. Perhaps this is related to the fact that LED3 is by default wired to the output of PTDF2, and its operation was hosing with the PWM.

Lastly, the the modulation count was still the same for the direct timer output (which for timer 2 channel 0 is PTD3, see http://www.freescale.com/files/microcontrollers/doc/data_sheet/MC9S08GB60.pdf), so:

#define half_ms_duty_50hz (TPM2MOD - (TPM2MOD/40) -2)
#define ONE_EIGHTY half_ms_duty_50hz

void initICG(){
/*configure Internal Clock Generator [ICG]*/
/*MFD[]={4,6,8,10,12,14,16,18}*/
ICGC2_MFD = 7; /*32KHz crystal, demo board.
For 4MHz crystal (eval board):
ICGC2_MFD = 3
*/
ICGC2_RFD = 0; /* RFD[]={1,2,4,8,16,32,64,128}*/
//ICGC1 = 0b00110000;
ICGC1 = 0b00111000;
/*32KHz crystal, demo board.
For 4MHz crystal (eval board):
ICGC1 = 0b01111000;
*/
while((ICGS1_LOCK==0)||(ICGS1_ERCS==0)){
/*Ensure COP doesn't reset device whilst waiting for clock lock*/
__RESET_WATCHDOG(); /* kicks the dog */
}
ICGC2_LOCRE = 1; /*enable reset if clock fails*/

}

void initTimer2Chnl0_50hz(){
TPM2C0SC_CH0IE = 1; //enable channel

TPM2SC_CLKSA = 1;/*Select BUS clock*/
TPM2SC_CLKSB = 0;

TPM2SC_PS = PRESCALAR;/*clock source divided by prescalar*/
TPM2MOD = 1475;/*counter value, counts up to*/

TPM2SC_CPWMS = 1;
/*configure PWM mode and pulse*/
TPM2C0SC_MS0B = 1; /*MS0B=1, MS0A=0; << Edge align PWM*/
TPM2C0SC_ELS0A = 1; /*Select low as true*/

TPM2C0V = ONE_EIGHTY;
}



Once I get the code cleaned up and more presentable, I'll post the entire thing for future replication.

No comments: