Generating Square Waves
Mark Crosbie has a web page dealing with Linux PIC programming, along with some example projects. One of these is a test program which purports to generate a 100KHz square wave on a 4MHz PIC. In fact anyone trying this out will find it lumbers along at a mere 15.157 KHz. Looking at the code, it's not too hard to see why. A 4MHz PIC runs a 1 million instruction cycles per second, to generate 100 KHz, you need to toggle the state of a port twice in 10 microseconds. The delays in this code are far too long.
Replacing the main loop with this:
Loop comf PORTA nop nop goto LoopProduces a 100KHz square wave. If you're desperate, you can do it with one less instruction:
Loop comf PORTA goto $+1 goto LoopBy removing the delay thus:
Loop comf PORTA goto LoopWe can produce a square wave of 166.66 KHz, the fastest we can sustainably go with a 4MHz clock. It is possible to toggle a port at 500KHz, but only for a short period, as the two-cycle penalty of the jump instruction will mess things up.
This C code produces a 10-cycle burst at 500KHz followed by a 1 millisecond delay:
asm __config _CP_OFF & _XT_OSC & _PWRTE_ON & _WDT_OFF
main()
{
set_bit( STATUS, RP0 );
set_tris_a( 0 );
clear_bit( STATUS, RP0 );
output_port_a( 0 );
while( 1 ) // Forever
{
delay_ms(1);
asm comf PORTA
asm comf PORTA
asm comf PORTA
asm comf PORTA
asm comf PORTA
asm comf PORTA
asm comf PORTA
asm comf PORTA
asm comf PORTA
asm comf PORTA
asm comf PORTA
asm comf PORTA
asm comf PORTA
asm comf PORTA
asm comf PORTA
asm comf PORTA
asm comf PORTA
asm comf PORTA
asm comf PORTA
asm comf PORTA
delay_ms(1);
}
}
This code needs to be linked with delay.lib
Want to generate a sustained 500KHz? The simplest way is to use the 166 KHz code i.e.
Loop comf PORTA goto LoopInstead of using a 4MHz crystal to clock the PIC, drop in a 12MHz, this will generate a 500KHz square wave [yes, even on a '4 MHz' PIC]. I have run '4 MHz' PICs with clocks as high as 16MHz.