STM32F4XX中断方式通过IO模拟I2C总线Master模式

STM32的I2C硬核为了规避NXP的知识产权,使得I2C用起来经常出问题,因此ST公司推出了CPAL库,CPAL库在中断方式工作下仅支持无子地址

的器件,无法做到中断方式完成读写大部分I2C器件。同时CPAL库在多个I2C同时使用时,经测试也有问题,因此我们项目中放弃了使用ST公司的CPAL库以及标准外设库

访问I2c器件,用IO模拟I2c总线,同时也是支持中断方式完成I2C读写。

目前网上绝大部分IO模拟I2c总线的程序都是查询方式,浪费大量CPU周期用于循环等待,本文的程序使用定时器中断推动状态机来模拟I2C总线的操作,

中断方式使用,请定义回调函数,本程序将在读写完成或出错时自动调用回调函数

当然此程序也可以通过查询方式读写I2c总线,仅需查询IIC_BUSY.

 

本程序仅模拟主模式(Master)

i2c_sim.h

#ifndef __I2C_SIM_H__

#define __I2C_SIM_H__



#include <stm32f4xx.h>



#define MAXFREQ 500000



extern uint8_t I2C_Read7(uint8_t IIC, uint8_t device, uint8_t Addr, uint8_t *Buf, uint8_t Count);



extern uint8_t I2C_Read16(uint8_t IIC, uint8_t device, uint16_t Addr, uint8_t *Buf, uint8_t Count);



extern uint8_t I2C_WriteByte7(uint8_t IIC, uint8_t device, uint8_t Addr, uint8_t Data);



extern uint8_t I2C_Write16(uint8_t IIC, uint8_t device, uint16_t Addr, uint8_t *Buf, uint8_t Count);



extern void IIC_Init(uint8_t IIC, uint16_t MicroSecond);



extern void IIC_DeInit(uint8_t IIC);



extern void IIC_SetCallback(uint8_t IIC, void(*OnTx)(void), void(*OnRx)(void) ,void(*OnErr)(void));





#endif

  

 

i2c_sim.c

#include "stm32f4xx_conf.h"

#include <string.h>



#define IIC_COUNT 2



#if (IIC_COUNT>3) 

	Error! To many IIC

#endif



/*----------- I2C1 Device -----------*/

  

#define I2C1_SCL_GPIO_PORT         GPIOB       

#define I2C1_SCL_GPIO_CLK          RCC_AHB1Periph_GPIOB 

#define I2C1_SCL_GPIO_PIN          GPIO_Pin_6

#define I2C1_SCL_GPIO_PINSOURCE    GPIO_PinSource6 

  

#define I2C1_SDA_GPIO_PORT         GPIOB       

#define I2C1_SDA_GPIO_CLK          RCC_AHB1Periph_GPIOB 

#define I2C1_SDA_GPIO_PIN          GPIO_Pin_7 

#define I2C1_SDA_GPIO_PINSOURCE    GPIO_PinSource7 

  

/*-----------I2C2 Device -----------*/

  

#define I2C2_SCL_GPIO_PORT         GPIOA       

#define I2C2_SCL_GPIO_CLK          RCC_AHB1Periph_GPIOA 

#define I2C2_SCL_GPIO_PIN          GPIO_Pin_8

#define I2C2_SCL_GPIO_PINSOURCE    GPIO_PinSource8 



#define I2C2_SDA_GPIO_PORT         GPIOC       

#define I2C2_SDA_GPIO_CLK          RCC_AHB1Periph_GPIOC 

#define I2C2_SDA_GPIO_PIN          GPIO_Pin_9 

#define I2C2_SDA_GPIO_PINSOURCE    GPIO_PinSource9  



/*-----------I2C3 Device -----------*/

  

#define I2C3_SCL_GPIO_PORT         GPIOH

#define I2C3_SCL_GPIO_CLK          RCC_AHB1Periph_GPIOH

#define I2C3_SCL_GPIO_PIN          GPIO_Pin_7

#define I2C3_SCL_GPIO_PINSOURCE    GPIO_PinSource7

  

#define I2C3_SDA_GPIO_PORT         GPIOH

#define I2C3_SDA_GPIO_CLK          RCC_AHB1Periph_GPIOH

#define I2C3_SDA_GPIO_PIN          GPIO_Pin_8

#define I2C3_SDA_GPIO_PINSOURCE    GPIO_PinSource8

  

 

