10

I2C串列通訊

10.1 STM32 I2C簡介

1.          I²C使用兩條雙向開放集極(Open Drain),串列資料(SDA)及串列時脈(SCL)並利用電阻將電位上拉。

2.          I²C允許相當大的工作電壓範圍,但典型的電壓準位為+3.3v+5v

3.          SDASCL構成的串列匯流排,可發送和接收資料。在CPU與被控IC之間、ICIC之間進行雙向傳送。

4.          I2C匯流排在傳送資料過程中共有三種類型信號, 它們分別是:START信號、FINISH信號和ACK信號。

STM32F10x處理器I2C結構圖

image001  

image002  

1.          STARTSCLhigh時,SDAhigh變成low,開始傳送資料。

2.          FINISHSCLhigh時,SDAlow變成high,結束傳送資料。

3.          ACK:接收資料的IC在接收到8bit資料後,向發送資料的IC發出特定的低電平脈衝,表示已收到資料。

 

 

 

10.2 I2C Standard Driver Library

 

本節說明ST提供I2C  Standard Driver Library

 

Function name

Description

I2C_DeInit

Resets the I2Cx peripheral registers to their default reset values.

I2C_Init

Initializes the I2Cx peripheral according to the specified

parameters in the I2C_InitStruct.

I2C_StructInit

Fills each I2C_InitStruct member with its default value.

I2C_Cmd

Enables or disables the specified I2C peripheral.

I2C_DMACmd

Enables or disables the specified I2C DMA requests.

I2C_DMALastTransferCmd

Specifies that the next DMA transfer is the last one.

I2C_GenerateSTART

Generates I2Cx communication Start condition.

I2C_GenerateSTOP

Generates I2Cx communication Stop condition.

I2C_ITConfig

Enables or disables the specified I2C interrupts.

I2C_SendData

Sends a data byte through the I2Cx peripheral.

I2C_ReceiveData

Returns the most recent received data by the I2Cx peripheral.

I2C_Send7bitAddress

Transmits the address byte to select the slave device.

I2C_ReadRegister

Reads the specified I2C register and returns its value.

I2C_SoftwareResetCmd

Enables or disables the specified I2C software reset.

I2C_SMBusAlertConfig

Drives the SMBAlert pin high or low for the specified I2C.

I2C_TransmitPEC

Enables or disables the specified I2C PEC transfer.

I2C_PECPositionConfig

Selects the specified I2C PEC position.

I2C_CalculatePEC

Enables or disables the PEC value calculation of the transferred bytes.

I2C_GetPEC

Returns the PEC value for the specified I2C.

I2C_ARPCmd

Enables or disables the specified I2C ARP.

I2C_StretchClockCmd

Enables or disables the specified I2C clock stretching.

I2C_FastModeDutyCycleConfig

Selects the specified I2C fast mode duty cycle.

I2C_GetLastEvent

Returns the last I2Cx event

I2C_CheckEvent

Checks whether the last I2Cx event is equal to the one passed as

parameter.

I2C_GetFlagStatus

Checks whether the specified I2C flag is set or not.

I2C_ClearFlag

Clears the I2Cx’s pending flags.

I2C_GetITStatus

Checks whether the specified I2C interrupt has occurred or not.

I2C_ClearITPendingBit

Clears the I2Cx’s interrupt pending bits.

 

10.2 .1 I2C_Mode

 

I2C_Mode is used to configure the I2C mode. See tablefor the values taken by this

 

member.

 

I2C_Mode

Description

I2C_Mode_I2C

I2C is configured in I2C mode

I2C_Mode_SMBusDevice

I2C is configured in SMBus device mode

I2C_Mode_SMBusHost

I2C is configured in SMBus host mode

 

10.2 .2 I2C_DutyCycle

 

I2C_DutyCycle is used to select the I2C fast mode duty cycle. See for the values

 

taken by this member.

 

I2C_DutyCycle

Description

I2C_DutyCycle_16_9

I2C fast mode Tlow/Thigh=16/9

I2C_DutyCycle_2

I2C fast mode Tlow/Thigh=2

 

 

 

Note: This member is meaningful only when the I2C operates in Fast mode (working clock speed greater than 100 kHz).

 

