//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////// Ultrasonic Range Meter //////////////////////
//////////////////////////////////// //////////////////////
//////////////////////////////////// processor=16F877(A) at 4 MhZ //////////////////////
//////////////////////////////////// i2c eeprom 24c256 //////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include "pic.h" // included from assembler\include directory
#include "defs.h" // include from local workspace
#include "delay.h" // id.
#include "delay.c" // id.
__CONFIG(0x3f31); /* XT_OSC, CP_OFF, PWRT_ON, WRT_ON, WDT_OFF, BODEN_OFF */
#define XTAL_FREQ 4MHZ /* Crystal frequency in MHz */
#define nok_sclk RD6 // nokia lcd sclk
#define nok_sda RD7 // nokia lcd sda
#define nok_dc RD0 // nokia lcd d/!c
#define nok_cs RD3 // nokia lcd !cs
#define nok_res RD1 // nokia lcd !res
#define tx_pin RD5 // reserved (1 wire output to TX module) not used here
#define rx_pin RB7 // reserved (1 wire input from RX module) not used here
#define kmenu RB6 // reserved (key menu) not used here
#define kmin RB3 // reserved (key -)
#define kplus RB4 // reserved (key +)
#define kenter RB5 // reserved (key enter)
#define USRX_q RB2 // Ultrasonic Range Meter USRX_q input
#define USRX_res RD2 // USRX_res output
#define USTX_en RD4 // USTX_en output
////////////////////////// RC3=SCL ext eeprom 24c256 // see settings in void init()
////////////////////////// RC4=SDA ext eeprom 24c256
signed char c;
unsigned char charsel,eerow;
unsigned char bytefornokia;
unsigned char UMSB,LMSB,ULSB,LLSB;
unsigned int dec;
unsigned long binary,speedtest,us_count;
void init(void); // initialisation
void menu_nokia_printmessage(const char* message);
void hex2bcd_conversion(void);
void nokia_write_command(void); // nokia lcd subroutines
void nokia_write_dorc(void);
void nokia_build_DDRAM(void);
void nokia_write_data(void);
void nokia_gotoxy(byte xnokia, byte ynokia);
void nokia_printchar(byte c);
void nokia_printmessage(const char* message);
void ext_eeprom_to_nokialcd(void); // i2c external eeprom to nokia lcd
void speed_test(void);
void us_to_nokia(void); // ultrasonic range meter routine
void blank(void);
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void main(void)
{
init();
nokia_gotoxy(0,0); // x,y
nokia_printmessage("UltraSonic ");
nokia_gotoxy(0,2); // x,y
nokia_printmessage("sample=");
nokia_gotoxy(0,4); // x,y
nokia_printmessage("distance=");
for(;;) { // continually
nokia_gotoxy(60,2);
speed_test();
nokia_gotoxy(60,4);
us_to_nokia(); // ultrasonic range meter routine
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void init(void)
{
// i2c init
char x;
TRISC = 0x18; // RC3-4 are inputs 0001 1000 // RC3=SCK/SCL //RC4=SDI/SDA
SSPSTAT = 0x80; // slew rate disabled // SSPSTAT=0x94
SSPCON = 0x38; // enable port in 7 bit slave mode // SSPCON=0x14
SSPCON2 = 0x00; // not a lot // SSPCON2=0x91
SSPADD = 5; // baud rate in address reg was 19 dec // SSPADD=0x93 i2c slave address buffer
x = SSPBUF; // dummy read clears BF // SSPBUF=0x13 i2c buffer
// port D init
TRISD = 0x00; // portD is output; (NOKIA LCD = portD) + RD5 (=tx_pin)
PORTD = 0x00; // all low
// port B init
TRISB = 0xff; // key inputs + RB7 (=rx_pin)
// nokia LCD init
nok_dc=1; // bytes are stored in the display data ram, address counter, incremented automatically
nok_cs=1; // chip disabled
DelayMs(10);
nok_res=0; // reset chip during 250ms
DelayMs(250);
nok_res=1;
bytefornokia=0x21; // set extins extended instruction set
nokia_write_command();
bytefornokia=0xc5; // Vop was 0xc5 // better is 0xa0
nokia_write_command();
bytefornokia=0x13; // bias
nokia_write_command();
bytefornokia=0x20; // horizontal mode from left to right, X axe are incremented automatically , 0x22 for vertical addressing ,back on normal instruction set too
nokia_write_command();
bytefornokia=0x09; // all on
nokia_write_command();
DelayMs(50);
// DelayMs(250);
nokia_build_DDRAM(); // reset DDRAM, otherwise the lcd is blurred with random pixels
DelayMs(10);
bytefornokia=0x08; // mod control blank change (all off)
nokia_write_command();
DelayMs(10);
bytefornokia=0x0c; // mod control normal change
nokia_write_command();
nokia_gotoxy(0,0);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void nokia_write_command(void)
{
nok_dc=0; // byte is a command it is read with the eight SCLK pulse
nok_cs=0; // chip enabled
nokia_write_dorc();
nok_cs=1; // chip disabled
}
/////////////////////////////////////////////////////////////////////////////////
void nokia_write_data(void)
{
nok_dc=1;
nok_cs=0; // chip enabled
nokia_write_dorc();
nok_cs=1; // chip disabled
}
//////////////////////////////////////////////////////////////////////////////////
void nokia_write_dorc(void) // serial write data or command subroutine
{
for (c=8;c>0;c--) {
nok_sclk=0;
if ((bytefornokia&0x80)==0){
nok_sda=0;
}
else {
nok_sda=1;
}
nok_sclk=1;
bytefornokia=bytefornokia<<1;
}
}
//////////////////////////////////////////////////////////////////////////////////
void nokia_build_DDRAM(void) // clear all DDRAM (set all bits to zero)
{
signed char ch, cm, cl;
nok_sda=0;
nok_dc=1;
nok_cs=0;
for (ch=6;ch>0;ch--){ // 6 rows
for (cm=84;cm>0;cm--){ // 84 columns
for (cl=8;cl>0;cl--){ // 8 pixels
nok_sclk=0;
nok_sclk=1;
}
}
}
nok_cs=1;
}
//////////////////////////////////////////////////////////////////////////////////
void nokia_gotoxy (byte xnokia, byte ynokia) // Nokia LCD Position cursor
{
bytefornokia=(0x40|(ynokia&0x07)); // Y axe initialisation: 0100 0yyy
nokia_write_command();
bytefornokia=(0x80|(xnokia&0x7f)); // X axe initialisation: 1xxx xxxx
nokia_write_command();
}
//////////////////////////////////////////////////////////////////////////////////
void nokia_printmessage(const char* message) // Write message to LCD (C string type)
{
while (*message) // Look for end of string
nokia_printchar(*message++); //
}
//////////////////////////////////////////////////////////////////////////////////
void nokia_printchar(byte c) // Write 1 character to LCD
{
charsel=c;
ext_eeprom_to_nokialcd();
}
//////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// *************************************************************************************************************************
// ****************** i2c eeprom 24c256 read & send 6 bytes to nokia lcd ************************************
// *************************************************************************************************************************
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ext_eeprom_to_nokialcd(void) //
{
SEN = 1; // send start bit START
while(SEN);
ACKDT = 0; // acknowledge bit
SSPIF = 0; // CONTROL 1
SSPBUF = 0xa0; // set device address ext. i2c eeprom
while(!SSPIF);
SSPIF = 0;
SSPBUF=((charsel>>4)&0x0f); // read from address ADDH
while(!SSPIF); //
SSPIF = 0; //
SSPBUF=((charsel<<4)&0xf0); // read from address ADDL
while(!SSPIF); //
SSPIF = 0; //
RSEN = 1; // send repeated start bit REPEATED START
while(RSEN); // and wait for it to clear
SSPIF = 0;
SSPBUF = 0xa1; // set device address ext. i2c eeprom CONTROL 2
while(!SSPIF); // wait for interrupt
SSPIF = 0; // then clear it.
for (eerow=0;eerow<5;eerow++) {
// 5 rows read from eeprom & write to nokia ///////////
RCEN = 1; // start receiving READ & ACK (*5)
while(!STAT_BF); // wait for data
bytefornokia=SSPBUF; // and get it
nokia_write_data(); // send data to nokia
ACKEN = 1; // start acknowledge sequence
while(ACKEN); // wait for ack. sequence to end
}
RCEN = 1; // start receiving READ LAST & NO ACK
while(!STAT_BF); // wait for data
bytefornokia = SSPBUF; // and get it
nokia_write_data(); // send data to nokia
ACKDT = 1; // not acknowledge for last byte
PEN = 1; // send stop bit STOP
while(PEN);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void hex2bcd_conversion(void)
{
union {
struct {
unsigned long low; // 4 bytes (3210)
unsigned long high; // 4 bytes (7654)
} lng;
unsigned char byte[8]; // bytes 76543210
} cdec;
signed char c;
unsigned char d;
// binary = bearingW; // correct input selected in previous routine
// or binary = tempC; // id.
// or binary = speedtest // id.
cdec.lng.low=binary; // input
cdec.lng.high=0; // becomes output after conversion
for (c=0;c<32;c++) { // 32 bits to shift (see notes)
d=cdec.byte[3];
cdec.lng.low<<=1; // 4 bytes (bytes 3210)
cdec.lng.high<<=1; // 4 bytes (bytes 7654)
if ( (d& 0x80)==0x80) cdec.byte[4]|=1; // shift low(byte3)>>high(byte4)
for (d=4;d<8;d++) {
if ((cdec.byte[d]&0x0F)>=0x05) cdec.byte[d]+=0x03; // conversion (see notes)
if ((cdec.byte[d]&0xF0)>=0x50) cdec.byte[d]+=0x30; // conversion (see notes)
}
}
UMSB=(cdec.lng.high>>12)&0x0F; // pick outputs from correct location
LMSB=(cdec.lng.high>>8)&0x0F;
ULSB=(cdec.lng.high>>4)&0x0F;
LLSB=(cdec.lng.high)&0x0F;
if (UMSB>=8) UMSB-=3; // correction for dec output after conversion
if (LMSB>=8) LMSB-=3; //
if (ULSB>=8) ULSB-=3; //
if (LLSB>=8) LLSB-=3; //
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void speed_test(void)
{
binary = speedtest;
hex2bcd_conversion();
nokia_printchar(UMSB|0x30);
nokia_printchar(LMSB|0x30);
nokia_printchar(ULSB|0x30);
nokia_printchar(LLSB|0x30);
speedtest+=1;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void us_to_nokia(void) // ultrasonic range meter routine
{
us_count=0; // reset counter
USRX_res=1; // reset receiver flip-flop
USTX_en=0; // begin sending ultrasonic pulse // 0 is enable (bc639 drive)
DelayUs(150); // delay 300礢
DelayUs(150);
USTX_en=1; // end sending ultrasonic pulse // 1 is disable (bc639 drive)
DelayUs(250); // delay 700礢
DelayUs(250);
DelayUs(200);
DelayUs(250); // delay 500 礢
DelayUs(250); // // minimum distance from now
USRX_res=0; // enable receiver flip-flop //
// DelayUs should be 58 礢 (time needed for 1 cm), compensated for CPU time at 4 MhZ
while (USRX_q){DelayUs(38);us_count+=1;if (us_count==999){blank();return;}}
us_count+=24; // minimum distance addition
binary = us_count;
hex2bcd_conversion();
nokia_printchar(UMSB|0x30);
nokia_printchar(LMSB|0x30);
nokia_printchar(ULSB|0x30);
nokia_printchar(LLSB|0x30);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void blank(void)
{
nokia_printchar('-');
nokia_printchar('-');
nokia_printchar('-');
nokia_printchar('-');
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////