久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 4834|回復(fù): 0
收起左側(cè)

LPC11xx讀寫(xiě)AT24C04主模式400KHz程序

[復(fù)制鏈接]
ID:73735 發(fā)表于 2015-2-18 23:06 | 顯示全部樓層 |閱讀模式
IIC.c文件:
/*****************************************************************************
*   i2c.c:  I2C C file for NXP LPC11xx Family Microprocessors
*
*   Copyright(C) 2008, NXP Semiconductor
*   All rights reserved.
*
*   History
*   2008.07.19  ver 1.00    Preliminary version, first Release
*
*****************************************************************************/
#include "LPC11xx.h"                        /* LPC11xx Peripheral Registers */
#include "type.h"
#include "i2c.h"
#include "Delay.h"

volatile uint32_t I2CMasterState = I2C_IDLE;
volatile uint32_t I2CSlaveState = I2C_IDLE;

volatile uint32_t I2CMode;

volatile uint8_t  I2CMasterBuffer[I2C_BUFSIZE]={0};
volatile uint8_t  I2CSlaveBuffer[I2C_BUFSIZE] ={0};
volatile uint32_t I2CReadLength;
volatile uint32_t I2CWriteLength;

volatile uint32_t RdIndex = 0;
volatile uint32_t WrIndex = 0;

/*
From device to device, the I2C communication protocol may vary,
in the example below, the protocol uses repeated start to read data from or
write to the device:
For master read: the sequence is: STA,Addr(W),offset,RE-STA,Addr(r),data...STO
for master write: the sequence is: STA,Addr(W),offset,RE-STA,Addr(w),data...STO
Thus, in state 8, the address is always WRITE. in state 10, the address could
be READ or WRITE depending on the I2C command.
*/   

/*****************************************************************************
** Function name:                I2C_IRQHandler
**
** Descriptions:                I2C interrupt handler, deal with master mode only.
**
** parameters:                        None
** Returned value:                None
**
*****************************************************************************/
void I2C_IRQHandler(void)
{
  uint8_t StatValue;

  /* this handler deals with master read and master write only */
  StatValue = LPC_I2C->STAT;
  switch ( StatValue )
  {
/**************** Master write **********************************/
               
          case 0x08:                        /* A Start condition is issued. */
          WrIndex = 0;
          LPC_I2C->DAT = I2CMasterBuffer[WrIndex++];
          LPC_I2C->CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC);
          I2CMasterState = I2C_STARTED;
          break;
       
          case 0x10:                        /* A repeated started is issued */
          WrIndex = 0;
          /* Send SLA with R bit set, */
          LPC_I2C->DAT = I2CMasterBuffer[WrIndex++];
          LPC_I2C->CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC);
          I2CMasterState = I2C_RESTARTED;
          break;
       
          case 0x18:                        /* Regardless, it's a ACK */
          if ( I2CMasterState == I2C_STARTED )
          {
            LPC_I2C->DAT = I2CMasterBuffer[WrIndex++];
            I2CMasterState = DATA_ACK;
          }
          LPC_I2C->CONCLR = I2CONCLR_SIC;
          break;
       
          case 0x28:        /* Data byte has been transmitted, regardless ACK or NACK */
          case 0x30:
          if ( WrIndex < I2CWriteLength )
          {   
            LPC_I2C->DAT = I2CMasterBuffer[WrIndex++]; /* this should be the last one */
            I2CMasterState = DATA_ACK;
          }
          else
          {
            if ( I2CReadLength != 0 )
            {
                    LPC_I2C->CONSET = I2CONSET_STA;                 /* Set Repeated-start flag */
                    I2CMasterState = I2C_REPEATED_START;
            }
            else
            {
                    I2CMasterState = DATA_NACK;
                    LPC_I2C->CONSET = I2CONSET_STO;          /* Set Stop flag */
            }
          }
          LPC_I2C->CONCLR = I2CONCLR_SIC;
          break;
               
