I am debugging a modified PIC18F design where the CPU was changed from a 28 pin device to PIC18F4320, which is a 44 pin device.
The new board works seemingly OK, but I have found a problem in time delays between activation and deactivation of the relay drive pins, which cause switch-off transients to be generated. So now I am hunting for these delays (72 us to be exact) and for this I need to know the clock frequency of the PIC...
I have not worked with a PIC18 design before, just used PIC24 devices, so I am not up to speed in this regard.
The MPLAB C18 compiler is being used.
In this case there is no crystal so it uses the built-in PIC oscillator.
What I have found is the following settings which use the Internal Oscillator Block:
- Code: Select all
#pragma config OSC = INTIO2 //Internal RC oscillator, port function on RA6 and RA7
//In the inithw() function:
OSCCON = 0x4C; // Internal Oscillator Block @ 1Mhz. & set PRI_IDLE
It seems like this implies a 1 MHz oscillator is in use, but does this give 1 us or 2 us instruction cycle time?
I am seeing a delay of 72 us between the tristating of one end of the relay coil and the tristating of the other end.
But the code sequence is pretty simple and should execute faster, I believe:
- Code: Select all
void ControlRelay_PortC(unsigned char bitmask, unsigned char drive_dir)
/*Arguments: bitmask: relay bits in port
drive_dir: drive direction SET or CLEAR
*/
{
LATC = 0;
if (drive_dir == HIGH) LATC = bitmask;
TRISC = ~bitmask; // activate relay drive output
PulseRelayCommon(drive_dir); // pulse relay drive common output
TRISC = 0xFF; // de-activate relay drive output
LATC = 0;
}
void PulseRelayCommon(unsigned char relay_dir)
{
ActivateRelayCommon(relay_dir, TRUE); // activate relay common drive
Delay_ms(RELAY_HOLD_TIME); // delay for roughly 5ms
ActivateRelayCommon(relay_dir, FALSE); // de-activate relay common drive
}
void ActivateRelayCommon(unsigned char level, unsigned char state)
{
TRISE = 0xFF; //Make sure the port is in the OFF state
if (state == FALSE) return;
if (level == HIGH)
LATE = RECMN_SET;
else
LATE = RECMN_CLR;
TRISE = RECMN_IO_DIR;
}
The function ControlRelay_PortC() is called from main() to pulse a relay coil in one or the other direction.
It just sets the level for the relay drive pins, then calls the PulseRelayCommon() function to generate the drive pulse on the common line.
When this exits back the drive pins are tri-stated immediately (in the code) and still I see a 72 us delay between the two tri-state operations.
Why is this so?
Is the PIC18 so slow that it explains the delays or is the C18 compiler inserting wait states where there should be just a simple sequence of operations??