10.2 .3 I2C_OwnAddress1

 

This member is used to configure the first device own address. It can be a 7-bit or 10-bit

 

address.

 

I2C_OwnAddress1

Description

I2C1_SLAVE_ADDRESS7

This member is used to configure the first device own address.

 

I2C2_SLAVE_ADDRESS7

 

10.2 .4 I2C_Ack

 

I2C_Ack enables or disables the acknowledgement. See for the values taken by

 

this member.

 

I2C_Ack

Description

I2C_Ack_Enable

Enables the acknowledgement

I2C_Ack_Disable

Disables the acknowledgement

 

10.2 .5 I2C_Cmd function

 

describes the I2C_Cmd function.

 

Function name

I2C_Cmd

Function prototype

void I2C_Cmd(I2C_TypeDef* I2Cx, FunctionalState NewState)

Behavior description

Enables or disables the specified I2C peripheral.

Input parameter1

I2Cx: where x can be 1or 2 to select the I2C peripheral.

Input parameter2

NewState: new state of the I2Cx peripheral.

This parameter can be set to ENABLE or DISABLE.

Output parameter

None

Return parameter

None

Required preconditions

None

Called functions

None

 

 

 

Example:

 

/* Enable I2C1 peripheral */

 

I2C_Cmd(I2C1, ENABLE);

 

10.2 .6 I2C_GenerateSTART function

 

describes the I2C_GenerateSTART function.

 

Function name

I2C_GenerateSTART

Function prototype

void I2C_GenerateSTART(I2C_TypeDef* I2Cx, FunctionalState

NewState)

Behavior description

Generates I2Cx communication Start condition..

Input parameter1

I2Cx: where x can be 1or 2 to select the I2C peripheral.

Input parameter2

NewState: new state of the I2C Start condition generation.

This parameter can be: ENABLE or DISABLE.

Output parameter

None

Return parameter

None

Required preconditions

None

Called functions

None

 

 

 

Example:

 

/* Generate a Start condition on I2C1 */

 

I2C_GenerateSTART(I2C1, ENABLE);

 

10.2 .7 I2C_GenerateSTOP function

 

describes the I2C_GenerateSTOP function.

 

Function name

I2C_GenerateSTOP

Function prototype

void I2C_GenerateSTOP(I2C_TypeDef* I2Cx, FunctionalState

NewState)

Behavior description

Generates I2Cx communication Stop condition.

Input parameter1

I2Cx: where x can be 1or 2 to select the I2C peripheral.

Input parameter2

NewState: new state of the I2C Stop condition generation.

This parameter can be: ENABLE or DISABLE.

Output parameter

None

Return parameter

None

Required preconditions

None

Called functions

None

 

Example:

 

/* Generate a Stop condition on I2C2 */

 

I2C_GenerateSTOP(I2C2, ENABLE);

 

 

 

10.2 .8 I2C_ITConfig function

 

describes the I2C_ITConfig function.

 

Function name

I2C_ITConfig

Function prototype

void I2C_ITConfig(I2C_TypeDef* I2Cx, u16 I2C_IT, FunctionalState

NewState)

Behavior description

Enables or disables the specified I2C interrupts.

Input parameter1

I2Cx: where x can be 1 or 2 to select the I2C peripheral.

Input parameter2

I2C_IT: I2C interrupts sources to be enabled or disabled.

Refer to I2C_IT for more details on the allowed values for this

parameter.

Input parameter3

NewState: new state of the specified I2C interrupts.

This parameter can be set to ENABLE or DISABLE.

Output parameter

None

Return parameter

None

Required preconditions

None

Called functions

None

 

 

 

I2C_IT

 

This parameter enables or disables I2C interrupts. One or a combination of the following

 

values can be used:

 

I2C_IT

Description

I2C_IT_BUF

Buffer interrupt mask

I2C_IT_EVT

Event interrupt mask

I2C_IT_ERR

Error interrupt mask

 

Example:

 

/* Enable I2C2 event and buffer interrupts */

 

I2C_ITConfig(I2C2, I2C_IT_BUF | I2C_IT_EVT, ENABLE);

 

