/***************************************************************************** * Filename: main.c * * Author: LRF *****************************************************************************/ /* The following is a controller for a precision pendulum clock. It also demonstrats the use of interrupts, PWN and the AtoD converter. And for addition is shows how to use the sleep mode it which an interrupt wakes it. The circuit uses 3 potentiometers to input to 3 channels of the A to D and act as analog inputs controlling the PWM duty, duration and freq of operation. */ #include "CS110000.h" BIT Direction = 0; //0 = falling edge, right hand swing, pulse drive solenoid //1 = rising edge, left hand swing, check variable control settings float A2D_Duty = 512; float A2D_Freq = 1; float A2D_Dura = 40; int A2DBitsDuty; int A2DBitsFreq; int A2DBitsDura; BYTE Pulse_Count = 0; void main(void) { INTSET(0x40, 0x00, 0x40);//Enable interrupt on falling edge //Set up int1, falling, priority STPIND(44,LOW); //indicates slave solenoid is on STPIND(45,LOW); //indicates drive solenoid is on STPIND(2,LOW); while(1){ _asm //Put processor a sleep until an int occurs SLEEP _endasm Pulse_Count = Pulse_Count + 1; //Keep track of oscillations for timing purposes if(Direction==0) { //Swing to the left A2D_Duty = ANALOGIN(19,3,0,0,0); A2D_Freq = ANALOGIN(18,3,0,0,0); A2D_Dura = ANALOGIN(17,3,0,0,0); A2DBitsDuty =(A2D_Duty / 5)* 1024; A2DBitsFreq =((A2D_Freq / 5)* 1024)/85; //sets A2DBitsFreq from 0 to 11 A2DBitsDura =(((A2D_Dura / 5)* 1024)/10)+ 1; //sets the duration of the PWM output 1 to 103 mSeconds PAUSE(A2DBitsDura); } else{ //Swing to the right if(Pulse_Count > A2DBitsFreq) { Pulse_Count = 0; PWM(3,A2DBitsDuty,255); //Main drive solenoid TOGGLE(45); PAUSE(A2DBitsDura); PWM(3,0,255); TOGGLE(45); } } TOGGLE(2); //This is the Slave solenoid TOGGLE(44); PAUSE(40); TOGGLE(2); TOGGLE(44); } // End of while } // End of main //Interrupt routine /***************************************************************************** * FileName: zInterruptsH.c * Author LRF *****************************************************************************/ /* The following is an interrupt routine which returns a single bit either on or off which tells the main.c how to respond. Of interest is that on alternate interrupts I trigger on a falling edge then switch to a rising edge and then back again over and over */ #include "CS110000.h" extern BIT Direction; #pragma code #pragma interrupt InterruptHandlerHigh void InterruptHandlerHigh(void) { INTSOURCE(); if(Direction == 1){ INTSET(0x40, 0x00, 0x40);//Enable interrupt on falling edge Direction = 0; } else{ INTSET(0x40, 0x40, 0x40);//Enable interrupt on rising edge Direction = 1; } }