/***************************************************************************************/ /* Analog.c Example of PIC16F8xx Analog to Digital Converter */ /* */ /* By: J.Winpenny */ /*-------------------------------------------------------------------------------------*/ /* Date: | Revision History */ /*-------------------------------------------------------------------------------------*/ /* 07/02/2000 | Initial coding. */ /* | */ /* | */ /* | */ /* | */ /* | */ /* | */ /* | */ /*-------------------------------------------------------------------------------------*/ /* */ /* Simple Test of A/D single channel Input. */ /* Reads the A/D converter and displays the result. */ /* */ /* */ /* */ /* */ /* */ /***************************************************************************************/ #include // Definitions of lcd.c #pragma CLOCK_FREQ 3579545 // Processor clock frequency in Hz. // Default value for PIC is 4000000 (4MHz) // and for SX 50000000 (50MHz). // PORT Configuration #define PortAConfig 0x00 #define PortBConfig 0xf0 #define PortCConfig 0x98 /* SCL & SDA as Inputs */ #define PortDConfig 0x00 #define PortEConfig 0x00 // USART Register bits #define CSCR 7 #define TX9 6 #define TXEN 5 #define SYNC 4 #define BRGH 2 #define TRMT 1 #define TX9D 0 #define SPEN 7 #define RX9 6 #define SREN 5 #define CREN 4 #define ADDEN 3 #define FERR 2 #define OERR 1 #define RX9D 0 #define TRMT_MASK 2 // Masks for PIR1 #define PSPIF_MASK 0x80 #define ADIF_MASK 0x40 #define RCIF_MASK 0x20 #define TXIF_MASK 0x10 // Registers for I2C char SSPSTAT@0x94; // Bank 1 char SSPCON@0x14; // Bank 0 char SSPCON2@0x91; // Bank 1 char SSPBUF@0x13; // I2C Buffer char SSPADD@0x93; // I2C Slave Address register // Bits of SSPSTAT #define SMP 7 #define CKE 6 #define D_A 5 #define P 4 #define S 3 #define R_W 2 #define R_W_MASK 0x04 #define UA 1 #define BF 0 // Bits of SSPCON2 #define GCEN 7 #define ACKSTAT 6 #define ACKDT 5 #define ACKEN 4 #define RCEN 3 #define PEN 2 #define RSEN 1 #define SEN 0 // Bits of PIR1 #define PSPIF 7 #define ADIF 6 #define RCIF 5 #define TXIF 4 #define SSPIF 3 #define SSPIF_MASK 0x08 #define CCP1IF 2 #define TMR2IF 1 #define TMR1IF 0 // Bits of SSPCON #define WCOL 7 #define SSPOV 6 #define SSPEN 5 #define CKP 4 #define SSPM3 3 #define SSPM2 2 #define SSPM1 1 #define SSPM0 0 // Bits of ADCON0 #define GO_DONE 2 #define GO_DONE_MASK 0x04 // Bits of PIE1 #define ADIE 6 // Port addresses char PORTC@0x07; char PORTD@0x08; char PORTE@0x09; // USART Registers char TXREG@0x19; char RCREG@0x1a; char TXSTA@0x98; char RCSTA@0x18; char SPBRG@0x99; // Extra Ports on PIC16F877 char TRISC@0x87; char TRISD@0x88; char TRISE@0x89; char PIE1@0x8c; char PIE2@0x8d; char PIR1@0x0c; char PIR2@0x0d; char PCON@0x8e; // ADC registers; char ADCON0@0x1f; char ADCON1@0x9f; char ADRESH@0x1e; char ADRESL@0x9e; void Setup(void); void UpdateAnalog(void); void ShowAsHex( char bcd ); char ADH; // Storage of A/D converter result ( high byte ) char ADL; // Storage of A/D converter result ( low byte ) const char *Message1 = "Analog Display"; void interrupt(void) { if ( PIR1 & ADIF_MASK ) // If the A/D interrupted { UpdateAnalog(); // Update the A/D value for display clear_wdt(); clear_bit( PIR1, ADIF ); // Clear the interrupt flag } // Return from Interrupt } void main( void) { Setup(); // Setup the Ports etc. /*****************************/ /* Display a startup message */ /*****************************/ WriteLCDString( Message1 ); /*********************************/ /* Constantly display A/D result */ /*********************************/ while(1) { LCD_Line_2(); WriteLCDString("A/D = "); /**********************/ /* Start converting. */ /**********************/ clear_bit( PIR1, ADIF ); set_bit( ADCON0, GO_DONE ); /**********************/ /* Display result */ /**********************/ ShowAsHex( ADH ); ShowAsHex( ADL ); delay_ms(5); } } /*****************************************************/ /* setup PIC16F877 options,ports,interrupts */ /*****************************************************/ void Setup(void) { set_bit( INTCON, GIE ); // Enable Global Interrupts set_bit( INTCON, PEIE ); // Enable all Peripheral Interrupts set_bit( PIE1, ADIE ); // Enable A/D interrupt OPTION_REG = 0x0E; // Set Option register // Prescaler = WDT // 0x0C = WDT rate := 1:16 // 0x0E = WDT rate := 1:64 TRISD = PortDConfig; // ADCON1 = 0x7f; // Disable ADC ADCON1 = 0x82; // Enable ADC //PCON = 0x03; // Reset Power up status flags TRISA = PortAConfig; TRISB = PortBConfig; TRISC = PortCConfig; TRISE = PortEConfig; // Select an A/D input channel ADCON0 = 0x41; // A/D converter enabled // Upper 2 bits affect conversion speed. PIR1 = 0; clear_wdt(); LCD_Setup(); // Setup the LCD } /***************************/ /* ADIF Interrupt routine */ /***************************/ void UpdateAnalog(void) { /* Other processing here */ ADH = ADRESH; ADL = ADRESL; } /******************************************/ /* Convert the char to HEX and display */ /******************************************/ void ShowAsHex( char bcd ) { char n; n = bcd; n >>= 4; // Do high nibble first n &= 0x0f; // Mask upper bits if ( n < 10 ) LCD_Write_4_Bit( n + '0' ); else LCD_Write_4_Bit( ( n-10 ) + 'A' ); bcd &= 0x0f; // Mask upper bits for low nibble if ( bcd < 10 ) LCD_Write_4_Bit( bcd +'0' ); else LCD_Write_4_Bit( ( bcd-10 ) + 'A' ); } /*********************************************/ /* Include code for the lcd interface */ /*********************************************/ #include