gr8flyer55
Posts: 800
Score: 600 Joined: 11/30/2005 Last Login: 5/22/2013 From: Hamburg,
PA, USA Status: offline
|
Here's the file listing. copy and paste into your compiler or whatever you have that is working out of this mess of crap. John *********************************************************************** * Filename: 12f683_v0.9b3.c * * Version: 0.9 beta 3 * * Date: 8/29/12 * * Author: Jake Stewart (jakestew@mail.com) * * Credits: Nyemi, John, jpanhalt * * Copyright: 2012 Jake Stewart * ************************************************************************* * License: This code is free for personal and limited commercial use. * * You may use and modify it as you see fit as long as you do not sell * * the code or any derivative work or any product containing the above * * without written permission. Contact me for affordable licensing. * ************************************************************************* * Processor: PIC12F683 * * Compiler: MPLAB XC8 * * Extra files: Standard libraries only * ************************************************************************* * Description: CDI ignition control program * * * * Timer1 is used to time the ignition delay (in uS) * * Time base is internal RC oscillator. * ************************************************************************* * Pin assignments: * * Pin 7 (GP0) = Output for LED/tachometer, active high * * Pin 6 (GP1) = Output to HV spark circuit, active high * * Pin 5 (GP2) = Sensor input, interrupt on falling edge (low) * * Pin 4 (GP3) = Tied low * * Pin 3 (GP4) = Unused * * Pin 2 (GP5) = Unused * ************************************************************************* * Interrupts: * * GP2 - Triggered by sensor input falling edge * * TMR1 - Timer1, every 65.5 ms (if not cleared) * * CCP1IF - Timer1 = CCPR1 (Timer1 period register) * * * ************************************************************************/ #include #include #include // Auto include device specific headers and libraries. #include // Defines C99 standard data types like uint8_t and uint16_t #include // For true/false definition #define _XTAL_FREQ 8000000 // Oscillator/crystal Speed = 4mhz #define ICLK (_XTAL_FREQ/4) // Instruction clock = XTAL divided by four Device Config Register: CONFIG1 (see pic12f683.h) * IO on OSC pins, Watchdog Off, PowerUp Timer On, IO on MCLR, Code Protect Off, Data Protect Off, * Brown-out Reset Off,Clock Switch Off,Fail-Safe Clock Monitor Off */ __CONFIG(FOSC_INTOSCIO & WDTE_OFF & PWRTE_ON & MCLRE_OFF & CP_OFF & CPD_OFF & BOREN_OFF & IESO_OFF & FCMEN_OFF); *********************************************************************** * User Settings: * ************************************************************************/ #define SensorDigiDeg 42 // Sensor Digi-Degrees BTDC #define LowRPMAdvance 42 // Low RPM Advance Degrees (3 RPS - 916 RPM) #define StartDelay 16406 // Delay to fire spark when starting #define Dwell_Time 500 // Dwell time, in uS, that output is kept on #define MSD_Spark 3 // Total number of sparks per revolution when RPM is below Max_MSD_Rev (at least 1) #define MSD_Low_Spark 4 // Total number of sparks to fire when in LowRPM mode (below 915 RPM) #define MSD_Start_Spark 5 // Total number of sparks to fire on the first start spark #define MSD_dDeg 5 // DigiDegrees between multisparks (1 = 1.4 deg)(dwell time not accounted for) #define Max_MSD_Rev 79 // Maximum RPM (in terms of CurrentRev + 1) to use MSD (78 = 3,005) **** Ignition Advance Table (257 point, 16-bit table) *****/ const uint16_t DegDelay[257] = { **** PASTE TABLE DATA ON THE LINE BELOW *****/ 7112,2,44,86,128,170,212,254,296,338,380,422,464,506,548,379,407,435,463,491,519,547,575,603,631,658,686,714,742,770,798,826,854,882,910,938,966,994,1022,1050,1078,1105,1133,1161,1189,1217,1245,1273,1301,1329,1357,1385,1413,1441,1469,1497,1525,1552,1580,1608,1636,1664,1692,1720,1748,1776,1804,1832,1860,1888,1916,1944,1972,1999,2027,2055,2083,2111,2139,2167,2195,2223,2251,2279,2307,2335,2363,2391,2419,2446,2474,2502,2530,2558,2586,2614,2642,2670,2698,2726,2754,2782,2810,2838,2866,2893,2921,2949,2977,3005,3033,3061,3089,3117,3145,3173,3201,3229,3257,3285,3313,3340,3368,3396,3424,3452,3480,3508,3536,3564,3592,3620,3648,3676,3704,3732,3760,3787,3815,3843,3871,3899,3927,3955,3983,4011,4039,4067,4095,4123,4151,4179,4207,4234,4262,4290,4318,4346,4374,4402,4430,4458,4486,4514,4542,4570,4598,4626,4654,4681,4709,4737,4765,4793,4821,4849,4877,4905,4933,4961,4989,5017,5045,5073,5101,5128,5156,5184,5212,5240,5268,5296,5324,5352,5380,5408,5436,5464,5492,5520,5548,5575,5603,5631,5659,5687,5715,5743,5771,5799,5827,5855,5883,5911,5939,5967,5995,6022,6050,6078,6106,6134,6162,6190,6218,6246,6274,6302,6330,6358,6386,6414,6442,6469,6497,6525,6553,6581,6609,6637,6665,6693,6721,6749,6777,6805,6833,6861,6889,6916,6944,6972,7000,7028,7056,7084 }; **** PASTE TABLE DATA ON THE LINE ABOVE *****/ **** FUNCTION PROTOTYPES *****/ static void init(void); // Function prototype (declaration) **** GLOBAL VARIABLES *****/ union {uint8_t ALL;struct{unsigned GP0:1;unsigned GP1:1;unsigned GP2:1; unsigned GP3:1;unsigned GP4:1;unsigned GP5:1;};} sGPIO; // Shadow copy of GPIO volatile uint8_t CurrentRev = 0; // Timer for current revolution volatile uint8_t LastRev = 0; // Previous revolution time volatile uint8_t TMR1_Overflow = 0; // Timer1 counter volatile uint8_t Engine_Running = 0; // Engine running? volatile uint24_t LowCalc = 0; volatile uint8_t Unhandled_Interrupt = 0; volatile uint8_t Spark_Fire = MSD_Start_Spark; uint8_t i = 0; // Counter variable 1 uint8_t j = 0; // Counter variable 2 void main(void) { init(); PIE1bits.TMR1IE = 1; // Timer1 interrupt enable T1CONbits.TMR1ON = 1; // Start Timer1 INTCONbits.GIE = 1; // Enable interrupts while(1){ // Main loop, Run this loop forever } } static void interrupt isr(void){ All in one IF block to avoid runtime errors */ #if 1 Determine which flag generated the interrupt and service it */ if(PIR1bits.CCP1IF){ **** TIMER1 COMPARE MATCH *****/ for(;Spark_Fire > 0;Spark_Fire){ sGPIO.GP1 = 0; // Turn on HV output by turning GP1 off sGPIO.GP0 = 1; // Turn on LED/tach (GP0) bit in shadow GPIO = sGPIO.ALL; // Update GPIO __delay_us(Dwell_Time); // Load dwell time (uS) sGPIO.GP1 = 1; // GP1 is normally on (on = off) sGPIO.GP0 = 0; // Turn on LED/tach (GP0) bit in shadow GPIO = sGPIO.ALL; // Update GPIO for(i=MSD_dDeg;i>0;i){ // Loop for each DigiDegree __delay_us(10); for(j=CurrentRev>>2;j>0;j){NOP();} // Loop for 1 DigiDegree } } CCP1CONbits.CCP1M = 0; // Compare mode off, so we don't end up here again until the next spark PIR1bits.CCP1IF = 0; // Clear interrupt flag } else if(INTCONbits.INTF){ **** GP2 SENSOR INPUT *****/ LastRev = CurrentRev; // Store previous value T1CONbits.TMR1ON = 0; // Turn off Timer1 CurrentRev = TMR1H + (TMR1L >> 7); // 8 high bits of Timer1 + the highest low bit (rounding method) TMR1 = 0; // Reset Timer1 CCP1CONbits.CCP1M = 0b1010; // Set Timer1 CCP compare mode T1CONbits.TMR1ON = 1; // Turn on Timer1 CCPR1 = DegDelay[CurrentRev]; // Load delay table value if(CurrentRev > Max_MSD_Rev){Spark_Fire = MSD_Spark;} // Set the MSD sparks if revs are low enough else{Spark_Fire = 1;} if(TMR1_Overflow){ // If we overflowed we need to calc the delay time since it's not in the table LowCalc = CurrentRev + (TMR1_Overflow<<8); // Figure out total elapsed time CCPR1 = LowCalc * LowRPMAdvance; // Shift one more bit and multiply times our start advance setting TMR1_Overflow = 0; // Reset TMR1 overflow counter Spark_Fire = MSD_Low_Spark; CurrentRev = 255; // CurrentRev should be maxed instead of rolled over to a random number if(!Engine_Running){ // If our engine isn't running we won't have a valid rev time CCPR1 = StartDelay; // Use default starting figure Spark_Fire = MSD_Start_Spark; Engine_Running = 1; // Hopefully engine fired or at least hits the sensor again at above 3 RPS } } PIR1bits.CCP1IF = 0; // Clear compare interrupt flag PIE1bits.CCP1IE = 1; // Enable compare interrupt INTCONbits.INTF = 0; // Clear GP2 Interrupt Flag } else if(PIR1bits.TMR1IF){ **** TIMER1 OVERFLOW *****/ CCP1CONbits.CCP1M = 0; // Compare mode off if(TMR1_Overflow > 7){ Engine_Running = 0; // Engine is not running (under ~2 RPS / ~120 RPM) } else{ TMR1_Overflow++; // Increment overflow count (=uS*65536) } PIR1bits.TMR1IF = 0; // Clear interrupt flag } else { **** UNHANDLED INTERRUPT *****/ if(Unhandled_Interrupt < 255){Unhandled_Interrupt++;} } #endif } static void init(void) { OSCCONbits.IRCF = 0b111; // Internal osc = 8MHz OSCCONbits.SCS = 1; // Use Internal osc if(OSCCONbits.HTS == 0){__delay_ms(1);} // Wait for HF internal osc to become stable if(OSCCONbits.LTS == 0){__delay_ms(1);} // Wait for LF internal osc to become stable INTCON = 0b01010000; // Disable interrupts, except GP2, -TMR0, peripheral PIE1 = 0b00100001; // Peripheral Interrupt Enable. CCP1, TMR1 on. PIR1 = 0b000000; // Peripheral Interrupt Request Register ANSEL = 0b00000000; // Turn off all analog inputs WPU = 0b000000; // Make sure all internal pull-ups are off ****** GP 543210 *******/ ****** Pin 234567 *******/ TRISIO = 0b111100; // 0/1=Output/Input, Pin 234567, Label (GP543210) sGPIO.ALL = 0b000000; // Set initial pin states (all off) (Shadow write) sGPIO.GP1 = 1; // GP1 should normally be on (on = off) GPIO = sGPIO.ALL; // Shadow GPIO -> GPIO OPTION_REG = 0b10000000; // pullups off, falling edge, Tmr0 CMCON0 = 0b00000111; // comparator config, disable CCP1CON = 0b00000000; // CCP off, special event mode = 1011 (resets Timer1) T1CON = 0b00010100; // TMR1 Off, 1:2 prescaler TMR1 = 0; // Zero Timer1 }
Hide Signatures
|