/* * TMAP Sensor Fault Detection for ESD Assignment * PIC16F877A, 20MHz Crystal, 8-bit LCD on PORTB * A0 = MAP Signal, A1 = Temp Signal * Thresholds: <0.2V = Open, >4.8V = Short to Power */ #define _XTAL_FREQ 20000000 #include <xc.h> // CONFIG bits for 20MHz HS oscillator #pragma config FOSC = HS // High speed crystal #pragma config WDTE = OFF // Watchdog off #pragma config PWRTE = ON // Power-up timer on #pragma config BOREN = ON // Brown-out reset on #pragma config LVP = OFF // Low voltage programming off #pragma config CPD = OFF // Data EEPROM protection off #pragma config WRT = OFF // Flash write protection off #pragma config CP = OFF // Code protection off // LCD connections - 8 bit mode on PORTB #define LCD_PORT PORTB #define LCD_TRIS TRISB #define RS RB0 // Register Select #define EN RB1 // Enable #define RW RB2 // Read/Write - tied low in hardware // Function prototypes void LCD_Init(void); void LCD_Command(unsigned char cmd); void LCD_Char(unsigned char data); void LCD_String(const char *str); void LCD_SetCursor(unsigned char row, unsigned char col); void ADC_Init(void); unsigned int ADC_Read(unsigned char channel); void Delay_ms(unsigned int ms); void main(void) { unsigned int adc_map, adc_temp; float volt_map, volt_temp; // Set ports: A0,A1 analog input, rest digital ADCON1 = 0x80; // Right justified, AN0-AN1 analog, rest digital TRISA = 0x03; // RA0, RA1 input. Rest output TRISB = 0x00; // PORTB all output for LCD PORTB = 0x00; LCD_Init(); ADC_Init(); LCD_SetCursor(1,1); LCD_String("TMAP Sensor Test"); Delay_ms(2000); LCD_Command(0x01); // Clear while(1) { // Read ADC: 0-1023 for 0-5V adc_map = ADC_Read(0); // AN0 = MAP adc_temp = ADC_Read(1); // AN1 = Temp // Convert to voltage: ADC * 5 / 1023 volt_map = adc_map * 0.004887; volt_temp = adc_temp * 0.004887; LCD_SetCursor(1,1); // Priority: E01 Connector Open > E02/E03 Short // E01: Both signals < 0.2V = connector open if(volt_map < 0.20 && volt_temp < 0.20) { LCD_String("E01: OPEN CKT "); LCD_SetCursor(2,1); LCD_String("Check Connector "); } // E02: MAP > 4.8V = Short to power else if(volt_map > 4.80) { LCD_String("E02: MAP SHORT "); LCD_SetCursor(2,1); LCD_String("MAP=5V "); LCD_Command(0xC7); // Line 2, pos 7 LCD_Char((adc_map/1000)%10 + '0'); LCD_Char((adc_map/100)%10 + '0'); LCD_Char((adc_map/10)%10 + '0'); LCD_Char(adc_map%10 + '0'); } // E03: Temp > 4.8V = Short to power else if(volt_temp > 4.80) { LCD_String("E03: TEMP SHORT "); LCD_SetCursor(2,1); LCD_String("TMP=5V "); LCD_Command(0xC7); LCD_Char((adc_temp/1000)%10 + '0'); LCD_Char((adc_temp/100)%10 + '0'); LCD_Char((adc_temp/10)%10 + '0'); LCD_Char(adc_temp%10 + '0'); } // Normal condition else { LCD_String("System OK "); LCD_SetCursor(2,1); LCD_String("M:"); LCD_Char((adc_map/1000)%10 + '0'); LCD_Char('.'); LCD_Char(((adc_map*5)/102)%10 + '0'); LCD_String("V T:"); LCD_Char((adc_temp/1000)%10 + '0'); LCD_Char('.'); LCD_Char(((adc_temp*5)/102)%10 + '0'); LCD_String("V "); } Delay_ms(300); } } void ADC_Init(void) { ADCON0 = 0x41; // ADC ON, Fosc/16, Channel 0 ADCON1 = 0x80; // Right justified, Vref = Vdd/Vss } unsigned int ADC_Read(unsigned char channel) { ADCON0 &= 0xC5; // Clear channel bits ADCON0 |= channel << 3; // Set channel Delay_ms(1); // Acquisition time GO_nDONE = 1; // Start conversion while(GO_nDONE); // Wait return ((ADRESH << 8) + ADRESL); // Return 10-bit result } void LCD_Init(void) { LCD_TRIS = 0x00; // PORTB output Delay_ms(20); LCD_Command(0x38); // 8-bit, 2 line, 5x7 LCD_Command(0x0C); // Display on, cursor off LCD_Command(0x06); // Auto increment LCD_Command(0x01); // Clear display Delay_ms(2); } void LCD_Command(unsigned char cmd) { RS = 0; // Command mode RW = 0; // Write LCD_PORT = (LCD_PORT & 0x03) | (cmd & 0xFC); // Keep RS,EN, put data if(cmd & 0x02) RB1 = 1; else RB1 = 0; // D1 if(cmd & 0x01) RB0 = 1; else RB0 = 0; // D0 EN = 1; Delay_ms(1); EN = 0; Delay_ms(2); LCD_PORT = cmd; // Send full byte EN = 1; Delay_ms(1); EN = 0; Delay_ms(2); } void LCD_Char(unsigned char data) { RS = 1; // Data mode RW = 0; LCD_PORT = data; EN = 1; Delay_ms(1); EN = 0; Delay_ms(2); } void LCD_String(const char *str) { while(*str) LCD_Char(*str++); } void LCD_SetCursor(unsigned char row, unsigned char col) { if(row == 1) LCD_Command(0x80 + (col-1)); else LCD_Command(0xC0 + (col-1)); } void Delay_ms(unsigned int ms) { while(ms--) __delay_ms(1); }
Standard input is empty
/*
* TMAP Sensor Fault Detection for ESD Assignment
* PIC16F877A, 20MHz Crystal, 8-bit LCD on PORTB
* A0 = MAP Signal, A1 = Temp Signal
* Thresholds: <0.2V = Open, >4.8V = Short to Power
*/
#define _XTAL_FREQ 20000000
#include <xc.h>
// CONFIG bits for 20MHz HS oscillator
#pragma config FOSC = HS // High speed crystal
#pragma config WDTE = OFF // Watchdog off
#pragma config PWRTE = ON // Power-up timer on
#pragma config BOREN = ON // Brown-out reset on
#pragma config LVP = OFF // Low voltage programming off
#pragma config CPD = OFF // Data EEPROM protection off
#pragma config WRT = OFF // Flash write protection off
#pragma config CP = OFF // Code protection off
// LCD connections - 8 bit mode on PORTB
#define LCD_PORT PORTB
#define LCD_TRIS TRISB
#define RS RB0 // Register Select
#define EN RB1 // Enable
#define RW RB2 // Read/Write - tied low in hardware
// Function prototypes
void LCD_Init(void);
void LCD_Command(unsigned char cmd);
void LCD_Char(unsigned char data);
void LCD_String(const char *str);
void LCD_SetCursor(unsigned char row, unsigned char col);
void ADC_Init(void);
unsigned int ADC_Read(unsigned char channel);
void Delay_ms(unsigned int ms);
void main(void) {
unsigned int adc_map, adc_temp;
float volt_map, volt_temp;
// Set ports: A0,A1 analog input, rest digital
ADCON1 = 0x80; // Right justified, AN0-AN1 analog, rest digital
TRISA = 0x03; // RA0, RA1 input. Rest output
TRISB = 0x00; // PORTB all output for LCD
PORTB = 0x00;
LCD_Init();
ADC_Init();
LCD_SetCursor(1,1);
LCD_String("TMAP Sensor Test");
Delay_ms(2000);
LCD_Command(0x01); // Clear
while(1) {
// Read ADC: 0-1023 for 0-5V
adc_map = ADC_Read(0); // AN0 = MAP
adc_temp = ADC_Read(1); // AN1 = Temp
// Convert to voltage: ADC * 5 / 1023
volt_map = adc_map * 0.004887;
volt_temp = adc_temp * 0.004887;
LCD_SetCursor(1,1);
// Priority: E01 Connector Open > E02/E03 Short
// E01: Both signals < 0.2V = connector open
if(volt_map < 0.20 && volt_temp < 0.20) {
LCD_String("E01: OPEN CKT ");
LCD_SetCursor(2,1);
LCD_String("Check Connector ");
}
// E02: MAP > 4.8V = Short to power
else if(volt_map > 4.80) {
LCD_String("E02: MAP SHORT ");
LCD_SetCursor(2,1);
LCD_String("MAP=5V ");
LCD_Command(0xC7); // Line 2, pos 7
LCD_Char((adc_map/1000)%10 + '0');
LCD_Char((adc_map/100)%10 + '0');
LCD_Char((adc_map/10)%10 + '0');
LCD_Char(adc_map%10 + '0');
}
// E03: Temp > 4.8V = Short to power
else if(volt_temp > 4.80) {
LCD_String("E03: TEMP SHORT ");
LCD_SetCursor(2,1);
LCD_String("TMP=5V ");
LCD_Command(0xC7);
LCD_Char((adc_temp/1000)%10 + '0');
LCD_Char((adc_temp/100)%10 + '0');
LCD_Char((adc_temp/10)%10 + '0');
LCD_Char(adc_temp%10 + '0');
}
// Normal condition
else {
LCD_String("System OK ");
LCD_SetCursor(2,1);
LCD_String("M:");
LCD_Char((adc_map/1000)%10 + '0');
LCD_Char('.');
LCD_Char(((adc_map*5)/102)%10 + '0');
LCD_String("V T:");
LCD_Char((adc_temp/1000)%10 + '0');
LCD_Char('.');
LCD_Char(((adc_temp*5)/102)%10 + '0');
LCD_String("V ");
}
Delay_ms(300);
}
}
void ADC_Init(void) {
ADCON0 = 0x41; // ADC ON, Fosc/16, Channel 0
ADCON1 = 0x80; // Right justified, Vref = Vdd/Vss
}
unsigned int ADC_Read(unsigned char channel) {
ADCON0 &= 0xC5; // Clear channel bits
ADCON0 |= channel << 3; // Set channel
Delay_ms(1); // Acquisition time
GO_nDONE = 1; // Start conversion
while(GO_nDONE); // Wait
return ((ADRESH << 8) + ADRESL); // Return 10-bit result
}
void LCD_Init(void) {
LCD_TRIS = 0x00; // PORTB output
Delay_ms(20);
LCD_Command(0x38); // 8-bit, 2 line, 5x7
LCD_Command(0x0C); // Display on, cursor off
LCD_Command(0x06); // Auto increment
LCD_Command(0x01); // Clear display
Delay_ms(2);
}
void LCD_Command(unsigned char cmd) {
RS = 0; // Command mode
RW = 0; // Write
LCD_PORT = (LCD_PORT & 0x03) | (cmd & 0xFC); // Keep RS,EN, put data
if(cmd & 0x02) RB1 = 1; else RB1 = 0; // D1
if(cmd & 0x01) RB0 = 1; else RB0 = 0; // D0
EN = 1; Delay_ms(1); EN = 0; Delay_ms(2);
LCD_PORT = cmd; // Send full byte
EN = 1; Delay_ms(1); EN = 0; Delay_ms(2);
}
void LCD_Char(unsigned char data) {
RS = 1; // Data mode
RW = 0;
LCD_PORT = data;
EN = 1; Delay_ms(1); EN = 0; Delay_ms(2);
}
void LCD_String(const char *str) {
while(*str) LCD_Char(*str++);
}
void LCD_SetCursor(unsigned char row, unsigned char col) {
if(row == 1) LCD_Command(0x80 + (col-1));
else LCD_Command(0xC0 + (col-1));
}
void Delay_ms(unsigned int ms) {
while(ms--) __delay_ms(1);
}