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

📄 p87c591_i2c_test.c

📁 飞利浦提供的I2C参考程序。共P87C591使用。
💻 C
字号:
//------------------------------------------------------------------------------
// Keil Software, Inc.
// 
// Project: 	I2C EXAMPLE PROGRAM (BIT BANGED) FOR P87C591 MCU
//
// Filename: 	P87C591_I2C_Test.c
// Version: 	1.0.0
// Description:	This file contains example code to print over the serial
//				port of the P87C591 MCU and Evaultion Board (EVAL-P87C591QS).
//				This example will test the I2C function of the P87C591.
//				This will be done by writing and reading from
//				a serial A/D & D/A (P8591).
//				
//				This example will bit bang two general I/O ports for I2C
//
//				The example work with communicate at: 9600, 8, N, 1.
//
//				This code was tested using the mon-51 connected through COM-1
//				of the eval board.
//				CPU Frequency: 33.00 MHz
//
// Copyright 2000 - Keil Software, Inc.
// All rights reserved.
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
// Header files
//------------------------------------------------------------------------------
#include "REG591.H" 						// Header file for the P87C591 MCU
#include <STDIO.H>							// Standard I/O header file

sbit  P1_6 	= 0x96;							// Define the individual bit
sbit  P1_7 	= 0x97;							// Define the individual bit

//------------------------------------------------------------------------------
// Value Definitions
//------------------------------------------------------------------------------
#define 	TRUE			0x01			// Value representing TRUE
#define		FALSE			0x00			// Value representing FALSE
#define 	ON				0x01			// Value representing ON
#define		OFF				0x00			// Value representing OFF
#define 	HIGH			0x01			// Value representing ON
#define		LOW				0x00			// Value representing OFF

#define  	DELAY_WAIT		5000			// Value for delay time 

#define		I2C_ERROR		0x00
#define		I2C_OK			0x01
#define		I2C_BUSY		0x02


//------------------------------------------------------------------------------
// I2C Status Message Codes (Master Codes)
//------------------------------------------------------------------------------
#define		START_TXD			0x08		// Start condition for bus transmited
#define		REPEAT_START_TXD	0x10		// Repeated Start condition for bus transmited
#define		ADDRESS_TXD_ACK		0x18		// Address plus write sent, ack recieved
#define		ADDRESS_TXD_NOACK	0x20		// Address plus write sent, NO ack recieved!
#define		DATA_TXD_ACK		0x28		// Data sent, ack recieved
#define		DATA_TXD_NOACK		0x30		// Data sent, NO ack recieved!
#define		ARB_LOST			0x38		// I2C Master Arbitration Lost

#define		ADDRESS_RXD_ACK		0x40		// Address plus read sent, ack recieved
#define		ADDRESS_RXD_NOACK	0x48		// Address plus read sent, NO ack recieved!
#define		DATA_RXD_ACK		0x50		// Data received, ack sent
#define		DATA_RXD_NOACK		0x58		// Data received, NO ack sent!


//------------------------------------------------------------------------------
// I2C Peripheral Function Prototypes
//------------------------------------------------------------------------------
											// Reads the ADC value for a given channel
unsigned char read_adc_channel(unsigned char channel_number);
void write_dac (unsigned char voltage_out);	// Writes a byte to the DAC

//------------------------------------------------------------------------------
// I2C Functions
//------------------------------------------------------------------------------
void i2c_start (void);						// Starts a transfer

//------------------------------------------------------------------------------
// Support Function Prototypes
//------------------------------------------------------------------------------
void initialize_system (void);				// Initializes MCU (RS-232)
void delay_time (unsigned int time_end);    // To pause execution for pre-determined time

//------------------------------------------------------------------------------
// Globar Variables
//------------------------------------------------------------------------------
unsigned char data_buffer[4], number_of_bytes, device_address, data_in, transfer_status;
bit	i2c_read_write;

//------------------------------------------------------------------------------
// MAIN FUNCTION 
//------------------------------------------------------------------------------
void main (void)
{
	unsigned char voltage_out;

	initialize_system();

	printf("\n\rKeil Software, Inc.\n\r");	// Display starup message
	printf("P87C591 MCU I睠 Example Test Program\n\r");
	printf("Version 1.0.0\n\r");
	printf("Copyright 2000 - Keil Software, Inc.\n\r");
	printf("All rights reserved.\n\n\r");
	printf("P8591 Test Program....Reading from ADC channel 0, Writing to DAC!\n\r");

	while (TRUE)
	{
		for (voltage_out = 0; voltage_out < 0xFF; voltage_out++)
		{
			write_dac(voltage_out);			// Write voltage value to DAC
			delay_time(DELAY_WAIT);
											// Read voltage (ADC 0) and display results
   			printf("DAC output: %3bu     ADC Channel 0: %3bu\n\r", voltage_out, read_adc_channel(0x00));
		}
	}
}

//------------------------------------------------------------------------------
// I2C Peripheral Function Prototypes
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
// Procedure:	write_dac
// Inputs:		voltage_out
// Outputs:		none
// Description:	Writes a byte to the DAC
//------------------------------------------------------------------------------
void write_dac (unsigned char voltage_out)	
{
	device_address = 0x90;
	i2c_read_write = 0;
	number_of_bytes = 2;
	data_buffer[0] = 0x40;
	data_buffer[1] = voltage_out;
	i2c_start();                  			// Start the I2C Transfer
}