I2C_SendData function

 

describes the I2C_SendData function.

 

Function name

I2C_SendData

Function prototype

void I2C_SendData(I2C_TypeDef* I2Cx, u8 Data)

Behavior description

Sends a data byte through the I2Cx peripheral.

Input parameter1

I2Cx: where x can be 1or 2 to select the I2C peripheral.

Input parameter2

Data: byte to be transmitted.

Output parameter

None

Return parameter

None

Required preconditions

None

Called functions

None

 

 

 

Example:

 

/* Transmit 0x5D byte on I2C2 */

 

I2C_SendData(I2C2, 0x5D);

 

11.2.15 I2C_ReceiveData function

 

describes the I2C_ReceiveData function.

 

Function name

I2C_ReceiveData

Function prototype

u8 I2C_ReceiveData(I2C_TypeDef* I2Cx)

Behavior description

Returns the most recent received data by the I2Cx peripheral.

Input parameter

I2Cx: where x can be 1 or 2 to select the I2C peripheral..

Output parameter

None

Return parameter

Received byte.

Required preconditions

None

Called functions

None

 

 

 

Example:

 

/* Read the received byte on I2C1 */

 

u8 ReceivedData;

 

ReceivedData = I2C_ReceiveData(I2C1);

 

10.3實例演練

 

實驗一 SIOC使用I2C通訊介面傳收資料

 

實驗說明:如何使用interruptI2C_1(master)能傳送data I2C_2(slave),其中使用7 bits address模式,clock rate200KHz

 

主要程式碼說明

 

I2C main.c程式碼

 

/* Includes ------------------------------------------------------------------*/

 

#include "stm32f10x.h"

 

#include "stdio.h"

 

#include "string.h"

 

#include "hw_config.h"

 

#include "stm32f10x_i2c.h"

 

/* Private typedef -----------------------------------------------------------*/

 

typedef enum {FAILED = 0, PASSED = !FAILED} TestStatus;

 

 

 

/* Private define ------------------------------------------------------------*/

 

#define I2C1_SLAVE_ADDRESS7   0x30

 

#define I2C2_SLAVE_ADDRESS7   0x30

 

#define BufferSize            4

 

#define ClockSpeed            200000 // 200 KHz

 

#define I2C1_EV_IRQChannel           ((u8)0x1F)  /* I2C1 Event Interrupt */

 

#define I2C1_ER_IRQChannel           ((u8)0x20)  /* I2C1 Error Interrupt */

 

#define I2C2_EV_IRQChannel           ((u8)0x21)  /* I2C2 Event Interrupt */

 

#define I2C2_ER_IRQChannel           ((u8)0x22)  /* I2C2 Error Interrupt */

 

 

 

/* Private variables ---------------------------------------------------------*/

 

I2C_InitTypeDef  I2C_InitStructure;

 

u8 I2C1_Buffer_Tx[BufferSize] = {1,2,3,4};

 

u8 I2C2_Buffer_Rx[BufferSize];

 

vu8 Tx_Idx = 0, Rx_Idx = 0, PEC_Value = 0;

 

volatile TestStatus TransferStatus = FAILED;

 

/* Private functions ---------------------------------------------------------*/

 

void Delay(vu32 nCount);

 

void GPIO_Configuration(void);

 

void NVIC_Configuration(void);

 

TestStatus Buffercmp(u8* pBuffer1, u8* pBuffer2, u16 BufferLength);

 

 

 

/*******************************************************************************

 

* Function Name  : main.

 

* Description    : Main routine.

 

* Input          : None.

 

* Output         : None.

 

* Return         : None.

 

*******************************************************************************/

 

int main(void)

 

