立即注册 登录
返回首页

uid:112317的个人空间

日志

pic单片机超声波测距程序

已有 2643 次阅读2016-4-7 01:53

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////    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('-');
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


路过

鸡蛋

鲜花

握手

雷人

评论 (0 个评论)

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

返回顶部