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

📄 ssp.c

📁 用PIC16F887做的4个触摸按键的例程
💻 C
字号:
// ssp.c
// Tom Perme
// Microchip Technology Inc.
// 2007

#include "main887.h"
#include "ssp.h"

void SSPInit(void);
void SSPISR(void);					
void LoadSSPBUF(void);
void UnloadSSPBUF(void);

/*....................................................................
.	SSPInit()
.
.		Initializes pins and registers for SSP use.
....................................................................*/
void SSPInit(void) {

	int i;

	// SSP Pins
	TRISSDA = 1;								// SDA = 1nput  (digital i/p, ANSEL set by Cap. init)
	TRISSCL = 1;								// SCL = 1nput  (digital i/p, ANSEL set by Cap. init)

	// Initialize Module
	SSPCON 	= 0x00;								// Clear Reg, then set appropriate bits.
	SSPEN 	= 1;								// Enable module
	CKP		= 1;								// Enable Clock
	SSPM3	= 1;								// Set for I2C slave, 7-bit addr, S & P intpts
	SSPM2	= 1;								//      "
	SSPM1	= 1;								//      "
	SSPM0	= 0;

	GCEN 	= 0;								// Clear general call enable interrupt (only react to device address)
	SSPADD 	= DEVICE_ADDR;						// Set device address to respond to, mask bits default 0xFF to match all.
	SMP 	= 1;								// Set for sample rate ~100kHz

	SSPIF	= 0;								// Clear flag in case prexists as set PIR1
	SSPIE	= 1;								// Enable SSP Interrupt
	PEIE	= 1;								// Enable Peripheral Interrupts
	/* GIE										Needs to be set when ready to enable all interrupts. */
	

	// Init Ram Variables
	Flags.SSPBF = 0;
	ByteCount 	= 0;
}



/*....................................................................
.		High level call that determines what action to take. Call
.	this function whenever an SSPIF flag is detected whether under
.	read or write conditions.  The condition will be sorted out,
.	and the appropriate action will be taken to make the device
.	act as EEPROM.
....................................................................*/
void SSPISR(void) {


	SSPIF = CLEAR;								// Clear interrupt flag right away

	// 1. Check if I have a start or stop condition
	// 2. Service Starts and Stops differently
	// 3. Service byte transmissions read/write as appropriate

	if (STOP == 1) {
		// Stop Condition
		Flags.SSPBF = CLEAR;

		// Wrap-up Transmission
		SSPOV = CLEAR;							// Clear overflow err if applicable		
		CKP	  = SET;							// Enable clock again
		return;									// Return to end SSP use
		
	} else if (RW == 0 && BF == 0) {
		// Start Condition
		Flags.SSPBF = SET;						// Set SSP Busy Flag

		SSPOV = CLEAR;							// Clear overflow err if applicable		
		CKP	  = SET;							// Enable clock again
		return;									// Return to finish start interrupt
	}
	
	// If not a Start or Stop, perform the read or write of a byte

	if (DA == 0) {								// DEVICE ADDRESS BYTE, determine if R/W
		
		if (RW == 0) {							// Write byte
			ByteCount = SSPBUF;					// Read SSPBUF to clear BF flag (destination not critical)
			ByteCount = 0;						// Clear ByteCount for start of Write(s)

		} else {								// Read Byte
												// { Master expecting data to be sent from address at SSPBUF }
			CKP = 0;							// Ensure clock disabled
			LoadSSPBUF();						// Load SSPBUF and prep for next pass
		}

	} else {									// DATA BYTE
		
		if (RW == 0) {							// Write Byte
			
			if (ByteCount == 0) {				// 2nd Byte received by slave, (command byte)
				SSPCommand = SSPBUF;			// Index for where to read is byte received over SSP.
				ByteCount++;					// Increment BC for next pass to keep track of byte meanings

			} else if (ByteCount == 1) {		// 3rd Write Byte received by slave, (index byte)
				SSPIndex = SSPBUF;				// Get the index of sensor to start readings
				ByteCount++;					// Keep track of received bytes from Master					

			} else if (ByteCount == 2) {		// 4th Write Byte received by slave, (size byte)
				SSPSize = SSPBUF;				// How many sensors to operate upon
				if (SSPCommand != WRITE_SENSOR)	// For all but read funcs, reset bc
					ByteCount = 0;				// Clear ByteCount to start over - for use with reads, helps 0-base index values
				else
					ByteCount++;

			} else {							// Receiving data byte
												// { Note no bounds checking }
				UnloadSSPBUF();					// Take Contents of SSPBUF and place into data arrays
			}

		} else {								// Read Byte
												// { Send data to master. }
			CKP    = CLEAR;						// disable clock line
			LoadSSPBUF();						// Load SSPBUF and prep for next pass
		}	
	}

	// Finished servicing byte		
				
	SSPOV = CLEAR;								// Clear overflow err if applicable		
	CKP	  = SET;								// Enable clock again
	return;	
}