{

 

  int temp;

 

  Set_System();

 

  getchar();

 

 

 

  NVIC_Configuration();

 

  GPIO_Configuration();

 

 

 

  /* I2C1 configuration ------------------------------------------------------*/

 

 

 

  I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;                          // I2C模式

 

  I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;        //快速模式下的選項,100KHZ以上才有用

 

  I2C_InitStructure.I2C_OwnAddress1 = I2C1_SLAVE_ADDRESS7;       //slave address長度

 

  I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;            //每次都會回送ACK

 

  I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;

 

  I2C_InitStructure.I2C_ClockSpeed = ClockSpeed;        // I2C 速度配置,這個範例是200KHz,一般是40KHZ400KHZ是極限,一般到不了那麼高

 

  I2C_Init(I2C1, &I2C_InitStructure);

 

  printf("I2C1 configuration\r\n");

 

 

 

  /* I2C2 configuration ------------------------------------------------------*/

 

 

 

  I2C_InitStructure.I2C_OwnAddress1 = I2C2_SLAVE_ADDRESS7;

 

  I2C_Init(I2C2, &I2C_InitStructure);

 

  printf("I2C2 configuration\r\n");

 

 

 

 

 

  /*----- Transmission Phase -----*/

 

  /* Send I2C1 START condition */

 

 

 

  /* Enable I2C1 and I2C2 event and buffer interrupt */

 

  I2C_ITConfig(I2C1, I2C_IT_EVT | I2C_IT_BUF, ENABLE);

 

  I2C_ITConfig(I2C2, I2C_IT_EVT | I2C_IT_BUF, ENABLE);

 

  /* Enable I2C1 and I2C2 ----------------------------------------------------*/

 

  I2C_Cmd(I2C1, ENABLE);

 

  I2C_Cmd(I2C2, ENABLE);

 

 

 

  I2C_GenerateSTART(I2C1, ENABLE);

 

  printf("Send I2C1 START condition\r\n");

 

  /* Send data */

 

 

 

 

 

  while(Rx_Idx < (BufferSize+1))

 

  {

 

       

 

  }

 

 

 

  /* Check the corectness of written data */

 

  printf("Check the corectness of written data\r\n");

 

  TransferStatus = Buffercmp(I2C1_Buffer_Tx, I2C2_Buffer_Rx, BufferSize);

 

  printf("Buffercmp Finish\r\n");

 

 

 

  /* TransferStatus = PASSED, if the transmitted and received data are equal */

 

  /* TransferStatus = FAILED, if the transmitted and received data are different */

 

 

 

  if(TransferStatus) printf("Transmission SUCESS\r\n");

 

  else printf("Transmission FAILED\r\n"); 

 

  while(1)

 

  {

 

               

 

        }

 

 

/*******************************************************************************

 

* Function Name  : Delay

 

* Description    : Inserts a delay time.

 

* Input          : nCount: specifies the delay time length.

 

* Output         : None

 

* Return         : None

 

*******************************************************************************/

 

void Delay(vu32 nCount)

 

{

 

  for(; nCount != 0; nCount--);

 

}

 

/*******************************************************************************

 

* Function Name  : GPIO_Configuration

 

* Description    : Configures the different GPIO ports.

 

* Input          : None

 

* Output         : None

 

* Return         : None

 

*******************************************************************************/

 

void GPIO_Configuration(void)

 

{

 

  GPIO_InitTypeDef GPIO_InitStructure;

 

 

 

  /* Configure I2C1 pins: SCL and SDA ----------------------------------------*/

 

 

 

  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6 | GPIO_Pin_7 |GPIO_Pin_10 | GPIO_Pin_11;

 

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

 

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;

 

  GPIO_Init(GPIOB, &GPIO_InitStructure);

 

  GPIO_Init(GPIOB, &GPIO_InitStructure);

 

 

 

 

 

 }

 

 

 

/*******************************************************************************

 

* Function Name  : NVIC_Configuration

 

* Description    : Configures NVIC and Vector Table base location.

 

* Input          : None

 

* Output         : None

 

* Return         : None

 

*******************************************************************************/

 

void NVIC_Configuration(void)

 

{

 

  NVIC_InitTypeDef NVIC_InitStructure;

 

 

 

#ifdef  VECT_TAB_RAM 

 

  /* Set the Vector Table base location at 0x20000000 */

 

  NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);

 

#else  /* VECT_TAB_FLASH  */

 

  /* Set the Vector Table base location at 0x08000000 */

 

  NVIC_SetVectorTable(0x8003000, 0x0);  

 

#endif

 

 

 

  /* 1 bit for pre-emption priority, 3 bits for subpriority */

 

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);

 

  

 

  /* Configure and enable I2C1 interrupt -------------------------------------*/

 

  NVIC_InitStructure.NVIC_IRQChannel = I2C1_EV_IRQChannel;

 

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

 

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

 

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

 

  NVIC_Init(&NVIC_InitStructure);

 

 

 

  /* Configure and enable I2C2 interrupt -------------------------------------*/ 

 

  NVIC_InitStructure.NVIC_IRQChannel = I2C2_EV_IRQChannel;

 

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

 

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

 

  NVIC_Init(&NVIC_InitStructure);

 

}

 

 

 