//------------------------------------------------------------------------------
// Procedure:	read_adc_channel
// Inputs:		channel
// Outputs:		none
// Description:	Reads the ADC value for a given channel
//------------------------------------------------------------------------------
unsigned char read_adc_channel(unsigned char channel_number)
{
	device_address = 0x90;
	i2c_read_write = 0;
	number_of_bytes = 1;
	data_buffer[0] = 0x40 | channel_number;
	i2c_start();                  			// Start the I2C Transfer

	i2c_read_write = 1;
	i2c_start();                  			// Start the I2C Transfer

	return data_in;                 
}

//------------------------------------------------------------------------------
// I2C Functions 
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
// 	Routine:	i2c_start
//	Inputs:		none
//	Outputs:	none
//	Purpose:	Starts I2C Transfer
//------------------------------------------------------------------------------
void i2c_start (void)
{
	S1CON = 0x43;     						// Enable I2C, 75 KHz, Int.
	STA = 1;          						// Send start signal
	transfer_status = I2C_BUSY;			
	while (transfer_status == I2C_BUSY);	// Wait unitl finished
}

//------------------------------------------------------------------------------
// SUPPORT FUNCTIONS
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
 // Procedure:	initialize_system
// Inputs:		none
// Outputs:		none
// Description:	Initializes embedded system MCU LPC764
//------------------------------------------------------------------------------
void initialize_system (void)
{
// Initialize the serial port (9600, 8, N, 1) 
	PCON &= 0x7F;							// Set bit 7 of the PCON register (SMOD = 0)  
	S0PSH = 0x00;							// Set the baud rate to be generated from Timer #1
	S0CON = 0x50;							// 0101,0000 (Mode 1 and RxD enable)			
	TMOD |= 0x20;							// Timer #1 in autoreload 8 bit mode
	TH1 = 0xF3;								// Baud rate is determined by
											// Timer #1 overflow rate (T1H = 256 - (Fosc / (192 * BR)))
	TR1 = 1;								// Turn on Timer 1
	TI = 1;									// Set UART to send first char

// Initialize I2C Interface (75 kHZ operation)
	P1_6 = 1;
	P1_7 = 1;
	P1M1 |= 0xC0;
	P1M2 |= 0xC0;

	S1CON = 0x43;							// Configure I2C
  	ES1 = 1;   								// Enable I2C Int.
	EA = 1;									// Int. Enable Global
}

////////////////////////////////////////////////////////////////////////////////
// 	Routine:	delay_time
//	Inputs:		counter value to stop delaying
//	Outputs:	none
//	Purpose:	To pause execution for pre-determined time
////////////////////////////////////////////////////////////////////////////////
void delay_time (unsigned int time_end)
{
	unsigned int index;
	for (index = 0; index < time_end; index++);
}

////////////////////////////////////////////////////////////////////////////////
// 	Routine:	i2c_isr
//	Inputs:		none
//	Outputs:	none
//	Purpose:	Services the I2C Interrupt based upon status value and mode
////////////////////////////////////////////////////////////////////////////////
void i2c_isr(void) interrupt 5 using 1
{
	static buffer_index;
	
	switch(S1STA)
  	{
	    case START_TXD:						// Start condition for bus transmited, send the address
    		STA = 0;                        // Clear start bit
		  	if (i2c_read_write)				// If Read Mode, Send device addres and read signal 
				S1DAT = device_address | 0x01;
			else							// Send device addres and write signal 
			  	S1DAT = device_address & 0xFE;
	      	break;
	    case REPEAT_START_TXD:				// Repeated Start condition for bus transmited
	      	STA = 0;                        // Clear start bit
		  	break;
    	case ADDRESS_TXD_ACK:				// Address plus write sent, ack recieved, send the 
		  	buffer_index = 0;				// Send first byte
	      	S1DAT = data_buffer[buffer_index];
	      	break;
    	case ADDRESS_TXD_NOACK:				// Address plus write sent, NO ack recieved! Stop the transfer
	      	STO = 1;						// Stop the transfer - ERROR
		  	transfer_status = I2C_ERROR;
	      	break;
    	case DATA_TXD_ACK:					// Data Bytes sent, ack recieved, send the next byte (if any) 
			buffer_index++;
 			if (number_of_bytes > buffer_index)
			{								// Send next byte in series
		      S1DAT = data_buffer[buffer_index];
			}
			else
		 	{
				STO = 1;					// Else stop the transfer - OK!
				transfer_status = I2C_OK;
		   	}
	     	break;
    	case DATA_TXD_NOACK:				// Data Bytes sent, NO ack recieved! Stop the transfer
	      	STO = 1;						// Stop the transfer - ERROR
		  	transfer_status = I2C_ERROR;
	      	break;
		case ADDRESS_RXD_ACK:				// Address plus read sent, ack recieved
		  	break;
		case ADDRESS_RXD_NOACK:				// Address plus read sent, NO ack recieved!
	      	STO = 1;						// Stop the transfer - ERROR
		  	transfer_status = I2C_ERROR;
	      	break;
		case DATA_RXD_NOACK:				// Data Byte received, NO ack sent!
		  	data_in = S1DAT;				// Read the byte
		  	STO = 1;						// Stop the transfer - OK!
		  	transfer_status = I2C_OK;
	      	break;
		default:							// ERROR OUT, UNKOWN STATE
		  	STO = 1;       
		  	ES1 = 0;       
		  	transfer_status = I2C_ERROR;
		  	break;
  	}
  	SI = 0;    
}

⌨️ 快捷键说明

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