/**************** Master read *********************************/
               
          case 0x40:        /* Master Receive, SLA_R has been sent */
          LPC_I2C->CONSET = I2CONSET_AA;        /* assert ACK after data is received */
          LPC_I2C->CONCLR = I2CONCLR_SIC;
          break;
       
          case 0x50:        /* Data byte has been received, regardless following ACK or NACK */
          I2CSlaveBuffer[RdIndex++] = LPC_I2C->DAT;
          if ( RdIndex < I2CReadLength )
          {   
            I2CMasterState = DATA_ACK;
          }
          else
          {
            I2CMasterState = DATA_NACK;
          }
          LPC_I2C->CONSET = I2CONSET_AA;        /* assert ACK after data is received */
          LPC_I2C->CONCLR = I2CONCLR_SIC;
          break;
       
          case 0x58:
          I2CSlaveBuffer[RdIndex++] = LPC_I2C->DAT;
          I2CMasterState = DATA_NACK;
          LPC_I2C->CONSET = I2CONSET_STO;        /* Set Stop flag */
          LPC_I2C->CONCLR = I2CONCLR_SIC;        /* Clear SI flag */
          break;

          case 0x20:                /* regardless, it's a NACK */
          case 0x48:
          LPC_I2C->CONCLR = I2CONCLR_SIC;
          I2CMasterState = DATA_NACK;
          break;
       
          case 0x38:                /* Arbitration lost, in this example, we don't
                                        deal with multiple master situation */
          default:
          LPC_I2C->CONCLR = I2CONCLR_SIC;       
          break;
  }
  return;
}

/*****************************************************************************
** Function name:                I2CStart
**
** Descriptions:                Create I2C start condition, a timeout
**                                value is set if the I2C never gets started,
**                                and timed out. It's a fatal error.
**
** parameters:                        None
** Returned value:                true or false, return false if timed out
**
*****************************************************************************/
uint32_t I2CStart( void )
{
  uint32_t timeout = 0;
  uint32_t retVal = FALSE;
  /*--- Issue a start condition ---*/
  LPC_I2C->CONSET = I2CONSET_STA;        /* Set Start flag */

  /*--- Wait until START transmitted ---*/
  while( 1 )
  {
          if ( I2CMasterState == I2C_STARTED )
          {
            retVal = TRUE;
            break;       
          }
          if ( timeout >= MAX_TIMEOUT )
          {
            retVal = FALSE;
            break;
          }
               
          timeout++;
  }
  return( retVal );
}

/*****************************************************************************
** Function name:                I2CStop
**
** Descriptions:                Set the I2C stop condition, if the routine
**                                never exit, it's a fatal bus error.
**
** parameters:                        None
** Returned value:                true or never return
**
*****************************************************************************/
uint32_t I2CStop( void )
{
  LPC_I2C->CONSET = I2CONSET_STO;      /* Set Stop flag */
  LPC_I2C->CONCLR = I2CONCLR_SIC;      /* Clear SI flag */

  /*--- Wait for STOP detected ---*/
  while( LPC_I2C->CONSET & I2CONSET_STO );
  return TRUE;
}

/*****************************************************************************
** Function name:                I2CInit
**
** Descriptions:                Initialize I2C controller
**
** parameters:                        I2c mode is either MASTER or SLAVE
** Returned value:                true or false, return false if the I2C
**                                interrupt handler was not installed correctly
**
*****************************************************************************/
uint32_t I2CInit( uint32_t I2cMode )
{
  /* It seems to be bit0 is for I2C, different from
  UM. To be retested along with SSP reset. SSP and I2C
  reset are overlapped, a known bug, for now, both SSP
  and I2C use bit 0 for reset enable. Once the problem
  is fixed, change to "#if 1". */
#if 1
  LPC_SYSCON->PRESETCTRL |= (0x1<<1);
#else
  LPC_SYSCON->PRESETCTRL |= (0x1<<0);
#endif
  //LPC_SYSCON->SYSAHBCLKCTRL |= (1<<5);
  LPC_IOCON->PIO0_4 &= ~0x3F;                   /*  I2C I/O config */
  LPC_IOCON->PIO0_4 |= 0x01;                         /* I2C SCL */
  LPC_IOCON->PIO0_5 &= ~0x3F;                   /*  I2C I/O config */
  LPC_IOCON->PIO0_5 |= 0x01;                         /* I2C SDA */

  /*--- Clear flags ---*/
  LPC_I2C->CONCLR = I2CONCLR_AAC | I2CONCLR_SIC | I2CONCLR_STAC | I2CONCLR_I2ENC;   

  /*--- Reset registers ---*/
#if FAST_MODE_PLUS
  LPC_IOCON->PIO0_4 |= (0x1<<9);
  LPC_IOCON->PIO0_5 |= (0x1<<9);
  LPC_I2C->SCLL   = I2SCLL_HS_SCLL;
  LPC_I2C->SCLH   = I2SCLH_HS_SCLH;
#else
  LPC_I2C->SCLL   = I2SCLL_SCLL;
  LPC_I2C->SCLH   = I2SCLH_SCLH;
#endif

  if ( I2cMode == I2CSLAVE )
  {
          LPC_I2C->ADR0 = AT24C_ADDR;
  }
       
  NVIC_EnableIRQ(I2C_IRQn);             /* Enable the I2C Interrupt */
  LPC_I2C->CONSET = I2CONSET_I2EN;      /* Enable I2C */
       
  return( TRUE );
}