/*******************************************************************************

 

* Function Name  : Buffercmp

 

* Description    : Compares two buffers.

 

* Input          : - pBuffer1, pBuffer2: buffers to be compared.

 

*                : - BufferLength: buffer's length

 

* Output         : None

 

* Return         : PASSED: pBuffer1 identical to pBuffer2

 

*                  FAILED: pBuffer1 differs from pBuffer2

 

*******************************************************************************/

 

TestStatus Buffercmp(u8* pBuffer1, u8* pBuffer2, u16 BufferLength)

 

{

 

  while(BufferLength--)

 

  {

 

    if(*pBuffer1 != *pBuffer2)

 

    {

 

      return FAILED;

 

    }

 

   

 

    pBuffer1++;

 

    pBuffer2++;

 

  }

 

 

 

  return PASSED; 

 

}

 

I2C 中斷stm32f10x_it.c程式碼

 

/* Includes ------------------------------------------------------------------*/

 

#include "stm32f10x_it.h"

 

#include "stm32f10x_i2c.h"

 

#include "usb_lib.h"

 

#include "usb_istr.h"

 

#include "hw_config.h"

 

 

 

/* Private typedef -----------------------------------------------------------*/

 

/* Private define ------------------------------------------------------------*/

 

/* Private macro -------------------------------------------------------------*/

 

#define BufferSize 4

 

#define I2C2_SLAVE_ADDRESS7   0x30

 

/* Private variables ---------------------------------------------------------*/

 

extern vu8 Tx_Idx, Rx_Idx, PEC_Value, DataToTransfer;

 

extern u8 I2C1_Buffer_Tx[], I2C2_Buffer_Rx[];

 

/* Private function prototypes -----------------------------------------------*/

 

/* Private functions ---------------------------------------------------------*/

 

/******************************************************************************/

 

/*            Cortex-M3 Processor Exceptions Handlers                         */

 

/******************************************************************************/

 

 

 

 

 

#ifndef STM32F10X_CL

 

/*******************************************************************************

 

* Function Name  : USB_LP_CAN1_RX0_IRQHandler

 

* Description    : This function handles USB Low Priority or CAN RX0 interrupts

 

*                  requests.

 

* Input          : None

 

* Output         : None

 

* Return         : None

 

*******************************************************************************/

 

void USB_LP_CAN1_RX0_IRQHandler(void)

 

{

 

  USB_Istr();

 

}

 

#endif /* STM32F10X_CL */

 

 

 

#if defined (USE_STM3210B_EVAL) || defined (USE_STM3210E_EVAL)

 

/*******************************************************************************

 

* Function Name  : USART1_IRQHandler

 

* Description    : This function handles USART1 global interrupt request.

 

* Input          : None

 

* Output         : None

 

* Return         : None

 

*******************************************************************************/

 

void USART1_IRQHandler(void)

 

{

 

  if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)

 

  {

 

    /* Send the received data to the PC Host*/

 

    USART_To_USB_Send_Data();

 

  }

 

 

 

  /* If overrun condition occurs, clear the ORE flag and recover communication */

 

  if (USART_GetFlagStatus(USART1, USART_FLAG_ORE) != RESET)

 

  {

 

    (void)USART_ReceiveData(USART1);

 

  }

 

}

 

#endif /* USE_STM3210B_EVAL or USE_STM3210E_EVAL */

 

 

 

#ifdef USE_STM3210C_EVAL

 

/*******************************************************************************

 

* Function Name  : USART2_IRQHandler

 

* Description    : This function handles USART2 global interrupt request.

 

* Input          : None

 

* Output         : None

 

* Return         : None

 

*******************************************************************************/

 