GPIO_TypeDef* I2C_SCL_GPIO_PORT[3] = {I2C1_SCL_GPIO_PORT, I2C2_SCL_GPIO_PORT, I2C3_SCL_GPIO_PORT};

const uint16_t I2C_SCL_GPIO_PIN[3] = {I2C1_SCL_GPIO_PIN, I2C2_SCL_GPIO_PIN, I2C3_SCL_GPIO_PIN};

const uint32_t I2C_SCL_GPIO_CLK[3] = {I2C1_SCL_GPIO_CLK, I2C2_SCL_GPIO_CLK, I2C3_SCL_GPIO_CLK};

const uint16_t I2C_SCL_GPIO_PINSOURCE[3] = {I2C1_SCL_GPIO_PINSOURCE, I2C2_SCL_GPIO_PINSOURCE, I2C3_SCL_GPIO_PINSOURCE};



GPIO_TypeDef* I2C_SDA_GPIO_PORT[3] = {I2C1_SDA_GPIO_PORT,I2C2_SDA_GPIO_PORT,I2C3_SDA_GPIO_PORT};

const uint16_t I2C_SDA_GPIO_PIN[3] = {I2C1_SDA_GPIO_PIN,I2C2_SDA_GPIO_PIN,I2C3_SDA_GPIO_PIN};

const uint32_t I2C_SDA_GPIO_CLK[3] = {I2C1_SDA_GPIO_CLK,I2C2_SDA_GPIO_CLK,I2C3_SDA_GPIO_CLK};

const uint16_t I2C_SDA_GPIO_PINSOURCE[3] = {I2C1_SDA_GPIO_PINSOURCE,I2C2_SDA_GPIO_PINSOURCE,I2C3_SDA_GPIO_PINSOURCE};



TIM_TypeDef* Timer[3] = {TIM5, TIM6, TIM7};

const IRQn_Type TimerIRQ[3] = {TIM5_IRQn, TIM6_DAC_IRQn, TIM7_IRQn};



const uint32_t RCC_APB1Periph_TIM[3] ={RCC_APB1Periph_TIM5, RCC_APB1Periph_TIM6, RCC_APB1Periph_TIM7};



#define SDA_Clear(IIC) I2C_SDA_GPIO_PORT[IIC]->BSRRH=I2C_SDA_GPIO_PIN[IIC]

#define SDA_Set(IIC) I2C_SDA_GPIO_PORT[IIC]->BSRRL=I2C_SDA_GPIO_PIN[IIC]



#define SCL_Clear(IIC) I2C_SCL_GPIO_PORT[IIC]->BSRRH=I2C_SCL_GPIO_PIN[IIC]

#define SCL_Set(IIC) I2C_SCL_GPIO_PORT[IIC]->BSRRL=I2C_SCL_GPIO_PIN[IIC]



#define En_SDA_Input(IIC) I2C_SDA_GPIO_PORT[IIC]->MODER&=~(I2C_SDA_GPIO_PIN[IIC]<<I2C_SDA_GPIO_PINSOURCE[IIC])

#define En_SDA_Output(IIC) I2C_SDA_GPIO_PORT[IIC]->MODER|=(I2C_SDA_GPIO_PIN[IIC]<<I2C_SDA_GPIO_PINSOURCE[IIC])



#define SDA_Read(IIC) ((I2C_SDA_GPIO_PORT[IIC]->IDR&I2C_SDA_GPIO_PIN[IIC])!=0)?1:0 





typedef struct {

	__IO uint8_t StartState;

	__IO uint8_t StopState;

	__IO int8_t ReadByteState;

	__IO uint8_t TransferByte;

	__IO uint8_t ReadStop;

	__IO uint8_t WriteByteState;

	__IO uint8_t WriteACK;

	__IO uint8_t Command;	//1-Read, 0=Write;

	__IO uint8_t Device;

	__IO uint32_t SubAddr;

	__IO uint8_t SubAddrLen;

	__IO uint8_t *TransferBuf;

	__IO uint16_t TransferCount;

	__IO uint8_t ReadState;

	__IO uint8_t WriteState;

	

	__IO uint8_t dat;

	__IO uint8_t bit;

	__IO	uint8_t IIC_BUSY;

	__IO uint8_t ERROR;

}	IIC_State;



static IIC_State iic_state[IIC_COUNT];



typedef struct {

	void(*OnTx)(void);

	void(*OnRx)(void);

	void(*OnErr)(void);

} IIC_Callback;



__IO IIC_Callback iic_callback[IIC_COUNT];





#define IN            1