/*****************************************************************************
**I2C_SendOneByte()啟動(dòng)I2C發(fā)送一個(gè)數(shù)據(jù),Addr為從機(jī)地址,Data為將要發(fā)送的數(shù)據(jù)****
*****************************************************************************/
uint32_t I2C_SendOneByte(uint8_t Addr, uint8_t Data)
{
        /* Write SLA(W), address and one data byte */
  I2CWriteLength = 2;
  I2CReadLength  = 0;
  I2CMasterBuffer[0] = Addr;              /* Address Data and Write Bit */
  I2CMasterBuffer[1] = Data;              /* Data 0 */
       
        do                                      /*發(fā)送起始條件,直到起始條件成功發(fā)送,順利接管總線*/
        {
                ;
        }
        while(I2CStart() == FALSE);
       
        while (1)
  {
          if ( I2CMasterState == DATA_NACK )
          {
            I2CStop();
            break;
          }
  }
  return ( TRUE );
}

/******************************************************************************************************
**I2C_SendOneByte()啟動(dòng)I2C發(fā)送多個(gè)數(shù)據(jù),Addr為從機(jī)地址,Num為要發(fā)送的數(shù)據(jù)個(gè)數(shù),pdata為數(shù)據(jù)首字節(jié)地址指針**
******************************************************************************************************/
uint32_t I2C_SendNumByte(uint8_t Addr, uint8_t Num, uint8_t *pdata)
{
        uint8_t x=0;
        /* Write SLA(W), address and one data byte */
  I2CWriteLength = Num+1;
  I2CReadLength  = 0;
  I2CMasterBuffer[0] = Addr;                        /* Address Data and Write Bit*/
       
        for(x=0;x<Num;x++)
        {
                I2CMasterBuffer[x+1] = pdata[x];                /* Data */
        }
       
        do                             /*發(fā)送起始條件,直到起始條件成功發(fā)送,順利接管總線*/
        {
                ;
        }
        while(I2CStart() == FALSE);
       
        while (1)
  {
          if ( I2CMasterState == DATA_NACK )
          {
            I2CStop();
            break;
          }
  }
  return ( TRUE );
}
/*****************************************************************************
****I2C_ReadByte()啟動(dòng)I2C讀取多個(gè)數(shù)據(jù),Addr為從機(jī)地址,Num為要發(fā)送的數(shù)據(jù)個(gè)數(shù)
*****************************************************************************/
uint32_t I2C_ReadByte(uint32_t Num)
{
        I2CWriteLength = 1;
  I2CReadLength  = Num;
        I2CMasterBuffer[0] = AT24C_ADDR|READ_BIT;     /*Address Data and Write Bit*/
       
        do                                            /*發(fā)送起始條件,直到起始條件成功發(fā)送,接管總線*/
        {
                ;
        }
        while(I2CStart() == FALSE);
       
        while ( 1 )
  {
          if ( I2CMasterState == DATA_NACK )
          {
            I2CStop();
            break;
          }
  }
  return ( TRUE );
}

/*****************************************************************************
** 以下為AT24C04驅(qū)動(dòng)程序**
*****************************************************************************/
uint32_t AT24C04_ByteWrite(uint8_t Page,uint8_t WordAddr,uint8_t Data)
{
        /* Write SLA(W), DeviceAddress+Page and one data byte */
  I2CWriteLength = 3;
  I2CReadLength  = 0;
  I2CMasterBuffer[0] = AT24C_ADDR|Page|WRITE_BIT;       /* DeviceAddress Data+Page and Write Bit*/
  I2CMasterBuffer[1] = WordAddr;                        /* Word Address*/
        I2CMasterBuffer[2] = Data;                            /* Data */
       
        do                                                    /*發(fā)送起始條件,直到起始條件成功發(fā)送,順利接管總線*/
        {
                ;
        }
        while(I2CStart() == FALSE);
       
        while (1)
  {
          if ( I2CMasterState == DATA_NACK )
          {
            I2CStop();
            break;
          }
  }
  return ( TRUE );
}
/************************************************************************************************/
/* the microcontroller can transmit up to seven(1K/2K) or fifteen (4K, 8K, 16K) more data words.*/
/************************************************************************************************/
uint32_t AT24C04_PageWrite(uint8_t Page,uint8_t WordAddr,uint32_t Num,uint8_t *pdata)
{
        uint8_t x=0;
        if(Num>16)
        {
                Num=16;
        }
        /* Write SLA(W), DeviceAddress+Page and one data byte */
  I2CWriteLength = Num+2;
  I2CReadLength  = 0;
  I2CMasterBuffer[0] = AT24C_ADDR|Page|WRITE_BIT;       /* DeviceAddress Data+Page and Write Bit*/
  I2CMasterBuffer[1] = WordAddr;              /* Word Address*/
        for(x=0;x<=Num;x++)
        {
                I2CMasterBuffer[x+2] = pdata[x];          /* Data */
        }
       
        do                                          /*發(fā)送起始條件,直到起始條件成功發(fā)送,順利接管總線*/
        {
                ;
        }
        while(I2CStart() == FALSE);
       
        while (1)
  {
          if ( I2CMasterState == DATA_NACK )
          {
            I2CStop();
            break;
          }
  }
  return ( TRUE );
}

