📄 p87c591_i2c_test.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 + -