#define OUT           0



void __INLINE SetIicSdaDir(uint8_t IIC, uint8_t x) {

	if (x) En_SDA_Input(IIC);

		 else En_SDA_Output(IIC);

}



void IIC_GPIOInit(uint8_t IIC)

{  

  GPIO_InitTypeDef GPIO_InitStructure;

  

  /* Enable I2Cx SCL and SDA Pin Clock */

	RCC_AHB1PeriphClockCmd((I2C_SCL_GPIO_CLK[IIC] | I2C_SDA_GPIO_CLK[IIC]), ENABLE); 

    

  /* Set GPIO frequency to 50MHz */

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  

  /* Select Alternate function mode */

	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//?????

  

  /* Select output Open Drain type */

  GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;

  

  /* Disable internal Pull-up */

  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;

  

  /* Initialize I2Cx SCL Pin */ 

  GPIO_InitStructure.GPIO_Pin = I2C_SCL_GPIO_PIN[IIC];

  

  GPIO_Init((GPIO_TypeDef*)I2C_SCL_GPIO_PORT[IIC], &GPIO_InitStructure);

  

  /* Initialize I2Cx SDA Pin */

  GPIO_InitStructure.GPIO_Pin = I2C_SDA_GPIO_PIN[IIC];

  

  GPIO_Init((GPIO_TypeDef*)I2C_SDA_GPIO_PORT[IIC], &GPIO_InitStructure);     

}







static void IIC_DelayTimer_Init(uint8_t IIC)

{

	NVIC_InitTypeDef NVIC_InitStructure;

	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);

	NVIC_InitStructure.NVIC_IRQChannel = TimerIRQ[IIC];

	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0 ;

	NVIC_Init(&NVIC_InitStructure);

	memset((void *)&iic_state[IIC], 0, sizeof(IIC_State));

	memset((void *)&iic_callback[IIC], 0, sizeof(IIC_Callback));

}



static void IIC_DelayTimer_DeInit(uint8_t IIC)

{

	NVIC_InitTypeDef NVIC_InitStructure;

	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);

	NVIC_InitStructure.NVIC_IRQChannel = TimerIRQ[IIC];

	NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE;

	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0 ;

	NVIC_Init(&NVIC_InitStructure);

	TIM_Cmd(Timer[IIC], DISABLE);

	memset(&iic_state[IIC], 0, sizeof(IIC_State));

}



static void IIC_SetDelay(uint8_t IIC, uint16_t MicroSecond)

{

	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

	RCC_ClocksTypeDef rccClocks;

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM[IIC],ENABLE);

	

	RCC_GetClocksFreq(&rccClocks);

	

	TIM_DeInit(Timer[IIC]);

	TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;

	if (Timer[IIC]==TIM2||Timer[IIC]==TIM3||Timer[IIC]==TIM4||Timer[IIC]==TIM5||Timer[IIC]==TIM6||Timer[IIC]==TIM7||

		Timer[IIC]==TIM12||Timer[IIC]==TIM13||Timer[IIC]==TIM14) TIM_TimeBaseStructure.TIM_Prescaler=rccClocks.PCLK1_Frequency*2/1000000;

		else TIM_TimeBaseStructure.TIM_Prescaler=rccClocks.PCLK2_Frequency*2/1000000;

	TIM_TimeBaseStructure.TIM_ClockDivision=0;

	TIM_TimeBaseStructure.TIM_Period=MicroSecond;

	TIM_TimeBaseInit(Timer[IIC], &TIM_TimeBaseStructure);

	

	TIM_ClearFlag(Timer[IIC], TIM_FLAG_Update);

	

	TIM_ITConfig(Timer[IIC],TIM_FLAG_Update, ENABLE);

}



void IIC_Init(uint8_t IIC, uint16_t MicroSecond)

{	

	IIC_GPIOInit(IIC);

	SDA_Set(IIC);

	SCL_Set(IIC);	

	IIC_DelayTimer_Init(IIC);

	IIC_SetDelay(IIC, MicroSecond);			     

}

#define p iic_state[IIC]

#define q iic_callback[IIC]



void IIC_SetCallback(uint8_t IIC, void(*OnTx)(void), void(*OnRx)(void) ,void(*OnErr)(void))

{

		q.OnErr=OnErr;

		q.OnTx=OnTx;

		q.OnRx=OnRx;

}



void IIC_DeInit(uint8_t IIC)

{	

	IIC_DelayTimer_DeInit(IIC);		     

}







