#include<p18f2620.h>
#include<delays.h>
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
void Init_LCD(void);
void WrLCD(char, char);
void Clear_LCD(void);
void CurPosLCD(char);
void Out_LCD(char rom near*);
void Out_Dec_LCD(unsigned int i);
void Out_Hex_LCD(unsigned int i);
void Puts_LCD(char *);
char Hex2ascii(char);
void LCD_Intro(void);
void disp_val(void);
void adc_pressure(void);
void Delay_msec(unsigned int);
void Delay_sec(unsigned int);
#define LCD_DATA PORTB
#define LCD_E PORTBbits.RB1
#define LCD_RS PORTBbits.RB0c
#define PB1 PORTAbits.RA4
#define MOTOR PORTBbits.RB3
#define VALVE PORTCbits.RC2
#define ADC_PRESSURE 0b00000001 // ADC channel 0 for pressure sensor
#define ROM_TYPE (char rom near*)
#define OSC_FREQ 32000000
#define DELAY1MS 8 // 1ms delay = OSC_FREQ(4*1000*1000)
#define DELAY1S 200 // 1s delay = OSC_FREQ/(4*10000*4)
char temp;
unsigned int i,x,y;
int BP;
float Voltage_BP;
void main()
{
OSCCON = 0b01110000; // Use internal 8MHz x 4 oscillator
OSCTUNE = 0b01000001; // Enable HSPLL mode
ADCON0 = 0b00000001; // Turn on ADC
ADCON1 = 0b00001110; // AN0 as analog input
ADCON2 = 0b10101010; // 12 TAD; FOSC/32; Right justified
TRISA = 0b11111111; // RA4<=button
TRISB = 0b00000100; // PORTB=>LCD_DATA, RB0=>LCD_E, RB1=>LCD_RS;
TRISC = 0b11111001; // RC1 & RC2=>MOTOR and VALVE
MOTOR=0;
VALVE=0;
Init_LCD();
LCD_Intro();
while(1)
{
while (1)
{
CurPosLCD(0x11);
Out_LCD(ROM_TYPE "Put on ");
CurPosLCD(0x20);
Out_LCD(ROM_TYPE "cuff and");
if (!PB1)
break;
Delay_sec(1);
CurPosLCD(0x11);
Out_LCD(ROM_TYPE "Press ");
CurPosLCD(0x20);
Out_LCD(ROM_TYPE "<Start> ");
if (!PB1)
break;
Delay_sec(1);
CurPosLCD(0x11);
Out_LCD(ROM_TYPE "250708");
CurPosLCD(0x20);
Out_LCD(ROM_TYPE "07:07:07");
if (!PB1)
break;
Delay_sec(2);
}
WrLCD(0b00000001,0);
CurPosLCD(0x21);
Out_LCD(ROM_TYPE "Relax");
CurPosLCD(0x13);
Out_LCD(ROM_TYPE "5");
Delay_sec(1);
CurPosLCD(0x13);
Out_LCD(ROM_TYPE "4");
Delay_sec(1);
CurPosLCD(0x13);
Out_LCD(ROM_TYPE "3");
Delay_sec(1);
CurPosLCD(0x13);
Out_LCD(ROM_TYPE "2");
Delay_sec(1);
CurPosLCD(0x13);
Out_LCD(ROM_TYPE "1");
Delay_sec(1);
WrLCD(0b00000001,0);
ADCON0 = ADC_PRESSURE; //ADC channel 0 for Pressure sensor
ADCON0bits.GO = 1; //Start A/D conversion
while(ADCON0bits.DONE);
BP = 256*ADRESH + ADRESL; //Get the value abd storein BP
Voltage_BP = BP*(3300/1024); // Convert to mV
if(Voltage_BP<510) // Motor will continue to pump air until it reaches 200mmHg
{
MOTOR=1;
VALVE=1;
CurPosLCD(0x10);
Out_LCD(ROM_TYPE "Taking ");
CurPosLCD(0x20);
Out_LCD(ROM_TYPE "your BP ");
Delay_msec(500);
WrLCD(0b00000001,0);
CurPosLCD(0x10);
Out_LCD(ROM_TYPE " ");
CurPosLCD(0x20);
Out_LCD(ROM_TYPE " ");
Delay_msec(500);
}
WrLCD(0b00000001,0);
CurPosLCD(0x11);
Out_LCD(ROM_TYPE "BP is");
CurPosLCD(0x20);
Out_LCD(ROM_TYPE "taken at");
Delay_sec(2); // Wait for 3 seconds
CurPosLCD(0x11);
Out_LCD(ROM_TYPE "250708");
CurPosLCD(0x20);
Out_LCD(ROM_TYPE "07:07:07");
Delay_sec(2);
WrLCD(0b00000001,0);
disp_val(); // Display BP measurements
CurPosLCD(0x11);
Out_LCD(ROM_TYPE "Have a");
CurPosLCD(0x20);
Out_LCD(ROM_TYPE "good day");
Delay_sec(2);
WrLCD(0b00000001,0);
}
}
// Initialise LCD
void Init_LCD() // LCD display Initialization
{
Delay_msec(15); // 15ms LCD power up delay
WrLCD(0x03,0);
Delay_msec(5); // 5ms delay
WrLCD(0x02,0);
WrLCD(0x28,0); // func set 4-bit, 2lines, 5x7
WrLCD(0x0C,0); // display on, cursor off
WrLCD(0x06,0); // entry mode-inc addr,no shift
WrLCD(0x01,0); // clear display & home position
WrLCD(0x80,0); //Display cursor at home position
}
//Write control/data word to LCD 4-bit at a time
void WrLCD(char x, char i)
{
LCD_RS = i; // Logic '0' to select instruction register
temp = x; // store control word
temp &= 0xF0; // select higher nibble of control word
LCD_DATA &= 0x0F;
LCD_DATA |= temp; // store in LCD_DATA
Delay_msec(1); // 1ms delay
LCD_E = 1; // Activate E pulse
Delay_msec(1); // 1ms delay
LCD_E = 0; // De-activate E pulse
Delay_msec(1); // 1ms delay
temp = x; // store control word
temp <<= 4;
temp &= 0xF0; // select the lower nibble
LCD_DATA &= 0x0F;
LCD_DATA |= temp; // store in LCD_DATA
Delay_msec(1); // 1ms delay
LCD_E = 1; // Activate E pulse
Delay_msec(1); // 1ms delay
LCD_E = 0; // De-activate E pulse
Delay_msec(1); // 1ms delay
}
// Clear the LCD display
void Clear_LCD(void)
{
WrLCD(0x01,1); //Clear display command
WrLCD(0x02,1); //Set cursor to home position
Delay_msec(2);
}
// Set current LCD cursor position
// pos = 0x10 is the first character of the first line
// pos = 0x20 is the first character of the second line
void CurPosLCD(char pos) {
if((0xf0 & pos) == 0x20) {
pos = pos &0x0f;
pos = pos |0xc0;
}
else {
pos = pos & 0x0f;
pos = pos | 0x80;
}
WrLCD(pos, 0);
}
// Display const message on LCD
void Out_LCD(char rom near *message)
{
while (*message)
{
WrLCD(*message,1);
message++;
}
}
// Print decimal number to LCD
void Out_Dec_LCD(unsigned int i)
{
char digit, zero, value;
long denom;
denom = 1000000000;
zero = 1;
if (!value)
WrLCD('0',1);
else
{
while (denom)
{
digit = value/denom;
if (digit)
{
WrLCD(digit + '0',1);
zero = 0;
}
else if (!zero)
WrLCD('0',1);
value -= digit*denom;
denom /= 10;
}
}
}
// Print hexadecimal number to LCD
void Out_Hex_LCD(unsigned int i)
{
unsigned char ctmp0, ctmp1, ctmp2, ctmp3;
ctmp0 = 0x000f & i;
i >>= 4;
ctmp1 = 0x000f & i;
i >>= 4;
ctmp2 = 0x000f & i;
i >>= 4;
ctmp3 = 0x000f & i;
WrLCD(Hex2ascii(ctmp3),1);
WrLCD(Hex2ascii(ctmp2),1);
WrLCD(Hex2ascii(ctmp1),1);
WrLCD(Hex2ascii(ctmp0),1);
}
// Convert hexadecimal number to ASCII character
char Hex2ascii(char c)
{
c &= 0x0f;
if(c < 0x0a)
return (c + 0x30);
else
return (c + 0x37);
}
// Output variable string to LCD
void Puts_LCD(char *message)
{
while (*message)
{
WrLCD(*message,1);
message++;
}
}
// Output initialisation messages
void LCD_Intro(void)
{
Clear_LCD;
CurPosLCD(0x10);
Out_LCD(ROM_TYPE "TEMASEK");
CurPosLCD(0x22);
Out_LCD(ROM_TYPE "POLY ");
Delay_sec(2);
CurPosLCD(0x10);
Out_LCD(ROM_TYPE "PORTABLE");
CurPosLCD(0x20);
Out_LCD(ROM_TYPE "BP METER");
Delay_sec(2);
WrLCD(0b00000001,0);
}
// Display user's bp measurement
void disp_val()
{
for(y=0; y<2; y++)
{
WrLCD(0x82,0);
Out_LCD(ROM_TYPE "SYS ");
WrLCD(0xC0,0);
Out_LCD(ROM_TYPE "mmHg");
Delay_sec(3);
}
}
// Delay multiple number of msec
void Delay_msec(unsigned int delayInMSEC)
{
while (delayInMSEC--)
Delay1KTCYx(DELAY1MS);
}
// Delay multiple number of sec
void Delay_sec(unsigned int delayInSEC)
{
while (delayInSEC--)
{
Delay10KTCYx(DELAY1S);
Delay10KTCYx(DELAY1S);
Delay10KTCYx(DELAY1S);
Delay10KTCYx(DELAY1S);
}