Wednesday, 19 June 2013


This is a variable frequency dual square wave generator. It simply uses a PIC to create 2 square waves 180 out of phase on ports B0 and B1. By turning the POT to vary the voltage into port A0, the analogue-to-digital converter creates an integer from the voltage, the frequency of the outputs is increased by turning the POT as shown in the above video. I don't have an oscilloscope so can't give an accurate frequency output, but I think it ranges from about 5Hz to 1000Hz.

The reason for this is to get the ringer as loud as possible, I  initially tested it with square waves at about 22Hz fed into the H-bridge, but I don't think this is quick enough, so have included the ability to 'tune' the circuit with the frequency of the input voltage.

The code on the PIC 16F88:

#include <16F88.h>
#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES INTRC_IO                 //Internal RC Osc, no CLKOUT
#FUSES NOPUT                    //No Power Up Timer
#FUSES MCLR                     //Master Clear pin enabled
#FUSES BROWNOUT                 //Reset when brownout detected
#FUSES LVP                      //Low Voltage Programming on B3(PIC16) or B5(PIC18)
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOPROTECT                //Code not protected from reading
#FUSES FCMEN                    //Fail-safe clock monitor enabled
#FUSES IESO                     //Internal External Switch Over mode enabled

#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_A3,rcv=PIN_A2,bits=8)


void main()
{
   int16 adc_value;
   setup_adc_ports(sAN0|VSS_VDD);
   setup_adc(ADC_CLOCK_DIV_8);
   setup_spi(FALSE);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   setup_oscillator(False);

  while(TRUE) {
     read_adc(ADC_START_ONLY);
     adc_value = read_adc(ADC_READ_ONLY);

     output_high(PIN_B0);
     output_low(PIN_B1);
     delay_us(adc_value);
     output_low(PIN_B0);
     output_high(PIN_B1);
     delay_us(adc_value);
  }

}

No comments:

Post a Comment