void USART2_IRQHandler(void)

 

{

 

  if (USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)

 

  {

 

    /* Send the received data to the PC Host*/

 

    USART_To_USB_Send_Data();

 

  }

 

 

 

  /* If overrun condition occurs, clear the ORE flag and recover communication */ 

 

  if (USART_GetFlagStatus(USART2, USART_FLAG_ORE) != RESET)

 

  {

 

    (void)USART_ReceiveData(USART2);

 

  }

 

}

 

#endif /* USE_STM3210C_EVAL */

 

 

 

#ifdef STM32F10X_CL

 

/*******************************************************************************

 

* Function Name  : OTG_FS_IRQHandler

 

* Description    : This function handles USB-On-The-Go FS global interrupt request.

 

* Input          : None

 

* Output         : None

 

* Return         : None

 

*******************************************************************************/

 

void OTG_FS_IRQHandler(void)

 

{

 

  STM32_PCD_OTG_ISR_Handler();

 

}

 

#endif /* STM32F10X_CL */

 

 

 

/*******************************************************************************

 

* Function Name  : I2C1_EV_IRQHandler

 

* Description    : This function handles I2C1 Event interrupt request.

 

* Input          : None

 

* Output         : None

 

* Return         : None

 

*******************************************************************************/

 

void I2C1_EV_IRQHandler(void)

 

{

 

       

 

        switch (I2C_GetLastEvent(I2C1))

 

  {

 

    /* Test on I2C1 EV5 and clear it */

 

    case I2C_EVENT_MASTER_MODE_SELECT:              

 

      /* Send I2C2 slave Address for write */

 

      I2C_Send7bitAddress(I2C1, I2C2_SLAVE_ADDRESS7, I2C_Direction_Transmitter);

 

      break;

 

 

 

    /* Test on I2C1 EV6 and first EV8 and clear them */

 

    case I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED:

 

      /* I2C1 and I2C2 PEC Transmission Enable */

 

      I2C_CalculatePEC(I2C1, ENABLE);

 

      I2C_CalculatePEC(I2C2, ENABLE);

 

      /* Send the first data */

 

      I2C_SendData(I2C1, I2C1_Buffer_Tx[Tx_Idx++]);  //EV8 just after EV6

 

      break;

 

 

 

    /* Test on I2C1 EV8 and clear it */

 

    case I2C_EVENT_MASTER_BYTE_TRANSMITTED:         

 

      if(Tx_Idx < BufferSize)

 

      {

 

        /* Send buffer data */

 

        I2C_SendData(I2C1, I2C1_Buffer_Tx[Tx_Idx++]);

 

      }

 

      else

 

      {

 

        /* Disable I2C1 interrupts */

 

        I2C_ITConfig(I2C1, I2C_IT_EVT | I2C_IT_BUF, DISABLE);

 

 

 

        /* Enable Transfer PEC next for I2C1 and I2C2 */

 

        I2C_TransmitPEC(I2C2, ENABLE);

 

        I2C_TransmitPEC(I2C1, ENABLE);

 

      }

 

      break;

 

 

 

    default:

 

      break;

 

  }

 

 }

 

 

 

/*******************************************************************************

 

* Function Name  : I2C1_ER_IRQHandler

 

* Description    : This function handles I2C1 Error interrupt request.

 

* Input          : None

 

* Output         : None

 

* Return         : None

 

*******************************************************************************/

 

void I2C1_ER_IRQHandler(void)

 

{

 

}

 

 

 

/*******************************************************************************

 

* Function Name  : I2C2_EV_IRQHandler

 

* Description    : This function handles I2C2 Event interrupt request.

 

* Input          : None

 

* Output         : None

 

* Return         : None

 

*******************************************************************************/

 

void I2C2_EV_IRQHandler(void)

 