/*....................................................................
.	LoadSSPBUF()
.
.		Loads the SSPBUF register with the appropriate data.  Since
.	the data is stored as 2-byte integers, and only 1 byte may be sent
.	over the SSP at a time, the byte must be loaded in the correct
.	byte of each integer variable.
.		(Reads bytes from PIC to Master)
....................................................................*/
void LoadSSPBUF(void) {

	if (SSPCommand == READ_RAW_AVG) {
		// Command byte says to reply to the Master with Raw and Avg data for requested sensors

		// RAW
		if (ByteCount < 2*SSPSize) {
			// Send raw data for requested sensors

			// First entrance, setup index counter
			if (ByteCount == 0)					
				IndexCount = SSPIndex;				
			
			// Send the data
			SSPBUF = (ByteCount % 2) ? RAW[IndexCount] : RAW[IndexCount] >> 8;	// Load SSPBUF with raw data


		
		// AVG
		} else {
			// For read raw/avg, there is only avg left

			// First entrance, set up index counter
			if (ByteCount == 2*SSPSize*1)
				IndexCount = SSPIndex;

			// Send the data
			SSPBUF = (ByteCount % 2) ? AVERAGE[IndexCount] : AVERAGE[IndexCount] >> 8;	// Load SSPBUF with raw data

		}		
	
	} else if (SSPCommand == READ_ALL) {
		// Reply to the Master with RAW, AVERAGE, TRIP, and GUARd

		if (ByteCount < 2*SSPSize) {
			// RAW
			// ...

			// First entrance, setup index counter
			if (ByteCount == 0)					
				IndexCount = SSPIndex;				
			
			// Send the data
			SSPBUF = (ByteCount % 2) ? RAW[IndexCount] : RAW[IndexCount] >> 8;	// Load SSPBUF with raw data


		} else if (ByteCount <2*SSPSize*2) {
			// AVERAGE
			// ...

			// First entrance, set up index counter
			if (ByteCount == 2*SSPSize*1)										// Detects rolling from above if, into this else if
				IndexCount = SSPIndex;

			// Send the data
			SSPBUF = (ByteCount % 2) ? AVERAGE[IndexCount] : AVERAGE[IndexCount] >> 8;	// Load SSPBUF with data


		} else if (ByteCount <2*SSPSize*3) {									// 2*SSPSize*3 enters trip byte region
			// TRIP
			// ...
		
			// First entrance, set up index counter
			if (ByteCount == 2*SSPSize*2)
				IndexCount = SSPIndex;

			// Send the data
			SSPBUF = (ByteCount % 2) ? TRIP[IndexCount] : TRIP[IndexCount] >> 8;	// Load SSPBUF with data

		} else if (ByteCount <2*SSPSize*4) {
			// GUARD
			// ...

			// First entrance, set up index counter
			if (ByteCount == 2*SSPSize*3)
				IndexCount = SSPIndex;

			// Send the data
			SSPBUF = (ByteCount % 2) ? GUARD[IndexCount] : GUARD[IndexCount] >> 8;	// Load SSPBUF with data

		}		


	} else if (SSPCommand == READ_NUM_SENSORS) {
		// This one is easy.. 
		SSPBUF = NUM_BTTNS;										// Report the number of buttons in the system						

	}


	// After each read..
	// Increment byte counter, index counter handled based on func
	ByteCount++;														// Byte counter is for actual byte of dat

	// with new bytecount value, choose to incr. integer index or not
	if (ByteCount % 2 == 0)
		IndexCount++;													// Increment IndexCounter on byte basis (may be reset to start index by func in if's above)

}




/*....................................................................
.	UnloadSSPBUF()
.
.		Unloads the SSPBUF register into the appropriate data.  Since
.	the data is stored as 2-byte integers, and only 1 byte may be sent
.	over the SSP at a time, this makes the PIC act like EEPROM.
.		(Writes bytes from Master into PIC)
....................................................................*/
void UnloadSSPBUF(void) {

	TempInt = SSPBUF;										// Load incoming byte into variable

	// Store Data to Array
	// ...
	if (SSPCommand == WRITE_SENSOR) {
		// Write data to the sensor specified
		// 				TrpU	TrpL	GbU		GbL
		// ByteCount	3		4		5		6
		// (future note: to make extensible, subtract offset of 3 off of BC, or reset to 0-based index another way)
		// (for this simple interface, it was simplest to do it as below)

		// High Bytes

		if (ByteCount == 3)								// Trip high byte
			TRIP[SSPIndex] = TempInt << 8;				// Mul Incoming Byte by 256, shift 8, to get into high byte
		else if (ByteCount == 5)						// Guard high byte
			GUARD[SSPIndex] = TempInt << 8;				// Shift up to high byte

		// Low Bytes
		if (ByteCount == 4) {
			TRIP[SSPIndex] &= 0xFF00;					// Clear Low byte
			TRIP[SSPIndex] |= TempInt;					// Store SSPBUF (Low byte) to raw data
		} else if (ByteCount == 6) {
			GUARD[SSPIndex] &= 0xFF00;					// Clear Low byte
			GUARD[SSPIndex] |= TempInt;					// Store SSPBUF (Low byte) to raw data
		}
	}

	ByteCount++;											// Increment byte recvd counter
}





/*....................................................................
.	SetMasterMode()
.
.		Configures SSP for I2C master mode.  This function should be
.	used prior to communicating from the 16F887 circuit to the 16F677
.	over the SDA and SCL lines. 
....................................................................*/
void SetMasterMode(void) {

	// Set SSPM of SSPCON to 1000 for master mode
	SSPEN = 0;
	SSPCON |= 0b00001000;		// SSPM = 1xxx
	SSPCON &= 0b11111000;		// SSPM = x000  --> SSPM = 1000
	SSPEN = 1;

}



/*....................................................................
.	SetSlaveMode()
.
.		Configures SSP for I2C slave mode.  This function should be
.	used prior to communicating from the 16F887 circuit to the user's
.	computer through the PICkit Serial Analyzer.
....................................................................*/
void SetSlaveMode(void) {

	// Set for I2C slave, 7-bit addr, S & P intpts, SSPM = 1110
	SSPEN = 0;
	SSPCON |= 0b00001110;		// SSPM = 111x
	SSPCON &= 0b11111110;		// SSPM = xxx0  --> SSPM = 1110
	SSPEN = 1;

}


⌨️ 快捷键说明

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