EmbeddedRelated.com
Forums
Memfault Beyond the Launch

input capture problem

Started by chai...@hotmail.com October 12, 2008
Hi,

Im trying to use input capture to sense the rising edge from the encoder.
It seems like my program cant go into the interrupt function. After i sense 100 times rising edge, i set ptm.0 to be 1. Im using channel 5 as input capture.

void interrupt TIC5 (void)
{
int i;
i = i + 1;
if(i == 100)
{
PTM = 0xFF;
}

TFLG1 = 0x20;
}

void main (void)
{
EnableInterrupts;

DDRT = 0x00;
DDRM = 0xFF;

TIOS = 0x00;
TIE = 0x20;
TCTL3 = 0x04;
TSCR2 = 0x03;
TSCR1 = 0x80;
TFLG1 = 0x20;
}

When you want to read Encoder's Pulses ( --> R.P.M) , you can use
HCS12's PulseAcculator.

HCS12 have two 16bit-PulseAcculators : PulseAcc A (PT7) , PulseAcc B
(PT0) or four 8bit- Pulse Accs.

Method for read Encodef's pulses:
+ Enable PulseAcculator A ( Detect rising Edge or Falling Egde)
+ Enable Timer and use Interrupt ( example TOC2 )
+ When Timer Interrupt (ex: 20ms), you read value Pulses (from PAC32
register - if you use PulseAcc-A)

If you use PulseAcc to measure Motor's Speed, i will post my code . (i
am using MC9S12DP512 to Control Speed DC-Motor with PID-fuzzy logic)

Regards,
HoangLongU
Im using it to control the motor speed and know the direction of rotation.
Can you send me the code or post it here?
Thanks for your help

Here is my code for Reading Motor's Speed , use PulseAcc-A and TOC2
+> TOC2 make a Timer Interrupt 20ms
+> PulseAcc-A detect Rising Edge, PulseAcc-A connect with pin-PT7.

I use CodeWarrior 4.7- Special Version.

#include /* common defines and macros */
#include /* derivative information */
#include
#include "pll.h" /* Use PLL --> Bus Clock: 24Mhz/
#include "SCI0.H"

#pragma LINK_INFO DERIVATIVE "mc9s12dp512"

//------------ GLOBAL VARAIBLE --------------//
int count_pulse,count=0 ,speed_temp=0 ,speed_exac=0 ;
unsigned char ngan,length,index=0;
int toc_do_dat= 80,toc_do_do ,prior_OCR0@,set_speed = 2400;
int bnn_ET[3],bnn_DET[3]; // for Fuzzy-Rule-Table
int u[3][3];
signed int ET,DET,ss_cu = 0,ss_moi = 0 ;

float temp_value, temp_add ;
signed int Kp,Ki,alpha,Kd, du ; //PID varaible

static char LCD_SSpeed[4] =" ";
static char LCD_RSpeed[4] =" ";
static char LCD_SysTime[19] =" "; // 0 -->18
//"xx/xx/xx - hh:mm:ss"
//-------//

// ----------------PWM_Init--------------------//
/* enable PWM channel 0 - 2 Khz Frequency

period = PWMPER0 * 2^(PCKA+1) * PWMSCLA (when: PWMCLK = 1)

Use PLL --> Bus Clock 24Mhz
*/

void PWM_Init(void){
PWMCTL = PWMCTL & ~0xF0 ;
PWMPRCLK = PWMPRCLK & ~0x07 ; // PCKA = 0
PWMCLK = PWMCLK | 0x01 ; // use PWMSCLA
PWMPOL = PWMPOL | 0x01 ;
PWMSCLA = 30 ; // 1KHz
PWMCAE = PWMCAE & ~0x01 ;
PWMPER0 = 200 ;
PWME = PWME | 0x01 ;
PWMDTY0 = 50 ; // 50% Hiduty
}

////