/*****************************************************************************
**AT24C04_CurrAdrRead(),參數(shù)Page為0或者1,以選擇所讀取的頁(yè)面*******************
**Word Address保持上次讀寫(xiě)操作所用的Word Address地址,并自增1*****************
*****************************************************************************/
uint32_t AT24C04_CurrAdrRead(uint8_t Page)
{
        I2CWriteLength = 1;
  I2CReadLength  = 1;
        I2CMasterBuffer[0] = AT24C_ADDR|Page|READ_BIT;     /*DeviceAddress Data and Write Bit*/
       
        do                                            /*發(fā)送起始條件,直到起始條件成功發(fā)送,接管總線*/
        {
                ;
        }
        while(I2CStart() == FALSE);
       
        while ( 1 )
  {
          if ( I2CMasterState == DATA_NACK )
          {
            I2CStop();
            break;
          }
  }
  return ( TRUE );
}

/*******************************************************************************************
**AT24C04_RandomRead(),參數(shù)Page為0或者1,以選擇所讀取的頁(yè)面,WordAddr為所選取頁(yè)面的字節(jié)地址**
*******************************************************************************************/
uint32_t AT24C04_RandomRead(uint8_t Page,uint8_t WordAddr)
{
        /* Write SLA(W), address+Page and one data byte */
  I2CWriteLength = 2;
  I2CReadLength  = 1;
  I2CMasterBuffer[0] = AT24C_ADDR|Page|WRITE_BIT;   /* DeviceAddress Data+Page and Write Bit*/
  I2CMasterBuffer[1] = WordAddr;                    /* Word Address*/
       
        do                                                /*發(fā)送起始條件,直到起始條件成功發(fā)送,順利接管總線*/
        {
                ;
        }
        while(I2CStart() == FALSE);                       /* 接管總線后,發(fā)送DeviceAddress和WoraAddress */
       
        while (1)
  {
          if ( I2CMasterState == I2C_REPEATED_START )
          {
                        I2CWriteLength = 1;
      I2CMasterBuffer[0] = AT24C_ADDR|Page|READ_BIT;     /* DeviceAddress Data+Page and Write Bit*/
                       
                        while ( 1 )
      {
              if ( I2CMasterState == DATA_NACK )
              {
                I2CStop();
                break;
              }
      }
      return ( TRUE );
          }
  }
}

/*******************************************************************************************
**AT24C04_SequRead(),參數(shù)Page為0或者1,以選擇所讀取的頁(yè)面,Num為讀出的字節(jié)個(gè)數(shù)***************
*******************************************************************************************/
uint32_t AT24C04_SequRead(uint8_t Page,uint32_t Num)
{
        I2CWriteLength = 1;
  I2CReadLength  = Num;
        I2CMasterBuffer[0] = AT24C_ADDR|Page|READ_BIT;     /*DeviceAddress Data and Write Bit*/
       
        do                                            /*發(fā)送起始條件,直到起始條件成功發(fā)送,接管總線*/
        {
                ;
        }
        while(I2CStart() == FALSE);
       
        while ( 1 )
  {
          if ( I2CMasterState == DATA_NACK )
          {
            I2CStop();
            break;
          }
  }
  return ( TRUE );
}

/******************************************************************************
**                            End Of File
******************************************************************************/