static uint8_t IIC_StartStateMachine(uint8_t IIC)

{

	switch(p.StartState) {

		case 0:

			SDA_Set(IIC);

			SCL_Set(IIC);

			p.StartState++;

			break;

		case 1:

			SDA_Clear(IIC);

			//SoftDelay(0);

 			p.StartState++;

 			break;

 		case 2:

			SCL_Clear(IIC);

			p.StartState=0;

			break;

	}

	return p.StartState;

}	



static uint8_t IIC_StopStateMachine(uint8_t IIC) 

{

	switch(p.StopState) {

		case 0:

			SCL_Set(IIC);

			SDA_Clear(IIC);

			//SoftDelay(1);

			p.StopState++;

			break;

		case 1:

			SDA_Set(IIC);

			p.StopState=0;

			break;

	}

	return p.StopState;

}



static uint8_t IIC_ReadByteStateMachine(uint8_t IIC)

{

	switch(p.ReadByteState) {

		case 0: 

				SetIicSdaDir(IIC, IN);

				p.bit=0;

				p.ReadByteState++;

				break;

		case 1:

				p.dat <<= 1;

				SCL_Set(IIC);

				p.ReadByteState++;

				break;

		case 2:

				if(SDA_Read(IIC))

				{

						p.dat |= 1;

				}

				SCL_Clear(IIC);

				p.bit++;

				if (p.bit==8) p.ReadByteState++;

				else {

					p.ReadByteState--;

					break;

				}

		case 3:

				p.TransferByte=p.dat;

				SetIicSdaDir(IIC, OUT);

				if (p.ReadStop) SDA_Set(IIC); else SDA_Clear(IIC);	   // ReadStop = 0; ask, ReadStop = 1,stop

				p.ReadByteState++;

				break;

		case 4:

				SCL_Set(IIC);

				p.ReadByteState++;

				break;

		case 5:

				SCL_Clear(IIC);

				p.ReadByteState++;

		case 6:

				p.ReadByteState=0;

				break;

	}

	return p.ReadByteState;

}

			

static uint8_t IIC_WriteByteStateMachine(uint8_t IIC)

{

	switch(p.WriteByteState) {

		case 0: 

				p.dat=p.TransferByte;

				p.bit=8;

				p.WriteByteState++;

		case 1:

				if(p.dat & 0x80)

				{

						SDA_Set(IIC);

				}

				else

				{

						SDA_Clear(IIC);

				}

				p.WriteByteState++;

				break;

		case 2:

				SCL_Set(IIC);

				p.WriteByteState++;

				break;

		case 3:

				p.dat <<= 1;

				SCL_Clear(IIC);

				p.bit--;

				if (p.bit) {

					p.WriteByteState=1;

					break;

				}

				else p.WriteByteState++;

		case 4:

			SetIicSdaDir(IIC, IN);

			p.WriteByteState++;

			break;

		case 5:

			SCL_Set(IIC);

			p.WriteByteState++;

			break;

		case 6:

			p.WriteACK = SDA_Read(IIC);

			SCL_Clear(IIC);

			SetIicSdaDir(IIC, OUT);

			p.WriteByteState++;

			break;

		case 7:

			p.WriteByteState=0;

			break;

	}

	return p.WriteByteState;

}



static uint8_t IIC_ReadStateMachine(uint8_t IIC)