{

 

 

 

        switch (I2C_GetLastEvent(I2C2))

 

    {

 

    /* Test on I2C2 EV1 and clear it */

 

    case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED:  

 

      break;

 

 

 

    /* Test on I2C2 EV2 and clear it */

 

    case I2C_EVENT_SLAVE_BYTE_RECEIVED:             

 

      if (Rx_Idx < BufferSize)

 

      {

 

        /* Store received data buffer */

 

        I2C2_Buffer_Rx[Rx_Idx++] = I2C_ReceiveData(I2C2);

 

      }

 

      else

 

      {

 

        /* Store received PEC value */

 

        PEC_Value = I2C_ReceiveData(I2C2);

 

        Rx_Idx++;

 

        /* Send I2C1 STOP Condition */

 

        I2C_GenerateSTOP(I2C1, ENABLE);

 

      }    

 

      break;

 

 

 

    /* Test on I2C2 EV4 and clear it */

 

    case I2C_EVENT_SLAVE_STOP_DETECTED:             

 

      /* Clear STOPF flag */

 

      I2C_ClearFlag(I2C2, I2C_FLAG_STOPF);

 

      /* Disable I2C2 interrupts */

 

      I2C_ITConfig(I2C2, I2C_IT_EVT | I2C_IT_BUF, DISABLE);

 

      break;

 

 

 

     default:

 

      break;

 

  }

 

}

 

 

 

/*******************************************************************************

 

* Function Name  : I2C2_ER_IRQHandler

 

* Description    : This function handles I2C2 Error interrupt request.

 

* Input          : None

 

* Output         : None

 

* Return         : None

 

*******************************************************************************/

 

void I2C2_ER_IRQHandler(void)

 

{

 

}

 

 

 

 

 

 

 

接線示意圖

image003  

實驗結果

image004  

實驗二 可變資料筆數的傳收

實驗說明:如何使用interrupt讓能傳送使用者指定多少筆數目的dataI2C_2,其中使用7 bits address模式,clock rate200KHz。接續實驗一的設定,修改main.cI2C 中斷stm32f10x_it.c程式碼

 

主要程式碼說明

I2C main.c程式碼

int main(void)

