/******* EEtest.c ************** * * Test Alex's example. * Show EEwrites by awake times on scope (using Delay(100)). * ******* Program hierarchy ***** * * main * Initial * ******************************* */ #include // Define PIC18LF4321 registers and bits /******************************* * Configuration selections ******************************* */ #pragma config OSC = INTIO1 // Use internal osc, RA6=Fosc/4, RA7=I/O #pragma config PWRT = ON // Enable power-up delay #pragma config LVP = OFF // Disable low-voltage programming #pragma config WDT = OFF // Disable watchdog timer initially #pragma config WDTPS = 4 // 16 millisecond WDT timeout period, nominal #pragma config MCLRE = ON // Enable master clear pin #pragma config PBADEN = DIG // PORTB<4:0> = digital #pragma config CCP2MX = RB3 // Connect CCP2 internally to RB3 pin #pragma config BOR = SOFT // Brown-out reset controlled by software #pragma config BORV = 3 // Brown-out voltage set for 2.1V, nominal #pragma config LPT1OSC = OFF // Deselect Timer1's low-power oscillator /******************************* * Global variables ******************************* */ char GIEHCOPY; // Copy of GIEH bit for EEPROM writes char SBORENCOPY; // Copy of SBOREN bit for EEPROM writes char* RAMPTR; // Pointer to RAM array to be copied to EEPROM char TEMPARRAY[] = {'a','b','c','d'}; // Characters to copy unsigned char EEADDRESS; // Starting address in EEPROM unsigned char EECNT; // Number of bytes to copy unsigned int DELAY; // Sixteen-bit counter for obtaining a delay /******************************* * Function prototypes ******************************* */ void Initial(void); void EEread(void); void EEwrite(void); void EEArrayWrite(void); /******************************* * Macros ******************************* */ #define Delay(x) DELAY = x; while(--DELAY){ Nop(); Nop(); } /////// Main program ////////////////////////////////////////////////////////// /******************************* * main ******************************* */ void main() { Initial(); // Initialize everything EEADR = 0x10; EEDATA = 0xAA; EEwrite(); // Do the first write // Write 1 while (1) { EECON1bits.WREN = 0; // Disable further EEPROM writes EEArrayWrite(); // Deal with EEPROM writes, as called upon // Writes 2 and 3 Sleep(); // Sleep through writes to EEPROM // Check this Nop(); } } /******************************* * Initial * * This function performs all initializations of variables and registers. ******************************* */ void Initial() { OSCCON = 0b01100010; // Use Fosc = 4 MHz (Fcpu = 1 MHz) SSPSTAT = 0b00000000; // Set up SPI for output to LCD SSPCON1 = 0b00110000; ADCON1 = 0b00001011; // RA0,RA1,RA2,RA3 pins analog; others digital TRISA = 0b00001111; // Set I/O for PORTA TRISB = 0b01000100; // Set I/O for PORTB TRISC = 0b10000000; // Set I/O for PORTC TRISD = 0b10000000; // Set I/O for PORTD TRISE = 0b00000010; // Set I/O for PORTE PORTA = 0; // Set initial state for all outputs low PORTB = 0; PORTC = 0; PORTD = 0b00100000; // except RD5 that drives LCD interrupt PORTE = 0; Delay(50000); // Pause for half a second RCONbits.SBOREN = 0; // Now disable brown-out reset WDTCONbits.SWDTEN = 1; // Enable watchdog timer EECON1 = 0; // Initialize module state RAMPTR = TEMPARRAY + 1; // Experiment with EEPROM EEADDRESS = 0x20; EECNT = 2; // Set up for writes 2 and 3 } /**************************** * EEArrayWrite * * Each time this function is called with EECNT != 0, it writes one byte * from the RAM char[] pointed by RAMPTR, into the EEPROM location whose * address is in EEADDRESS. Then it increments RAMPTR and EEADDRESS and * decrements EECNT. RAMPTR, EEADDRESS and EECNT should not be modified * by other code until EECNT is 0. * Variable declaration: * char* RAMPTR; unsigned char EEADDRESS; unsigned char EECNT; * Example usage: * char TEMPARRAY[] = {'a','b','c','d'}; * RAMPTR = TEMPARRAY + 1; * EEADDRESS = 0x20; * EECNT = 2; * After 2 calls of EEArrayWrite, EECNT = 0; * and EEPROM has 'b' and 'c' in address 0x20 and 0x21 respectively. **************************** */ void EEArrayWrite() { if(EECNT && !EECON1bits.WR) // Skip to next loop time for second write { EEDATA = *(RAMPTR++); EEADR = EEADDRESS++; EEwrite(); EECNT--; } } /**************************** * EEread * * This function reads from the EEPROM address identified by EEADR * into EEDATA. **************************** */ void EEread() { while (EECON1bits.WR); // Wait on the completion of any write EECON1bits.RD = 1; // Set the RD bit to read from EEADR into EEDATA } /**************************** * EEwrite * * This function writes the data contained in EEDATA into the EEPROM * address identified by EEADR. * The write is self-timed and takes about 4 milliseconds. **************************** */ void EEwrite() { while (EECON1bits.WR); // Wait on the completion of any write SBORENCOPY = RCONbits.SBOREN; // Copy SBOREN for subsequent restore RCONbits.SBOREN = 1; // Enable brown-out reset GIEHCOPY = INTCONbits.GIEH; // Copy GIEH for subsequent restore INTCONbits.GIEH = 0; // Disable all interrupts EECON1bits.WREN = 1; // Enable write operation EECON2 = 0x55; // Write first key EECON2 = 0xAA; // Write second key EECON1bits.WR = 1; // Set WR bit to initiate write INTCONbits.GIEH = GIEHCOPY; // Restore global interrupt state RCONbits.SBOREN = SBORENCOPY; // Restore brown-out reset state PORTCbits.RC2 ^= 1; // Toggle pin to flag where write occurs Delay(100); // Add a delay to show sleep after 1 ms of writing }