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