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

📄 i2crtc.c

📁 lcd interface code for lpc214x series micro controllers
💻 C
字号:
#include "i2crtc.h"

#define RTC_ADDRESS 0xA2                 // I2C address of Real Time Clock
#define TIMEOUT 0xAA0F                   // timer reload value gives 22ms timeout period
                                         // for waiting on SLAve address + Write ack

//void init_i2c(void);
void rtc_write_byte(unsigned char address, unsigned char byte);
unsigned char rtc_read_byte(unsigned char address, unsigned char maskoff);
unsigned char bcdtochar(unsigned char bcdnum);
unsigned char chartobcd(unsigned char n);
void i2c_isr(void);
//void start_timer(void);
//void stop_timer(void);

unsigned char mask[] = {0xA8, 0x1F, 0x7F, 0x7F, 0x3F, 0x3F, 0x07, 0x1F,
                        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
			                              // mask values for registers

enum i2c_states { DATA_BYTE, FINISHED, DUMMY_WRITE }; // states of operations
                                                      // during a write the DATA_BYTE state is when the next byte to
													  // be written is the data byte. The FINISHED state is when the
													  // data byte has been written
													  // during a read the DUMMY_WRITE is the state during the dummy
													  // write to set the register address to read
enum i2c_operations { READ, WRITE };                  // possible I2C operations are Read and Write

unsigned char i2c_storage_address;                    // holds the address of the register to read or write
unsigned char i2c_byte;                               // holds the value to write or the value read from a register
unsigned char i2c_state;                              // holds the I2C state - DATA_BYTE, FINISHED or DUMMY_WRITE
unsigned char i2c_status;                             // holds the status - I2C_BUSY, I2C_OK or I2C_ERROR
unsigned char i2c_operation;                          // holds the operation - READ or WRITE
/*
// function init_i2c
// initializes the I2C peripheral
void init_i2c(void)
{
  P1M1 |= 0xC0;                      // set P1.6 and P1.7 open drain
  P1M2 |= 0xC0;
  TMOD |= 0x01;                      // timer 0 mode 1
  ES1 = 1;                           // enable SIO1 interrupts
  EA = 1;                            // global interrupt enable
}
*/
// function chartobcd
// converts a decimal value to the BCD equivalent
// decimal values must be stored in the Real Time Clock in BCD format
// passed is the decimal value to convert
// returned is the BCD equivalent
unsigned char chartobcd(unsigned char n)
{
  return ((n / 10) << 4) | (n % 10);  
}

// function bcdtochar
// converts a number in BCD format to the decimal equivalent
// decimal values must be stored in the Real Time Clock in BCD format
// passed is the BCD format value
// returned is the decimal equivalent
unsigned char bcdtochar(unsigned char bcdnum)
{
  return (bcdnum & 0x0f) + (bcdnum >> 4) * 10;
}

/*
// function rtc_write_byte
// stores a byte in a specific register in the Real Time Clock
// passed is the register address and the byte to store
// nothing is returned
// result of the operation is stored in i2c_status and may be
// I2C_OK or I2C_ERROR
void rtc_write_byte(unsigned char address, unsigned char byte)
{
  i2c_storage_address = address;     // copy the register address
  i2c_byte = chartobcd(byte);        // convert to BCD and copy the byte
  i2c_status = I2C_BUSY;             // I2C is now busy
  i2c_operation = WRITE;             // a write operation is being performed
  S1CON = 0x40;                      // enable the I2C perhiperal
                                     // no acknowledgements will be returned
  STA = 1;                           // request a start condition is transmitted
                                     // therefore putting I2C perhiperal in Master Transmitter mode
  while(i2c_status == I2C_BUSY);     // wait until I2C is not busy
}

// function rtc_read_byte
// reads a byte from a specific register in the Real Time Clock, performing
// optional masking of the result
// passed is the address of the register to read and a flag to indicate
// if masking is required - may be MASK or NOMASK
// the decimal value is returned
// result of the operation is stored in i2c_status and may be
// I2C_OK or I2C_ERROR 
unsigned char rtc_read_byte(unsigned char address, unsigned char maskoff)
{
  i2c_storage_address = address;     // copy the register address
  i2c_status = I2C_BUSY;             // I2C is now busy
  i2c_operation = READ;              // read operation is being performed
  i2c_state = DUMMY_WRITE;           // initially a dummy write has to be
                                     // performed to set the register address
  S1CON = 0x40;                      // enable the I2C peripheral
                                     // no acknowledgements will be returned
  STA = 1;                           // request a start condition is transmitted
                                     // therefore putting I2C peripheral in Master Transmitter mode
  while(i2c_status == I2C_BUSY);     // wait until I2C is no longer busy
  if (maskoff) i2c_byte &= mask[address];  // mask result if required
  return bcdtochar(i2c_byte);        // convert to decimal and return result
}
*/

/*
// function start_timer
// sets up and starts timer 0 - start of timeout period
// nothing is passed. nothing is returned
void start_timer(void)
{
  TL0 = TIMEOUT & 0xFF;              // set up timer 0 reload value
  TH0 = (TIMEOUT >> 8) & 0xFF;
  TR0 = 1;                           // start timer 0
}

// function stop_timer
// stops timer 0 and clears overflow flag
// nothing is passed. nothing is returned
void stop_timer(void)
{
  TR0 = 0;                           // stop timer 0
  TF0 = 0;                           // clear overflow flag
}

*/
 /*
// function i2c_isr
// I2C interrupt service routine
// the interrupt is triggered on each I2C event. The I2C peripheral state
// is stored in the S1STA SFR
// different actions are performed depending on the peripheral state
// nothing is passed. nothing is returned.
// Note: if debugging printfs are inserted into this function the execution
// will be slowed down to the point where the timeout occurs.
void i2c_isr(void) interrupt 5 using 1
{
  switch(S1STA)
  {
    // START CONDITION TRANSMITTED
    case 0x08:
      STA = 0;                       // clear flag so another start condition is not transmitted
	  start_timer();                 // start timer to measure timeout period
      S1DAT = RTC_ADDRESS & 0xFE;    // transmit Slave Address + Write command (SLA + W)
      break;
	// REPEATED START CONDITION TRANSMITTED
    case 0x10:
      STA = 0;                       // clear flag so another start condition is not transmitted
      if (i2c_operation == READ && i2c_state != DUMMY_WRITE)  // if performing a read and we have completed the dummy write then...
	  {
	    S1DAT = RTC_ADDRESS | 0x01;  // transmit Slave Address + Read command (SLA + R)
  	  }
	  else
	  {
        S1DAT = RTC_ADDRESS & 0xFE;  // transmit Slave Address + Write command (SLA + W)
		                             // this situation arises when no response was received from the
									 // Real Time Clock and another attempt is being made
      }
      break;
	// SLAVE ADDRESS + WRITE TRANSMITTED - ACK RECEIVED
    case 0x18:
	  stop_timer();                  // stop timer - response was received within the timeout period
      S1DAT = i2c_storage_address;   // transmit the register address
      i2c_state = DATA_BYTE;         // next byte to be sent is the data byte
	  break;
	// SLAVE ADDRESS + WRITE TRANSMITTED - NO ACK RECEIVED
    case 0x20:
	  if (TF0)                       // if timer 0 has overflowed then timeout period has been reached
	  {
	    STO = 1;                     // request to transmit a stop condition - give up attempt to communicate
		stop_timer();                // stop timer 0
		i2c_status = I2C_ERROR;      // status of operation is an error
	  }
	  else                           // still trying to communicate. The timeout period has not been reached
	  {
        STA = 1;                     // request to transmit a repeated start condition
	  }
      break;
	// DATA BYTE OR REGISTER ADDRESS TRANSMITTED - ACK RECEIVED
    case 0x28:
      switch(i2c_state)
      {
        case DATA_BYTE:              // next byte to be transmitted is the data byte
		  if (i2c_operation == READ) // if reading then this is the end of the dummy write
		                             // no date byte is transmitted
		  {
		    STA = 1;                 // request to transmit repeated start condition. This will start off the read cycle
		  }
		  else
		  {
            S1DAT = i2c_byte;        // transmit data byte
            i2c_state = FINISHED;    // next time around in this state we are finished
		  }
          break;
        case FINISHED:               // data byte has been successfully transmitted
         STO = 1;                    // request to transmit a stop condition
         i2c_status = I2C_OK;        // status of operation is OK
         break;
      }
	  break;
	// DATA BYTE OR REGISTER ADDRESS TRANSMITTED - NO ACK RECEIVED
	case 0x30:
	  STO = 1;                       // no response from Real Time Clock. Request to transmit a stop condition
	                                 // we could invoke another timeout period here if desired
	  i2c_status = I2C_ERROR;        // status of operation is ERROR
      break;
	// SLAVE ADDRESS + READ TRANSMITTED - ACK RECEIVED
	case 0x40:
	  break;                         // don't do anything. Next time around a data byte will be received
	// SLAVE ADDRESS + READ TRANSMITTED - NO ACK RECEIVED
	case 0x48:
	  STO = 1;                       // no response from Real Time Clock. Request to transmit a stop condition
	  i2c_status = I2C_ERROR;        // status of operation is ERROR
      break;
	// DATA BYTE RECEIVED - NO ACK RETURNED
    case 0x58:
      i2c_byte = S1DAT;              // data byte has been received from the Real Time Clock
	                                 // no ack was returned as per the datasheet
	  i2c_status = I2C_OK;           // status of operation is OK
      STO = 1;                       // request to transmit a stop condition
 	  break;
	// UNKNOWN STATE
    default:
	  STO = 1;                       // I2C peripheral is in a state not anticipated. Request to
	                                 // transmit a stop condition
	  i2c_status = I2C_ERROR;        // status of operation is ERROR
	  ES1 = 0;                       // disable I2C interrupts
	  break;
  }
  SI = 0;                            // clear I2C interrupt flag. This will initiate
                                     // another operation on the I2C bus and possibly
									 // another I2C interrupt being requested
}
	*/

⌨️ 快捷键说明

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