{

	switch(p.ReadState) {

		case 0:	

				p.ReadState++; 

		case 1:		

				if (IIC_StartStateMachine(IIC)==0) p.ReadState++; 

				break;

		case 2:

				p.TransferByte=p.Device;

				p.ReadState++;

		case 3:

				if (IIC_WriteByteStateMachine(IIC)==0) {

					if (p.WriteACK==1) {

						p.ReadState=14;		//Stop

					}

				else {

						if (p.SubAddrLen)	p.ReadState++;	//Send Access Address

						else p.ReadState+=3;	//No Address

					}

				}

				break;

		case 4:	//Send Address

				switch(p.SubAddrLen) {

					case 4: p.TransferByte=(p.SubAddr >> 24)&0x000000FF; break;

					case 3: p.TransferByte=(p.SubAddr >> 16)&0x000000FF; break;

					case 2: p.TransferByte=(p.SubAddr >> 8)&0x000000FF; break;

					case 1: p.TransferByte=p.SubAddr&0x000000FF; break;

				}

				p.SubAddrLen--;

				p.ReadState++;

		case 5:

				if (IIC_WriteByteStateMachine(IIC)==0) {

					if (p.WriteACK==1) {

						p.ReadState=14;		//Stop

					}

					else {

						if (p.SubAddrLen==0) p.ReadState++;

						else p.ReadState--;

					}

				}

				break;

		case 6:

				if (IIC_StartStateMachine(IIC)==0) p.ReadState++; 

				break;

		case 7:	//Send Device Read 

				p.TransferByte=p.Device|0x01;

				p.ReadState++;

		case 8:

				if (IIC_WriteByteStateMachine(IIC)==0) {

					if (p.WriteACK==1) {

						p.ReadState=14;

					}

					else {

						if (p.TransferCount==1) p.ReadState+=3;

						else p.ReadState++;

					}

				}

				break;	

		case 9:	//Read Bytes

				p.ReadStop=0;	

				p.ReadState++;

		case 10:

				if (IIC_ReadByteStateMachine(IIC)==0) {

						*p.TransferBuf=p.TransferByte;

						p.TransferBuf++;

						p.TransferCount--;

						if (p.TransferCount==1) p.ReadState++;

				}

				break;	

		case 11:	//Read Last Byte

				p.ReadStop=1;

				p.ReadState++;

		case 12:	//Read Last Byte

				if (IIC_ReadByteStateMachine(IIC)==0) {

						*p.TransferBuf=p.TransferByte;

						p.TransferCount=0;

						p.ReadState++;

				}

				break;

		case 13:

				if (IIC_StopStateMachine(IIC)==0) {

					p.ReadState=0; 

					p.IIC_BUSY=0;

					p.ERROR=0;

					if (q.OnRx) q.OnRx();

				}

				break;

		case 14:

				if (IIC_StopStateMachine(IIC)==0) {

					p.ReadState=0; 

					p.IIC_BUSY=0;

					p.ERROR=1;

					if (q.OnErr) q.OnErr();

				}

				break;

	}

	return p.ReadState;

}



static uint8_t IIC_WriteStateMachine(uint8_t IIC)

{

	switch(p.WriteState) {

		case 0:	

				p.WriteState++;

		case 1:		

				if (IIC_StartStateMachine(IIC)==0) p.WriteState++; 

				break;

		case 2:

				p.TransferByte=p.Device;

				p.WriteState++;

		case 3:

				if (IIC_WriteByteStateMachine(IIC)==0) {

					if (p.WriteACK==1) {

						p.WriteState=11;		//Stop

					}

					else {

						if (p.SubAddrLen)	p.WriteState++;	//Send Access Address

						else {

							if (p.TransferCount) p.WriteState+=5;	//Multi-Bytes;

								else p.WriteState+=3; //Single Byte

						}

					}

				}

				break;

		case 4:	//Send Address

				switch(p.SubAddrLen) {

					case 4: p.TransferByte=(p.SubAddr >> 24)&0x000000FF; break;

					case 3: p.TransferByte=(p.SubAddr >> 16)&0x000000FF; break;

					case 2: p.TransferByte=(p.SubAddr >> 8)&0x000000FF; break;

					case 1: p.TransferByte=p.SubAddr&0x000000FF; break;

				}

				p.SubAddrLen--;

				p.WriteState++;	

		case 5:

				if (IIC_WriteByteStateMachine(IIC)==0) {

					if (p.WriteACK==1) {

						p.WriteState=11;		//Stop

					}

					else {

						if (p.SubAddrLen==0) {

							if (p.TransferCount) p.WriteState+=3;	//Multi-Bytes;

								else p.WriteState++; //Single Byte

						}

						else p.WriteState--;

					}

				}

				break;

		case 6:	//Send Only One Byte 

				p.TransferByte=(uint32_t)p.TransferBuf;

				p.WriteState++;

		case 7:

				if (IIC_WriteByteStateMachine(IIC)==0) {

					if (p.WriteACK==1) {

						p.WriteState=11;		//Stop

					}

					else {

						p.WriteState+=3;

					}

				}

				break;

		case 8:	//Send Multi-Bytes Data 

				p.TransferByte=*p.TransferBuf; p.TransferBuf++; p.TransferCount--;

				p.WriteState++;

		case 9:

				if (IIC_WriteByteStateMachine(IIC)==0) {

					if (p.WriteACK==1) {

						p.WriteState=11;		//Stop

					}

					else {

						if (p.TransferCount==0) p.WriteState++;

						else p.WriteState--;

					}

				}

				break;

		case 10:

				if (IIC_StopStateMachine(IIC)==0) {

					p.WriteState=0;

					p.IIC_BUSY=0;

					p.ERROR=0;

					if (q.OnTx) q.OnTx();

				}

				break;

		case 11:

				if (IIC_StopStateMachine(IIC)==0) {

					p.WriteState=0;

					p.IIC_BUSY=0;

					p.ERROR=1;

					if (q.OnErr) q.OnErr();

				}

				break;

	}

	return p.WriteState;

}			