{

  u8 num;

  Set_System();

  getchar();

 

  NVIC_Configuration();

  GPIO_Configuration();

  printf("How many data do you want to send\r\n");

  scanf("%d", &num);

 

  DataSize = num;

  printf("DataSize %d\r\n", DataSize);

  /* I2C1 configuration ------------------------------------------------------*/

 

  I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;                          // I2C模式

  I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;        //快速模式下的選項,100KHZ以上才有用

  I2C_InitStructure.I2C_OwnAddress1 = I2C1_SLAVE_ADDRESS7;       //slave address長度

  I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;                                    //每次都會回送ACK

  I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;

  I2C_InitStructure.I2C_ClockSpeed = ClockSpeed;        // I2C 速度配置,這個範例是200KHz,一般是40KHZ400KHZ是極限,一般到不了那麼高

  I2C_Init(I2C1, &I2C_InitStructure);

  printf("I2C1 configuration\r\n");

 

  /* I2C2 configuration ------------------------------------------------------*/

 

  I2C_InitStructure.I2C_OwnAddress1 = I2C2_SLAVE_ADDRESS7;

  I2C_Init(I2C2, &I2C_InitStructure);

  printf("I2C2 configuration\r\n");

 

 

  /*----- Transmission Phase -----*/

  /* Send I2C1 START condition */

 

  /* Enable I2C1 and I2C2 event and buffer interrupt */

  I2C_ITConfig(I2C1, I2C_IT_EVT | I2C_IT_BUF, ENABLE);

  I2C_ITConfig(I2C2, I2C_IT_EVT | I2C_IT_BUF, ENABLE);

  /* Enable I2C1 and I2C2 ----------------------------------------------------*/

  I2C_Cmd(I2C1, ENABLE);

  I2C_Cmd(I2C2, ENABLE);

 

  I2C_GenerateSTART(I2C1, ENABLE);

  printf("Send I2C1 START condition\r\n");

  /* Send data */

 

  //修改部分

  while(Rx_Idx < (num+1))

  {

       

  }

 

  /* Check the corectness of written data */

  printf("Check the corectness of written data\r\n");

  TransferStatus = Buffercmp(I2C1_Buffer_Tx, I2C2_Buffer_Rx, num);

  printf("Buffercmp Finish\r\n");

 

  /* TransferStatus = PASSED, if the transmitted and received data are equal */

  /* TransferStatus = FAILED, if the transmitted and received data are different */

   

  if(TransferStatus) printf("Transmission SUCESS\r\n");

  else printf("Transmission FAILED\r\n"); 

  while(1)

    {

               

        }

I2C 中斷stm32f10x_it.c程式碼

/*******************************************************************************

* Function Name  : I2C1_EV_IRQHandler

* Description    : This function handles I2C1 Event interrupt request.

* Input          : None

* Output         : None

* Return         : None

*******************************************************************************/

void I2C1_EV_IRQHandler(void)

{

        vu8 num;

               

        switch (I2C_GetLastEvent(I2C1))

    {

    /* Test on I2C1 EV5 and clear it */

    case I2C_EVENT_MASTER_MODE_SELECT:              

      /* Send I2C2 slave Address for write */

I2C_Send7bitAddress(I2C1, I2C2_SLAVE_ADDRESS7, I2C_Direction_Transmitter);

      break;

 

    /* Test on I2C1 EV6 and first EV8 and clear them */

    case I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED:

      /* I2C1 and I2C2 PEC Transmission Enable */

      I2C_CalculatePEC(I2C1, ENABLE);

      I2C_CalculatePEC(I2C2, ENABLE);

      /* Send the first data */

          num = Tx_Idx++;

      I2C_SendData(I2C1, I2C1_Buffer_Tx[num]);  //EV8 just after EV6

          printf("Send Data %d...\r\n", I2C1_Buffer_Tx[num]);

      break;

 

    /* Test on I2C1 EV8 and clear it */

    case I2C_EVENT_MASTER_BYTE_TRANSMITTED:         

      if(Tx_Idx < DataSize)

      {

        /* Send buffer data */

                num = Tx_Idx++;

        I2C_SendData(I2C1, I2C1_Buffer_Tx[num]);

                printf("Send Data %d...\r\n", I2C1_Buffer_Tx[num]);

      }

      else

      {

        /* Disable I2C1 interrupts */

        I2C_ITConfig(I2C1, I2C_IT_EVT | I2C_IT_BUF, DISABLE);

               

        /* Enable Transfer PEC next for I2C1 and I2C2 */

        I2C_TransmitPEC(I2C2, ENABLE);

        I2C_TransmitPEC(I2C1, ENABLE);

      }

      break;

 

    default:

      break;

  }

}

 

 

/*******************************************************************************

* Function Name  : I2C2_EV_IRQHandler

* Description    : This function handles I2C2 Event interrupt request.

* Input          : None

* Output         : None

* Return         : None

*******************************************************************************/

void I2C2_EV_IRQHandler(void)

{

 

        switch (I2C_GetLastEvent(I2C2))

    {

    /* Test on I2C2 EV1 and clear it */

    case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED:  

      break;

 

    /* Test on I2C2 EV2 and clear it */

    case I2C_EVENT_SLAVE_BYTE_RECEIVED:             

      if (Rx_Idx < DataSize)

      {

        /* Store received data buffer */

        I2C2_Buffer_Rx[Rx_Idx++] = I2C_ReceiveData(I2C2);

      }

      else

      {

        /* Store received PEC value */

        PEC_Value = I2C_ReceiveData(I2C2);

        Rx_Idx++;

        /* Send I2C1 STOP Condition */

        I2C_GenerateSTOP(I2C1, ENABLE);

      }    

      break;

 

    /* Test on I2C2 EV4 and clear it */

    case I2C_EVENT_SLAVE_STOP_DETECTED:              

      /* Clear STOPF flag */

      I2C_ClearFlag(I2C2, I2C_FLAG_STOPF);

      /* Disable I2C2 interrupts */

      I2C_ITConfig(I2C2, I2C_IT_EVT | I2C_IT_BUF, DISABLE);

      break;

    default:

      break;

  }

}

實驗結果

image005  

 

COM4SPI1結果,COM9SPI2結果

 

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 youboook 的頭像
    youboook

    youboook的部落格

    youboook 發表在 痞客邦 留言(0) 人氣()