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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4803|回復: 0
打印 上一主題 下一主題
收起左側

LPC11xx讀寫AT24C04主模式400KHz程序

[復制鏈接]
跳轉到指定樓層
樓主
ID:73735 發表于 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()啟動I2C發送一個數據,Addr為從機地址,Data為將要發送的數據****
*****************************************************************************/
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                                      /*發送起始條件,直到起始條件成功發送,順利接管總線*/
        {
                ;
        }
        while(I2CStart() == FALSE);
       
        while (1)
  {
          if ( I2CMasterState == DATA_NACK )
          {
            I2CStop();
            break;
          }
  }
  return ( TRUE );
}

/******************************************************************************************************
**I2C_SendOneByte()啟動I2C發送多個數據,Addr為從機地址,Num為要發送的數據個數,pdata為數據首字節地址指針**
******************************************************************************************************/
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                             /*發送起始條件,直到起始條件成功發送,順利接管總線*/
        {
                ;
        }
        while(I2CStart() == FALSE);
       
        while (1)
  {
          if ( I2CMasterState == DATA_NACK )
          {
            I2CStop();
            break;
          }
  }
  return ( TRUE );
}
/*****************************************************************************
****I2C_ReadByte()啟動I2C讀取多個數據,Addr為從機地址,Num為要發送的數據個數
*****************************************************************************/
uint32_t I2C_ReadByte(uint32_t Num)
{
        I2CWriteLength = 1;
  I2CReadLength  = Num;
        I2CMasterBuffer[0] = AT24C_ADDR|READ_BIT;     /*Address Data and Write Bit*/
       
        do                                            /*發送起始條件,直到起始條件成功發送,接管總線*/
        {
                ;
        }
        while(I2CStart() == FALSE);
       
        while ( 1 )
  {
          if ( I2CMasterState == DATA_NACK )
          {
            I2CStop();
            break;
          }
  }
  return ( TRUE );
}

/*****************************************************************************
** 以下為AT24C04驅動程序**
*****************************************************************************/
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                                                    /*發送起始條件,直到起始條件成功發送,順利接管總線*/
        {
                ;
        }
        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                                          /*發送起始條件,直到起始條件成功發送,順利接管總線*/
        {
                ;
        }
        while(I2CStart() == FALSE);
       
        while (1)
  {
          if ( I2CMasterState == DATA_NACK )
          {
            I2CStop();
            break;
          }
  }
  return ( TRUE );
}

/*****************************************************************************
**AT24C04_CurrAdrRead(),參數Page為0或者1,以選擇所讀取的頁面*******************
**Word Address保持上次讀寫操作所用的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                                            /*發送起始條件,直到起始條件成功發送,接管總線*/
        {
                ;
        }
        while(I2CStart() == FALSE);
       
        while ( 1 )
  {
          if ( I2CMasterState == DATA_NACK )
          {
            I2CStop();
            break;
          }
  }
  return ( TRUE );
}

/*******************************************************************************************
**AT24C04_RandomRead(),參數Page為0或者1,以選擇所讀取的頁面,WordAddr為所選取頁面的字節地址**
*******************************************************************************************/
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                                                /*發送起始條件,直到起始條件成功發送,順利接管總線*/
        {
                ;
        }
        while(I2CStart() == FALSE);                       /* 接管總線后,發送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(),參數Page為0或者1,以選擇所讀取的頁面,Num為讀出的字節個數***************
*******************************************************************************************/
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                                            /*發送起始條件,直到起始條件成功發送,接管總線*/
        {
                ;
        }
        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
*****************************************************************************/








分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 视频1区 | 欧美日韩在线精品 | 欧美四虎 | www久久99 | 亚洲免费一区二区 | 美女天天干| 欧美日韩18 | 久久亚洲一区二区三区四区 | 国户精品久久久久久久久久久不卡 | 成人在线观看免费 | 在线观看av网站 | 香蕉视频一区二区 | 国产一区二区三区四区 | 久久国产精品一区二区三区 | 亚洲综合精品 | av在线免费不卡 | 91免费视频 | 国产一区二区欧美 | 中文一区| 精品久久久久久久 | 91精品国产综合久久久动漫日韩 | 欧美一级三级在线观看 | 国产亚韩| 在线观看av网站永久 | 久草资源网站 | 福利片在线| 欧美日韩中文字幕 | 成人在线视频网址 | 99精品免费久久久久久日本 | 国产精品久久久久久久久久 | 欧美日韩精品中文字幕 | 日韩在线欧美 | 国产一区免费视频 | 羞羞视频网站在线观看 | 亚洲毛片一区二区 | www.久久久久久久久久久久 | 午夜精品视频在线观看 | www.97国产| 一本大道久久a久久精二百 欧洲一区二区三区 | 自拍中文字幕 | 欧美无乱码久久久免费午夜一区 |