static uint8_t IIC_StateMachine(uint8_t IIC)

{

	if (p.Command) return IIC_ReadStateMachine(IIC);

		return IIC_WriteStateMachine(IIC);

}





uint8_t I2C_Read7(uint8_t IIC, uint8_t device, uint8_t Addr, uint8_t *Buf, uint8_t Count)

{

	if (p.IIC_BUSY==0) {

		memset(&p, 0, sizeof(IIC_State));

		p.Command=1;	//1-Read, 0=Write;

		p.Device=device;

		p.SubAddr=Addr;

		p.SubAddrLen=1;

		p.TransferBuf=Buf;

		p.TransferCount=Count;

		p.IIC_BUSY=1;

		TIM_Cmd(Timer[IIC], ENABLE);

		return 1;

	}	

	else return 0;	

}



uint8_t I2C_Read16(uint8_t IIC, uint8_t device, uint16_t Addr, uint8_t *Buf, uint8_t Count)

{

	if (p.IIC_BUSY==0) {

		memset(&p, 0, sizeof(IIC_State));

		p.Command=1;	//1-Read, 0=Write;

		p.Device=device;

		p.SubAddr=Addr;

		p.SubAddrLen=2;

		p.TransferBuf=Buf;

		p.TransferCount=Count;

		p.IIC_BUSY=1;

		TIM_Cmd(Timer[IIC], ENABLE);

		return 1;

	}	

	else return 0;	

}



uint8_t I2C_WriteByte7(uint8_t IIC, uint8_t device, uint8_t Addr, uint8_t Data)

{

	if (p.IIC_BUSY==0) {

		memset(&p, 0, sizeof(IIC_State));

		p.Command=0;	//1-Read, 0=Write;

		p.Device=device;

		p.SubAddr=Addr;

		p.SubAddrLen=1;

		p.TransferBuf=(uint8_t *)Data;

		p.TransferCount=0;

		p.IIC_BUSY=1;

		TIM_Cmd(Timer[IIC], ENABLE);

		return 1;

	}	

	else return 0;	

}



uint8_t I2C_Write16(uint8_t IIC, uint8_t device, uint16_t Addr, uint8_t *Buf, uint8_t Count)

{

	if (p.IIC_BUSY==0) {

		memset(&p, 0, sizeof(IIC_State));

		p.Command=0;	//1-Read, 0=Write;

		p.Device=device;

		p.SubAddr=Addr;

		p.SubAddrLen=2;

		p.TransferBuf=Buf;

		p.TransferCount=Count;

		p.IIC_BUSY=1;

		TIM_Cmd(Timer[IIC], ENABLE);

		return 1;

	}	

	else return 0;	

}



#if (IIC_COUNT>=1)

void TIM5_IRQHandler(void)

{

	if (TIM_GetITStatus(TIM5, TIM_IT_Update) != RESET) {

		TIM_ClearITPendingBit(TIM5, TIM_IT_Update);

		if (IIC_StateMachine(0)==0) {

			if (iic_state[0].IIC_BUSY==0) TIM_Cmd(TIM5, DISABLE);

		}

	}

}

#endif



#if (IIC_COUNT>=2)

void TIM6_DAC_IRQHandler(void)

{

	if (TIM_GetITStatus(TIM6, TIM_IT_Update) != RESET) {

		TIM_ClearITPendingBit(TIM6, TIM_IT_Update);

		if (IIC_StateMachine(1)==0) {

			if (iic_state[1].IIC_BUSY==0) TIM_Cmd(TIM6, DISABLE);

		}

	}

}

#endif



#if (IIC_COUNT>=3)

void TIM7_IRQHandler(void)

{

	if (TIM_GetITStatus(TIM7, TIM_IT_Update) != RESET) {

		TIM_ClearITPendingBit(TIM7, TIM_IT_Update);

		if (IIC_StateMachine(2)==0) {

			if (iic_state[2].IIC_BUSY==0) TIM_Cmd(TIM7, DISABLE);

		}

	}

}

#endif

  

你可能感兴趣的:(master)