IIC.h文件:
/*****************************************************************************
*   i2c.h:  Header file for NXP LPC Family Microprocessors
*
*   Copyright(C) 2006, NXP Semiconductor
*   All rights reserved.
*
*   History
*   2006.07.19  ver 1.00    Preliminary version, first Release
*
******************************************************************************/
#ifndef __I2C_H
#define __I2C_H

/* If I2C SEEPROM is tested, make sure FAST_MODE_PLUS is 0.
For board to board test, this flag can be turned on. */

#define FAST_MODE_PLUS               1

#define I2C_BUFSIZE                               6
#define MAX_TIMEOUT                         0x00FFFFFF

#define I2CMASTER                           0x01
#define I2CSLAVE                           0x02

#define I2C_ADDR                     0x80
#define AT24C_ADDR                   0xA0
#define AT24C_Page0                   0x00
#define AT24C_Page1                   0x02

#define WRITE_BIT                           0x00
#define READ_BIT                                 0x01

#define I2C_IDLE                                 0
#define I2C_STARTED                               1
#define I2C_RESTARTED                       2
#define I2C_REPEATED_START           3
#define DATA_ACK                                 4
#define DATA_NACK                                 5

#define I2CONSET_I2EN                       0x00000040  /* I2C Control Set Register */
#define I2CONSET_AA                               0x00000004
#define I2CONSET_SI                               0x00000008
#define I2CONSET_STO                       0x00000010
#define I2CONSET_STA                       0x00000020

#define I2CONCLR_AAC                       0x00000004  /* I2C Control clear Register */
#define I2CONCLR_SIC                       0x00000008
#define I2CONCLR_STAC                       0x00000020
#define I2CONCLR_I2ENC               0x00000040

#define I2DAT_I2C                                 0x00000000  /* I2C Data Reg */
#define I2ADR_I2C                                 0x00000000  /* I2C Slave Address Reg */
#define I2SCLH_SCLH                               0x00000060  /* I2C SCL Duty Cycle High Reg */
#define I2SCLL_SCLL                               0x00000060  /* I2C SCL Duty Cycle Low Reg */
#define I2SCLH_HS_SCLH                      0x00000015  /* Fast Plus I2C SCL Duty Cycle High Reg */
#define I2SCLL_HS_SCLL                      0x00000015  /* Fast Plus I2C SCL Duty Cycle Low Reg */

void I2C_IRQHandler(void);
uint32_t I2CStart( void );
uint32_t I2CStop( void );
uint32_t I2CInit( uint32_t I2cMode );
uint32_t I2CEngine( void );

uint32_t I2C_SendNumByte(uint8_t Addr, uint8_t Num, uint8_t *pdata);
uint32_t I2C_ReadByte(uint32_t Num);

uint32_t AT24C04_ByteWrite(uint8_t Page,uint8_t WordAddr,uint8_t Data);
uint32_t AT24C04_PageWrite(uint8_t Page,uint8_t WordAddr,uint32_t Num,uint8_t *pdata);
uint32_t AT24C04_CurrAdrRead(uint8_t Page);
uint32_t AT24C04_RandomRead(uint8_t Page,uint8_t WordAddr);
uint32_t AT24C04_SequRead(uint8_t Page,uint32_t Num);



#endif /* end __I2C_H */
/****************************************************************************
**                            End Of File
*****************************************************************************/








相關(guān)帖子

回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 日韩一区二区精品 | 国产成人精品综合 | 欧美精品久久久 | 日韩精品久久久久 | 日韩综合| 精品videossex高潮汇编 | 911精品美国片911久久久 | 亚洲三区在线观看 | 国产精品自产拍在线观看蜜 | 久久这里只有精品首页 | 久久99一区二区 | 伊人狠狠 | 欧美久久久网站 | 色综合99 | 天堂视频一区 | 久久久久国产 | 日本亚洲一区 | 亚洲精品在线看 | 日韩一级欧美一级 | 中文字幕一区二区三区日韩精品 | 中文字幕一二三 | 亚洲一区二区高清 | 成人福利在线 | 午夜伦理影院 | 国产1区在线| 91偷拍精品一区二区三区 | 日本在线免费看最新的电影 | 高清视频一区二区三区 | 国产精品一区久久久 | 天天操天天干天天爽 | 96国产精品久久久久aⅴ四区 | h视频在线播放 | 在线国产视频 | 久久精品国产免费看久久精品 | 亚洲视频国产视频 | 亚洲自拍偷拍视频 | 一级免费毛片 | 国产99久久精品一区二区永久免费 | 欧美二区在线 | 91久久精品国产91久久性色tv | 亚洲综合在线播放 |