⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 us_v2.c

📁 超声波测距仪单片机C语言源程序。采用PIC16F877单片机。
💻 C
字号:
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////    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('-');
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -