Re: Digest Number 492

Started by Lewis, Bob September 25, 2003

I am not sure that we have the same problem but here is what I experienced
that seems similar to what you are doing.

I was using the ECT for double edge detection and interrupt. That is:
-I used IC0(input capture 0) to detect a rising edge and latch the the timer
- on the following edge the count was again latched and an interrupt was
- The holding register was enabled so that on the second count the first
latch was transferred to the holding register, and the latch contained the
second count.
- Then by doing a difference between the holding and latch registers the
period of the signal could be determined. All the setup was done via various
bits in the control registers as you know.

The system worked perfectly when run with the BDM Pod connected, however it
would generate random numbers when the pod was disconnected and run by
hitting the reset. I literally spent weeks on this problem, writing and
rewriting code to do tests and builds of arrays to do comparisons and on and
on. The problem went through to the highest level of support in Motorola and
was really never solved. A long story, but what came out of this was a
suggestion to use only a rising edge interrupt and not use the buffered
registers. I wrote a C test program below that works correctly from reset
and without the pod. I retried the double latch solution and never did
resolve the problem (personally I think there is either a mistake in the
documentation or some other problem, but no one at Motorola could figure it
out). Here is the code that works and that sounds like basically what you
are doing. I try never hard code anything so hence all the definitions. I
re-formated the test code to be less then 60 chars so that it would not wrap
on the forum posting, hence the rather unusual comment positions. The vector
definitions comments are meant to be on the same lines as the vectors but
you can see that I think.

This was written for the HC12dg128A.

This test rtn takes signal on PP1 and drives the same signal out on PP0
using the PWM. I don't believe you need the include file Const_def.h.

// Robert W. Lewis July 16/03

extern void main(void);

extern void _start(void);
extern void Measure_Period(void);

typedef struct
void (*function)(void);
} rom_irq_vector; // Reserved $FF80-$FFAF

#pragma abs_address 0x0FFEA
//start the vector table in ROM at this address

rom_irq_vector rom_interrupt_vectors[] =
(void (*)(void))0xFFEA,
(void (*)(void))0xFFEE,
(void (*)(void))0xFFF0,
(void (*)(void))0xFFF2,
(void (*)(void))0xFFF4,
(void (*)(void))0xFFF6,
(void (*)(void))0xFFF8,
(void (*)(void))0xFFFA,
(void (*)(void))0xFFFC,

// RTI $FFF0-$FFF1
// IRQ $FFF2-$FFF3
// SWI $FFF6-$FFF7

Timer channel 2 I bit TMSK1 (C2I) $EA
Timer channel 1 I bit TMSK1 (C1I) $EC
Timer channel 0 I bit TMSK1 (C0I) $EE
Real time interrupt I bit RTICTL (RTIE) $F0
XIRQ X bit None $F4
SWI None None $F6
Unimplemented instruction trap None None $F8
COP failure reset None COP rate selected $FA
Clock monitor fail reset None COPCTL (CME FCME) $FC
Reset None $FE

#pragma end_abs_address
#pragma interrupt_handler Measure_Period

#include "Const_def.h"
// address offsets for LCD and other constants //--------*/
void Init (void);
void Set_PWM (void);

#define EDG1R 0x04 //;edge 1 rising value

unsigned int First; // DW $0 ;TC1 value at first edge
unsigned int Second; // DW $0 ;TC1 value at first edge
unsigned int Result; // DW $0
unsigned int result, Result_Saved = 9999,
Result_Saved_Masked, Result_Masked;
unsigned int Duty_Cycle, Period, Pwm_Count;
unsigned char Period_Scale = 4, Duty_Cycle_Scale = 8,
Pwm_Count_Scale = 2;
unsigned char Flag_1 =0, Flag_2 = 0;
void main (void)
COPCTL = 0x00;

INTERRUPT_OFF(); // disable I (internal)
// interrupts

Init(); // initialize port and timer
// for input capture on
// rising edge only

pwm_ENABLE_REG_PWEN |= PWEN0; // enable pulse width module,
// reg 0, 0 & 1 concatenated

INTERRUPT_ON(); // enable I (internal)
// interrupts
while (1) // set the values into the pwm
if (Flag_2 == 1)
Result = Second - First;// saved result for debug as below
Flag_2 = 0; // clear the calc flag

Period = Result/(Period_Scale);
// store Period in one operation,
// center alligned therefore
Duty_Cycle = Result/(Duty_Cycle_Scale);
// duty cycle = 1/2 Period, store duty cycle in one operation (2 bytes)

Pwm_Count = Result/(Pwm_Count_Scale);

Result_Saved_Masked = Result_Saved & 0xFFFC;
Result_Masked = Result & 0xFFFC;

if (Result_Saved_Masked != Result_Masked)
Result_Saved = Result;
// save the current Result for comparision of change

*(unsigned int *)&pwm_PWPER0 = Period;
// store Period in one operation, center alligned therefore

*(unsigned int *)&pwm_PWDTY0 = Duty_Cycle;
// duty cycle = 1/2 Period, store duty cycle in one operation (2 bytes)

// Init Rtns, Devices
//++++++++++++++++++++++++++++++++++++++++++++++++++++++ /*-------------------------Init--------------------------

Function: init IC on port 1
Input: none
Return: none
Notes: IMPORTANT - poll for any rising edge
detected on timer

void Init (void)
unsigned char timer_prescale = 1; // divide by 2, same as pwm


DDRA = 0x01; // set PA0 as output


timer_INTERRUPT_MASK_2_TMSK2 |= timer_prescale;
// set main timer prescale

pwm_PWPOL |= PCLK1;
// clock A is src for channel 0,1
pwm_PWPOL |= PPOL1;
// set output high

pwm_PWCLK |= CON01;
// concatenate pwm0&1

// center aligned pulse
pwm_PWSCAL0 |= pwm_SCALE;

// pull up port P

//-------------------------PTn--Input Capture-----------------------

TSCR |= TEN; // enable timer
TIOS &= ~C1F; // enable input capture on timer 1
TCTL4 |= EDG1R; // initialize for rising edge
TFLG1 = C1F; // reset input capture 1 flag

} //end-fcn
((((((((((((((( Measure_Period )))))))
void Measure_Period (void)
if (Flag_1 == 0)
First = TC1; //get timer 1 count and save as FIRST
TFLG1 = C1F; //reset the input capture 1 flag
Flag_1 = 1;
Second = TC1;
TFLG1 = C1F;//reset the input capture 1 flag
Flag_1 = 0;
Flag_2 = 1; // flag set to indicate calc should happen

} //end-fcn Message: 13
Date: Thu, 25 Sep 2003 01:47:17 -0000
From: "juju1414" <>
Subject: interrupts and sonar

I have been trying to get my sonars(srf04's) to work for some
time now, with no luck. The problem is the interrupts. I have
gotten the interrupts to trigger when they recieve the echo, but
they seem to give out random values for the time that the interrupt
occured. Here is some of the code: