#include <pic.h>
#include <pic16f877a.h>
#include <htc.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#define _XTAL_FREQ 4000000 // Xtal speed
__CONFIG(0x3D18); // Config bits
#define LCD_PORT PORTC //
#define LCD_TRIS TRISC
#define LCD_RS RA0
#define LCD_RW RA1
#define LCD_E RA2
// Required prototypes
void LCD_init(void), LCD_cmd(unsigned char ch), LCD_busy(void);
void LCD_printC(const char *str), LCD_printR(char *str);
void LCD_goto(char line, char column), LCD_clr(void);
void LCD_cur(unsigned char ch), pulse_E(void), LCD_hex(int value);
void LCD_char(unsigned char ch), LCD_charD(unsigned char ch);
bit Go;
bit too_late;
int distance = 100;
int target = 0;
int x_diff = 0;
int new_target = 0;
void interrupt Change_Target (void)
{
switch (PORTB)
{
case 0b00000011 :
new_target = 1;
break;
case 0b00000101 :
new_target = 2;
break;
case 0b00001001 :
new_target = 3;
break;
case 0b00010001 :
new_target = 4;
break;
case 0b00100001 :
new_target = 5;
break;
default :
break;
}
if (target!=0){
if (target > new_target){
x_diff=(10*(target-new_target));
}
else {
x_diff=(10*(new_target-target));
}
distance = sqrt((pow(x_diff, 2)) + (pow(distance, 2)));
}
target = new_target;
INTCON = 0b10010000;
}
void display(void)
{
char text1[20];
char text2[20];
sprintf (text1,"Target: %d",target);
sprintf (text2,"Distance: %d",distance);
int number = 0; // new counting variable
LCD_goto(1,0); // line 1.
while(text1[number] != 0) // while text1[number] is'nt zero
LCD_printC(text1[number++]); // write message 1
LCD_goto(2,0);
while(text2[number] != 0) // while text2[number] is'nt zero
LCD_printC(text2[number++]); // write message 2
}
void main (void)
{
TRISC = 0x00;
TRISB = 0xFF;
TRISA = 0x00;
INTCON = 0b10010000;
CMCON = 0x7; // Comparitors off // Led port as outputs
__delay_ms(100); // let LCD stabilise
LCD_init(); // Initalise screen
while (distance > 0){
if (PORTB,6 == 1 && target!=0){
Go = 1;
}
while (Go==1 && distance!=0){
__delay_ms(1000);
distance=distance-1;
}
if (distance<=25){
INTCON = 0b00000000;
}
display();
}
}
unsigned char HEX_Table[] = {0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
0x36, 0x37, 0x38, 0x39, 0x41, 0x42,
0x43, 0x44, 0x45, 0x46};
void LCD_printC(const char * str) // This passes the start a ROM character array
{ // by default the pointer points to data section
while(*str != 0) // while the character pointed to isn't 0
LCD_char(*str++); // print out the character, then increment
} // the pointer down the array
void LCD_printR(char * str) // This passes the start of a RAM character array
{ // by default the pointer points to data section
while(*str != 0) // while the character pointed to isn't 0
LCD_char(*str++); // print out the character, then increment
} // the pointer down the array
void LCD_init()
{
LCD_PORT = 2; // I decided to write the first command
LCD_RS = 0; // manually, as the busy flag can't be read
pulse_E(); // on the first instruction
__delay_ms(50);
LCD_PORT = 2;
LCD_RS = 0;
pulse_E();
__delay_ms(50); // busy should be available now..
//LCD_cmd(0x20); // 4 bit
LCD_cmd(0x28); // display shift
LCD_cmd(0x6); // character mode
LCD_cmd(0xc); // display on / off and cursor
LCD_clr(); // clear display
}
void LCD_hex(int value)
{
char data;
data = value >> 4 & 0xf;
data = HEX_Table[data]; // send upper nibble
LCD_char(data);
data = value & 0xf; // send lower nibble
data = HEX_Table[data];
LCD_char(data);
}
void LCD_goto(char line, char column) // combines line and lineW
{
unsigned char data = 0x80; // default to 1
if(line == 2)data = 0xc0; // change to 2
data += column; // add in column
LCD_cmd(data);
}
void LCD_clr()
{
LCD_cmd(1); // Clr screen
}
void LCD_cur(char on)
{
unsigned char cur = 0xc; // cursor off
if(on) cur = 0xd; // cursor on
LCD_cmd(cur);
}
void LCD_busy()
{
unsigned char BUSY = 0;
while(1)
{
LCD_TRIS = 0x0f; // port to read mode
LCD_RS = 0x0;
LCD_RW = 0x1; // set to read
LCD_E = 0x1;
BUSY = LCD_PORT & 0xf; // high byte comes first
__delay_us(5); // so busy flag is on bit 3
LCD_E = 0x0;
LCD_E = 0x1;
__delay_us(5); // dummy read
LCD_E = 0x0;
LCD_RW = 0x0; // set to write
LCD_TRIS = 0x00; // port to write mode
if(!(BUSY & 0x8 )) return; // AND with bit 3
}
}
void LCD_cmd(unsigned char ch)
{
LCD_PORT = ch >> 4 & 0xf;
LCD_RS = 0;
pulse_E();
LCD_PORT = ch & 0xf;
LCD_RS = 0;
pulse_E();
LCD_busy();
}
void LCD_charD(unsigned char ch)
{
ch+=0x30;
LCD_char(ch);
}
void LCD_char(unsigned char ch)
{
LCD_PORT = ch >> 4 & 0xf;
LCD_RS = 1;
pulse_E();
LCD_PORT = ch & 0xf;
LCD_RS = 1;
pulse_E();
LCD_busy();
}
void pulse_E()
{
LCD_E = 1;
__delay_us(1);
LCD_E = 0;
}