Linear Feedback Shift register pic16F684 code


// PIC16F684 Configuration Bit Settings

// 'C' source line config statements

// CONFIG
#pragma config FOSC = INTOSCIO  // Oscillator Selection bits (INTOSCIO oscillator: I/O function on RA4/OSC2/CLKOUT pin,
I/O function on RA5/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = ON      // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = OFF      // MCLR Pin Function Select bit (MCLR pin function is digital input, MCLR internally
tied to VDD)
#pragma config CP = OFF         // Code Protection bit (Program memory code protection is disabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)
#pragma config BOREN = OFF      // Brown Out Detect (BOR disabled)
#pragma config IESO = OFF       // Internal External Switchover bit (Internal External Switchover mode is disabled)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is disabled)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#include <xc.h>
#include <pic16f684.h>

#define _XTAL_FREQ 4000000  // default  can be set by OSCCON

unsigned int result;

void __interrupt() ADC_ISR(void){
    if (PIR1bits.ADIF == 1) {
        result = ADRESH; // 0-255
        PIR1bits.ADIF = 0;
        __delay_us(25);                  //Time to wait for the next conversion 
        ADCON0bits.GO_nDONE = 1;
    } else if (INTCONbits.RAIF == 1) {
        if (RA2 == 0) {
            RC2 = 1;
        } else if (RA2 == 1) {
            RC2 = 0;
        }
        INTCONbits.RAIF = 0;
    }
}

void delay(unsigned int msec) {
    for (int i =0; i < msec; i++) {
          __delay_us(500);
        }
}


void main(void) {

    TRISA = 0b00111101; //RA4 (manual input) and RA5 (auto) RA0 (ADC) RA2 (data))
    PORTA = 0b00110100;  // all PORTA pins are low except RA5 RA4 RA2
    TRISC = 0b00000000; // all PORTC output
    PORTC = 0x00; // all PORTC pins are low

    OSCCON = 0b01100111;  // 4 Mhz
    ANSEL =  0b00000001;  // analog select bits  AN0 == RA0 (pin 13 of the IC)
    ADCON0 = 0b00000001;  //  1/0 =right/left justified, 0=Vdd, 0=not impl, 000=AN0, 0=G0_nDone, 1=ADC on


    PIR1bits.ADIF = 0;  // 0 = A/D conversion has not completed or has not been started
    PIE1bits.ADIE = 1;  //   Enables the ADC interrupt
    INTCONbits.GIE = 1;  // 1 = Enables all unmasked interrupts
    INTCONbits.PEIE = 1;  // 1 = Enables all unmasked peripheral interrupts
    ADCON1bits.ADCS = 0b001;  // FOSc/8
    CMCON0 =  0b00000111;  //comparators CM2:CM0 off. CxIN pins are configured as digital I/O
    VRCON = 0x00;   // Shut off the Voltage Reference
    __delay_us(40); // Time to charge the cap
    ADCON0bits.GO_nDONE = 1;

    // interrupt-on-change
    IOCAbits.IOCA2 = 1;  // RA2
    INTCONbits.RAIE = 1; // enables IOC PORTA
    INTCONbits.RAIF = 0; // no interrupt yet

    WPUA = 0b00110100;  // RA5 & RA4 & RA2
    nRAPU = 0;  // enable weak pull-up per individual port

    unsigned char _auto = 0;  // manual or auto
    unsigned char once = 1;

    while(1) {
        if (RA5 == 1) {
            _auto = 1;
        } else {
            _auto = 0;
        }
        // auto frequency by pot meter
        if (_auto == 1) {
          RC0 = 1;
          __delay_us(2);  // was 10us
          RC1 = 1;
          delay(result);
          RC0 = 0;
          __delay_us(2); // was 10us
          RC1 = 0;
          delay(result);
        } else {  // manual frequency
            if ((RA4 == 0) && (once == 1)) {
               once = 0;
               RC0 = 1;
               __delay_us(10);
               RC1 = 1;
               __delay_ms(10); // was 100
               RC0 = 0;
               RC1 = 0;
            } else if (RA4 == 1) {
                once = 1;
                __delay_ms(25);
            }
        } // manual

    } // while
}  // main