igendel icon

Continuity Tester Code

igendel | PRO | 10/28/21 02:47:10 PM UTC (Edited) | 0 ⭐ | 2019 👁️ | Never ⏰ | []
C |

4.36 KB

|

None

|

0 👍

/

0 👎

// MPLAB X IDE v5.5, XC8 v2.32
// PIC12F1572 Configuration Bit Settings
// CONFIG1
#pragma config FOSC = INTOSC    //  (INTOSC oscillator; I/O function on CLKIN pin)
#pragma config WDTE = OFF       // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable (PWRT disabled)
#pragma config MCLRE = ON       // MCLR Pin Function Select (ON = MCLR/VPP pin function is MCLR, OFF = d.input)
#pragma config CP = OFF         // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config BOREN = OFF      // Brown-out Reset Enable
#pragma config CLKOUTEN = OFF   // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
// CONFIG2
#pragma config WRT = OFF        // Flash Memory Self-Write Protection (Write protection off)
#pragma config PLLEN = OFF      // PLL Enable (4x PLL disabled)
#pragma config STVREN = ON      // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset)
#pragma config BORV = LO        // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LPBOREN = OFF    // Low Power Brown-out Reset enable bit (LPBOR is disabled)
#pragma config LVP = ON         // Low-Voltage Programming Enable (Low-voltage programming enabled)
 
#define _XTAL_FREQ 500000U
 
#include <stdint.h>
#include <xc.h>
 
 
//=========================================================
void setup(void) {
    
    // RA4 is LED output
    LATAbits.LATA4 = 0; // Important, it's undefined!
    ANSELAbits.ANSA4 = 0;
    TRISAbits.TRISA4 = 0;
 
    // RA5 is PWM1 output (Alternate pin function)
    LATAbits.LATA5 = 0; // Important, it's undefined!
    TRISAbits.TRISA5 = 0;
    APFCONbits.P1SEL = 1;
  
    // RA2 will be used for INT while sleeping, and as ADC input for measurement
    TRISAbits.TRISA2 = 1;
    
    // PWM
    // Clock source is Fosc by default
    // PWM Toggle On Match mode
    PWM1CONbits.MODE = 2; 
    // period = 2 * ((PWM1PR + 1) * prescale / PWM1CLK), we need ~4KHz
    PWM1PR = 61U;
    PWM1PH = 1U;
    // Set PWM "active" output to LOW
    PWM1CONbits.POL = 1;
    
    // Disable internal LDO during sleep to save power
    VREGCONbits.VREGPM = 1;
    
    // ADC channel 2 (from RA2)
    ADCON0bits.CHS = 2;
    // Right-align ADRES (ADC result register)
    ADCON1bits.ADFM = 1; 
    // Set ADC conversion clock to FRC
    ADCON1bits.ADCS = 7;
}
 
//=========================================================
void prepareForTesting(void) {
 
    // Disable INT
    INTCONbits.INTE = 0;    
    
    // RA2 Needs to be analog input for the ADC to work
    ANSELAbits.ANSA2 = 1;    
    
    // Turn on ADC module
    ADCON0bits.ADON = 1;
    
}
 
//=========================================================
void prepareForSleep(void) {
 
    // Turn off ADC module
    ADCON0bits.ADON = 0;
    
    // RA2 Needs to be digital input for the interrupt to work
    ANSELAbits.ANSA2 = 0;
 
    // Clear flag just in case, and enable INT
    INTCONbits.INTF = 0;    
    INTCONbits.INTE = 1;    
    
    // GIE not required for sleep wake-up
    
}
 
//=========================================================
uint8_t continuityDetected(void) {
 
    // Start ADC conversion
    ADCON0bits.GO_nDONE = 1;
    while (1 == ADCON0bits.GO_nDONE) {
    }
    
    // Adjusted for <= 100 Ohm, with 10K to GND
    return (ADRES > 1013) ? 1 : 0; 
}
 
//=========================================================
void giveFeedback(void) {
    
    uint8_t rounds = 4; // An even number!
    uint8_t state = 1;
    
    // Enable PWM module, PWM1 output
    PWM1CONbits.EN = 1;
    PWM1CONbits.OE = 1;
    
    // LED blink
    while (rounds--) {
        
        LATAbits.LATA4 = state;
        state = 1 - state;
        __delay_ms(80);
        
    }
    
    // Disable PWM1 output and PWM module
    PWM1CONbits.OE = 0;    
    PWM1CONbits.EN = 0;
    
}
//=========================================================
void main(void) {
   
    setup();
    
    for ( ; ; ) {
        
        prepareForSleep();
        SLEEP();
 
        // Something got enough voltage to RA2 and woke us up
        
        prepareForTesting();
        while (continuityDetected()) {
            giveFeedback();
        }
        
    }
    
}
 
 

Comments