//--------- TOC2_INit --------------------//
// TOC2 Init
// inputs: none
// outputs: none
void Timer_Init(void){
TSCR1 = 0x80; // Enable TCNT, 24MHz boot mode
TSCR2 = 0x04; // divide by 16 TCNT prescale.+ Disable TOF
Interrupt
/* Bottom three bits of TSCR2 (PR2,PR1,PR0) determine TCNT period
divide fast(24MHz) slow (4MHz)
000 1 42ns TOF 2.73ms 250ns TOF 16.384ms
001 2 84ns TOF 5.46ms 500ns TOF 32.768ms
010 4 167ns TOF 10.9ms 1us TOF 65.536ms
011 8 333ns TOF 21.8ms 2us TOF 131.072ms
100 16 667ns TOF 43.7ms 4us TOF 262.144ns
101 32 1.33us TOF 87.4ms 8us TOF 524.288ms
110 64 2.67us TOF 174.8ms 16us TOF 1.048576s
111 128 5.33us TOF 349.5ms 32us TOF 2.097152s */

TIOS = TIOS | 0x04 ; // PT2 as OutPut Compare
TCTL2 = TCTL2 & ~0x30 ; // Disconnected at pin 2
TFLG1 = 0x04; // Clear Flag
TIE = TIE | 0x04 ; // Enable TOC2 Interrupt
TC3 = TCNT+30000; // At first : 20ms
}
//------//

//---------- Pulse_Acculator Init-------------//
void Pulse_Acc_Init(void){
TIOS = TIOS & ~0x80 ;
TCTL1 = TCTL1 & ~0xC0 ;

PACTL = 0x50 ;
PACN32 = 0 ; // First_value for Counter
}
//-------//

//--------------- TOC2_Interrupt -------------//
interrupt 10 void TOC2hndlr(void){
// Interrupt TOC2 - 20ms - at 24 Mhz Bus Clock

count_pulse = PACN32 ; // Read value from Counter - Pulses
toc_do_do = count_pulse ; /* Speed/20ms --> R.P.M = 30 * toc_do_do
DC motor: Encoder is 100pulses/round */

ss_cu = ss_moi;
ss_moi = toc_do_do - toc_do_dat;
ET = ss_moi; // ET/20ms
DET = (ss_moi - ss_cu); // DET/20ms

count +=1 ; // Increase Count
speed_temp += count_pulse ; // Add

if (count == 30){
speed_exac = speed_temp; // Update Value SPEED (RPM)
speed_temp = 0; // Reset Count
count = 0;
}

PACN32 = 0 ; // Reset Counter
TC2 = TC2 + 30000 ; // 20ms
TFLG1 = 0x04; // Clear Flag of TOC2 Interrupt
}
//-------//

/*...........
(continuted)
........... */

/****----------------- MAIN ---------------****/
void main(void) {

PLL_Init(); // running at 24MHz - You must Write
Timer_Init(); // enable TCNT and TOF_Inti
Pulse_Acc_Init() ; // Enable Pulse_Acc

// SCI0_Init_24(38400) ; // Enable SCI0 at 38400 - 24 Mhz Bus
// PWM_Init(); // Enable PWM
// LCD_init() ; // Enable LCD_module

EnableInterrupts; // Enable Interrupts

/*.............
(continuted)
............ */
}
//-------------------The END ------------------//

**************************************************

I hope you would success.
Regards,
Minh Thao(HoangLongU)
-------
VietNam National University
University of Technology, Ho Chi Minh city
Automatic Control Deparment.
> Im trying to use input capture to sense the rising edge from the encoder.
> It seems like my program cant go into the interrupt function. After i
> sense 100 times rising edge, i set ptm.0 to be 1. Im using channel 5 as
> input capture.
>
> void interrupt TIC5 (void)
> {
> int i;

i is not static and you don't initialize it. So i is probably random!

> i = i + 1;
> if(i == 100)
> {
> PTM = 0xFF;
> }
>
> TFLG1 = 0x20;
> }

Edward

Memfault Beyond the Launch