I2C通讯

很多传感器喜欢使用I2C进行通讯

i2c.c

#include "HRM_i2c.h"
// i2c

static void i2c_Delay(void)
{
	uint8_t i;

	/*¡¡
		¿ÉÓÃÂß¼­·ÖÎöÒDzâÁ¿I2CͨѶʱµÄƵÂÊ
    ¹¤×÷Ìõ¼þ£ºCPUÖ÷Ƶ180MHz £¬MDK±àÒë»·¾³£¬1¼¶ÓÅ»¯
  
		¾­²âÊÔ£¬Ñ­»·´ÎÊýΪ20~250ʱ¶¼ÄÜͨѶÕý³£

	*/
	for (i = 0; i < 100; i++);
}

/*¹ØÓÚI2CµÄ³õʼ»¯ºÍʹÓÃ
//  SCL:PB10
//	SDA:PB11
*/

void HRM_IIC_Init(void)
{
	GPIO_InitTypeDef GPIO_Initure;
	
	I2C_CLKCMD(I2C_CLK,ENABLE);
	
	GPIO_Initure.GPIO_Mode = GPIO_Mode_Out_OD;
	GPIO_Initure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Initure.GPIO_Pin = I2C_SCL_PIN | I2C_SDA_PIN;
	GPIO_Init(I2C_PORT,&GPIO_Initure);
	I2C_SCL_1();
	I2C_SDA_1();

}

void SDA_OUT(void)
{
	GPIO_InitTypeDef GPIO_Initure;
	
	I2C_CLKCMD(I2C_CLK,ENABLE);
	
	GPIO_Initure.GPIO_Mode = GPIO_Mode_Out_OD;
	GPIO_Initure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Initure.GPIO_Pin = I2C_SDA_PIN;
	GPIO_Init(I2C_PORT,&GPIO_Initure);
}
void SDA_IN(void)
{
	GPIO_InitTypeDef GPIO_Initure;
	
	I2C_CLKCMD(I2C_CLK,ENABLE);
	
	GPIO_Initure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Initure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Initure.GPIO_Pin = I2C_SDA_PIN;
	GPIO_Init(I2C_PORT,&GPIO_Initure);
}

void IIC_Start(void)
{
	SDA_OUT();
	//ÇåÁ㣬PB11 ÖÃΪ1  ÉèÖÃΪÊä³öģʽ
	I2C_SDA_1();
	I2C_SCL_1();
	i2c_Delay();
	I2C_SDA_0();
	i2c_Delay();
	I2C_SCL_0();
}

void IIC_Stop(void)
{
	SDA_OUT();//sdaÏßÊä³ö
	//{GPIOB->MODER&=~(3<<(11*2));GPIOB->MODER|=1<<11*2;} //PB11Êä³öģʽ
	I2C_SCL_0();
	I2C_SDA_0();//STOP:when CLK is high DATA change form low to high
	i2c_Delay();
	I2C_SCL_1(); 
	I2C_SDA_1();//·¢ËÍI2C×ÜÏß½áÊøÐźÅ
	i2c_Delay();							   	
}


//µÈ´ýÓ¦´ðÐźŵ½À´
//·µ»ØÖµ£º1£¬½ÓÊÕÓ¦´ðʧ°Ü
//        0£¬½ÓÊÕÓ¦´ð³É¹¦
uint8_t IIC_Wait_Ack(void)
{
	uint8_t ucErrTime=0; 
	SDA_IN();      //SDAÉèÖÃΪÊäÈë 
	I2C_SDA_1();
	i2c_Delay(); // ÑÓʱº¯Êý	   
	I2C_SCL_1();
	i2c_Delay(); //ÑÓʱº¯Êý
	
/*
//I2C_SDA_READ();
//GPIO_ReadInputDataBit(I2C_PORT,I2C_SDA_PIN);
//GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11); //¶ÁÈ¡PB11 ÊäÈëÊý¾Ý
*/
	while(I2C_SDA_READ()) 
	{
		ucErrTime++;
		if(ucErrTime>250)
		{
			IIC_Stop(); //Í£Ö¹IIC
			return 1;
		}
	}
	I2C_SCL_0();//ʱÖÓÊä³ö0 	   
	return 0;  
} 

//  SCL:PB10
//	SDA:PB11
//²úÉúACKÓ¦´ð
void IIC_Ack(void)
{
	I2C_SCL_0();//GPIO_ResetBits(GPIOB,GPIO_Pin_10);
	SDA_OUT();	//{GPIOB->MODER&=~(3<<(11*2));GPIOB->MODER|=1<<11*2;} //PB11Êä³öģʽ
	 I2C_SDA_0();//GPIO_ResetBits(GPIOB,GPIO_Pin_11);
	i2c_Delay();
	I2C_SCL_1();//GPIO_SetBits(GPIOB,GPIO_Pin_10);
	i2c_Delay();
	I2C_SCL_0();//GPIO_ResetBits(GPIOB,GPIO_Pin_10);
}


//²»²úÉúACKÓ¦´ð		    
void IIC_NAck(void)
{
	I2C_SCL_0();//GPIO_ResetBits(GPIOB,GPIO_Pin_10);
	SDA_OUT();	//{GPIOB->MODER&=~(3<<(11*2));GPIOB->MODER|=1<<11*2;} //PB11Êä³öģʽ
	 I2C_SDA_1();//GPIO_SetBits(GPIOB,GPIO_Pin_11);
	i2c_Delay();
	I2C_SCL_1();//GPIO_SetBits(GPIOB,GPIO_Pin_10);
	i2c_Delay();
	I2C_SCL_0();//GPIO_ResetBits(GPIOB,GPIO_Pin_10);
}					 				  

//IIC·¢ËÍÒ»¸ö×Ö½Ú
//·µ»Ø´Ó»úÓÐÎÞÓ¦´ð
//1£¬ÓÐÓ¦´ð
//0£¬ÎÞÓ¦´ð			  
void IIC_Send_Byte(uint8_t txd)
{                        
		uint8_t t;  
		SDA_OUT();	//{GPIOB->MODER&=~(3<<(11*2));GPIOB->MODER|=1<<11*2;} //PB11Êä³öģʽ
    I2C_SCL_0();//À­µÍʱÖÓ¿ªÊ¼Êý¾Ý´«Êä //GPIO_ResetBits(GPIOB,GPIO_Pin_10);
    for(t=0;t<8;t++)
    {              
			if((txd&0x80)>>7)
			{
				I2C_SDA_1();	//GPIO_SetBits(GPIOB,GPIO_Pin_11);
			}
			else
			{
				I2C_SDA_0();	//GPIO_ResetBits(GPIOB,GPIO_Pin_11);
			}
      txd<<=1; 	  
			i2c_Delay();   //¶ÔTEA5767ÕâÈý¸öÑÓʱ¶¼ÊDZØÐëµÄ
			I2C_SCL_1();	 //GPIO_SetBits(GPIOB,GPIO_Pin_10);
			i2c_Delay(); 
			I2C_SCL_0();	 //GPIO_ResetBits(GPIOB,GPIO_Pin_10);
			i2c_Delay();
    }	 
} 	    
//¶Á1¸ö×Ö½Ú£¬ack=1ʱ£¬·¢ËÍACK£¬ack=0£¬·¢ËÍnACK   
uint8_t IIC_Read_Byte(unsigned char ack)
{
	unsigned char i,receive=0;
	SDA_IN();//SDAÉèÖÃΪÊäÈë
	//{GPIOB->MODER&=~(3<<(11*2));
	//GPIOB->MODER|=0<<11*2;}	
  for(i=0;i<8;i++ )
	{
        I2C_SCL_0(); //GPIO_ResetBits(GPIOB,GPIO_Pin_10);
        i2c_Delay();
				I2C_SCL_1(); //GPIO_SetBits(GPIOB,GPIO_Pin_10);
        receive<<=1;
        if(I2C_SDA_READ()) //GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11); //¶ÁÈ¡PB11 ÊäÈëÊý¾Ý
					receive++;   
				i2c_Delay(); 
    }					 
    if (!ack)
        IIC_NAck();//·¢ËÍnACK   //²»²úÉúACKÓ¦´ð	
    else
        IIC_Ack(); //·¢ËÍACK    //²úÉúACKÓ¦´ð
    return receive;
}


i2c.h

#ifndef __HRM_I2C_H__
#define __HRM_I2C_H__


#include "stm32f10x.h"


#define I2C_PORT      GPIOB
#define I2C_SCL_PIN   GPIO_Pin_14
#define I2C_SDA_PIN   GPIO_Pin_13
#define I2C_CLKCMD		RCC_APB2PeriphClockCmd
#define I2C_CLK       RCC_APB2Periph_GPIOB


#define I2C_SCL_1()     GPIO_SetBits(I2C_PORT,I2C_SCL_PIN)
#define I2C_SCL_0()     GPIO_ResetBits(I2C_PORT,I2C_SCL_PIN)
#define I2C_SDA_1()     GPIO_SetBits(I2C_PORT,I2C_SDA_PIN)
#define I2C_SDA_0()     GPIO_ResetBits(I2C_PORT,I2C_SDA_PIN)
#define I2C_SDA_READ()  GPIO_ReadInputDataBit(I2C_PORT,I2C_SDA_PIN)


//#define SDA_IN()  {GPIOB->MODER&=~(3<<(11*2));GPIOB->MODER|=0<<11*2;}	//PB11ÊäÈëģʽ,Òª½«ÀïÃæµÄ11±ä³ÉSDAµÄÒý½ÅÊý
//#define SDA_OUT() {GPIOB->MODER&=~(3<<(11*2));GPIOB->MODER|=1<<11*2;} //PB11Êä³öģʽ

void SDA_OUT(void);
void SDA_IN(void);
//IICËùÓвÙ×÷º¯Êý
void HRM_IIC_Init(void);                //³õʼ»¯IICµÄIO¿Ú				 
void IIC_Start(void);				//·¢ËÍIIC¿ªÊ¼ÐźÅ
void IIC_Stop(void);	  			//·¢ËÍIICÍ£Ö¹ÐźÅ
void IIC_Send_Byte(uint8_t txd);			//IIC·¢ËÍÒ»¸ö×Ö½Ú
uint8_t IIC_Read_Byte(unsigned char ack);//IIC¶ÁÈ¡Ò»¸ö×Ö½Ú
uint8_t IIC_Wait_Ack(void); 				//IICµÈ´ýACKÐźÅ
void IIC_Ack(void);					//IIC·¢ËÍACKÐźÅ
void IIC_NAck(void);				//IIC²»·¢ËÍACKÐźÅ








#endif

调用i2c的函数

hrm.c

#include "HRM.h"
#include "HRM_i2c.h"
#include "bsp_SysTick.h"
#include "bsp_usart.h"


//ÐÄÂÊ´«¸ÐÆ÷

#define SCALE 2000

static void Change(float original[3],unsigned char back[6])
{
	short pool;
	float tmp;
	char i,j;
	for(i = 0,j = 0;i < 3;i++,j+=2)
	{
		tmp = original[i];
		tmp *= 10;
		pool = (short)(tmp*SCALE);
		back[j] = pool >> 8;
		back[j+1] = pool;
	}
}

void OFF_HRM(void)
{
	GPIO_SetBits(EN_PORT,EN_PIN);
}

void ON_HRM(void)
{
	GPIO_ResetBits(EN_PORT,EN_PIN);
}

void HRM_Init(void)
{
	GPIO_InitTypeDef GPIO_InitTypeStruct;
	EN_CLKCMD(EN_CLK,ENABLE);
	INT_CLKCMD(INT_CLK,ENABLE);
	
	//³õʼ»¯GPIO5  ÊäÈëģʽ
	GPIO_InitTypeStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_InitTypeStruct.GPIO_Pin = INT_PIN;
	GPIO_InitTypeStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(INT_PORT,&GPIO_InitTypeStruct);
	
	//³õʼ»¯GPIO8  Êä³öģʽ
	GPIO_InitTypeStruct.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitTypeStruct.GPIO_Pin = EN_PIN;
	GPIO_InitTypeStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(EN_PORT,&GPIO_InitTypeStruct);
	ON_HRM();
}

char GetHandshakeStatus(void)
{
	return GPIO_ReadOutputDataBit(INT_PORT,INT_PIN);
}


STATUS WriteData_HRM(uint8_t device_addr, uint8_t register_addr, uint8_t * data, uint8_t length)
{
	uint8_t i;
	IIC_Start();
	IIC_Send_Byte(device_addr<<1|0);
	if(IIC_Wait_Ack())
	{
		IIC_Stop();
		return 1;
	}
	IIC_Send_Byte(register_addr);
	IIC_Wait_Ack();
	for(i=0;i<length;i++)
	{
		IIC_Send_Byte(data[i]);
		if(IIC_Wait_Ack())
		{
			IIC_Stop();
			return 1;
		}
	}
	IIC_Stop();
	return 0;
}

STATUS ReadData_HRM(uint8_t device_addr, uint8_t register_addr, uint8_t * data, uint8_t length)
{
	uint8_t i = 0;
	IIC_Start();
	IIC_Send_Byte(device_addr<<1|0);
	if(IIC_Wait_Ack()) 
	{
		IIC_Stop();
		return 1;
	}
	IIC_Send_Byte(register_addr);         //д¼Ä´æÆ÷µØÖ·
	IIC_Wait_Ack();             //µÈ´ýÓ¦´ð
	IIC_Start();
	IIC_Send_Byte((device_addr<<1)|1); //·¢ËÍÆ÷¼þµØÖ·+¶ÁÃüÁî
	IIC_Wait_Ack(); 
	while(length)
	{
		if(length==1)
		{
			data[i]=IIC_Read_Byte(0);
		}
		else
		{
			data[i]=IIC_Read_Byte(1);
		}
		length--;
		i++;
	}
	IIC_Stop();
	return 0;
}
//²é¿´HRMSDKµÄ°æ±¾ºÅ
//buffer:½ÓÊÕ°æ±¾ºÅµÄ»º³åÇø,³¤¶È±ØÐë´óÓÚ2
//buffer[0]ÊÇÖ÷°æ±¾ºÅ,buffer[1]ÊǴΰ汾ºÅ
//·µ»Ø0Ϊ³É¹¦,1Ϊ´íÎó
STATUS GetSDKVerison(STATUS *buffer)
{
	STATUS flag;
	flag = ReadData_HRM(HRM_I2C_SLAVE_ADDRESS,HRM_SDK_VERSION,buffer,2);
	return flag;
}

//ÉèÖüÓËٶȵIJÉÑùƵÂÊ
//Frequency:ΪÉèÖõÄƵÂÊ,·¶Î§ÖµÎª10-20.µ¥Î»ÊÇHZ
//·µ»Ø0Ϊ³É¹¦,1Ϊ´íÎó
STATUS SetAccelFrequency(STATUS Frequency)
{
	unsigned short tmp;
	STATUS data[2];
	STATUS flag;
	if(Frequency < 10 || Frequency > 20)
	{
		return 1;
	}
	tmp = (unsigned short)Frequency * 1000;
	data[0] = tmp >> 8;
	data[1] = tmp;
	flag = WriteData_HRM(HRM_I2C_SLAVE_ADDRESS,ACCEL_FREQUENCY,data,2);
	return flag;
}

//ÉèÖÃHRMµÄÓ¦ÓÃID
//ID:ÒªÉèÖõÄÓ¦ÓÃID£¬¾ßÌ庬ÒåÇë²é¿´datasheet
//·µ»Ø0Ϊ³É¹¦,1Ϊ´íÎó
STATUS SetApplicationID(STATUS ID)
{
	STATUS flag;
	STATUS data[1];
	data[0] = ID;
	flag = WriteData_HRM(HRM_I2C_SLAVE_ADDRESS,APPLICATION_ID,data,1);
	return flag;
}

//¶ÁÈ¡HRMµÄÓ¦ÓÃID
//·µ»Ø-1Ϊ´íÎó,ÆäËû¾ÍΪIDºÅ
char ReadApplicationID()
{
	STATUS flag;
	STATUS data[1];
	flag = ReadData_HRM(HRM_I2C_SLAVE_ADDRESS,APPLICATION_ID,data,1);
	if(flag == 1)
	{
		return 0;
	}
	return data[0];
}

//¶ÁÈ¡HRM¼Ä´æÆ÷Ë¢ÐÂλ(SYNC)
//·µ»Ø0Ϊ³É¹¦,1Ϊ´íÎó
STATUS ReadHRMSYNC()
{
	STATUS flag;
	STATUS data[1];
	flag = ReadData_HRM(HRM_I2C_SLAVE_ADDRESS,HRM_SYNC,data,1);
	return flag;
}

//¶ÁÈ¡HRMµÄÐÄÂÊÖµºÍ״ֵ̬
//buffer£ºÎª½ÓÊÕÐÄÂÊÖµºÍ״ֵ̬µÄ»º³åÇø
//buffer[0]:״ֵ̬,buffer[1]:ÐÄÂÊÖµ
//·µ»Ø0Ϊ³É¹¦,1Ϊ´íÎó
void ReadHRM_Status(STATUS *buffer)
{
	STATUS flag;
	do
	{
		while(GetHandshakeStatus() == 1);
		flag = ReadData_HRM(HRM_I2C_SLAVE_ADDRESS,HRM_STATUS,buffer,2);
	}while(buffer[0] == 0xFF || buffer[1] == 0xFF || flag == 1);

}

//дAccelSample£¬¾ßÌ庬Òå¼ûdatasheet
//sample:дÈëµÄsampleÖµ
//·µ»Ø0Ϊ³É¹¦,1Ϊ´íÎó
STATUS WriteAccelSample(STATUS sample)
{
	STATUS flag;
	STATUS data[1];	
	data[0] = sample;
	flag = WriteData_HRM(HRM_I2C_SLAVE_ADDRESS,ACCEL_SAMPLE,data,1); 
	return flag;
}

//дÈë¼ÓËٶȵÄÖµ
//Accel:˳ÐòΪx,y,zÖáµÄ¼ÓËÙ¶È
//·µ»Ø0Ϊ³É¹¦,1Ϊ´íÎó
STATUS WriteValueOfAccel(float Accel[3])
{
	STATUS flag;
	STATUS tmp[6];
	Change(Accel,tmp);
	flag = WriteData_HRM(HRM_I2C_SLAVE_ADDRESS,ACC_DATA,tmp,6);
	return flag;
}

//HRMµÄĬÈÏÉèÖÃ(¼ÓËٶȵIJÉÑùĬÈÏΪ10hz,Ó¦ÓÃIDģʽΪ2)
void HRM_Default_Set(void)
{
	STATUS flag;
	flag = SetAccelFrequency(10);        //ÉèÖüÓËٶȲÉÑùƵÂÊ
	while(flag == 1)                     //¼ì²âÊÇ·ñÕýÈ·ÉèÖÃ
	{
		flag = SetAccelFrequency(10);
		Delay_ms(100);
	}
	printf("¼ÓËٶȲÉÑùƵÂÊÉèÖóɹ¦........\r\n");
SETID:
	flag = SetApplicationID(2);          //ÉèÖÃÓ¦ÓÃID
	while(flag == 1)                     //¼ì²âÊÇ·ñÕýÈ·ÉèÖÃ
	{
		flag = SetApplicationID(2); 
		Delay_ms(100);
	}
	printf("ÉèÖÃÓ¦ÓÃID³É¹¦........\r\n");
	flag = GetHandshakeStatus();         //µÈ´ýϽµÑØ
	while(flag == 1)                     //µÈ´ýϽµÑØ
	{
		flag = GetHandshakeStatus();
		Delay_ms(20);
	}
	if(ReadApplicationID() != 2)         //¼ì²éÊÇ·ñÉèÖÃID³É¹¦
	{
		goto SETID;
	}
	printf("ÕýÈ·ÉèÖÃÓ¦ÓÃID........\r\n");
	flag = ReadHRMSYNC();
	while(flag == 1)
	{
		flag = ReadHRMSYNC();
		Delay_ms(100);
	}
	printf("HRM³õʼ»¯Íê³É........\r\n");
}

//ÔÚ»ñÈ¡ÍêÐÄÂÊÊý¾Ýºó½øÐÐÇåÀí
void DoneClean(float Accel[3])
{
	STATUS flag;
	flag = WriteAccelSample(3);
//	if(flag == 0)
//	{
//		Debug_Info("..................................\r\n");
//	}
	flag = WriteValueOfAccel(Accel); 
//	if(flag == 0)
//	{
//		Debug_Info("..................................\r\n");
//	}
	flag = ReadHRMSYNC(); //¶ÁÈ¡HRM¼Ä´æÆ÷Ë¢ÐÂλ(SYNC)
	printf("the flag is %d\r\n",flag);
}

hrm.h

#ifndef __HRM_H__
#define __HRM_H__


#include "stm32f10x.h"

#define STATUS   unsigned char  


//HRMµÄÏà¹ØµÄGPIO

//¶ÔÓ¦ÐÄÂÊÒý½ÅµÄ:GPIO5 INT
#define INT_PORT      GPIOB
    #define INT_PIN       GPIO_Pin_12
#define INT_CLKCMD		RCC_APB2PeriphClockCmd
#define INT_CLK       RCC_APB2Periph_GPIOB

//¶ÔÓ¦ÐÄÂÊÒý½ÅµÄ:GPIO8 EN
#define EN_PORT      GPIOB
#define EN_PIN       GPIO_Pin_15
#define EN_CLKCMD    RCC_APB2PeriphClockCmd
#define EN_CLK       RCC_APB2Periph_GPIOB




//Ïà¹ØI2CµØÖ·
#define HRM_I2C_SLAVE_ADDRESS         0x30
#define HRM_SDK_VERSION               0
#define APPLICATION_ID                   4
#define ACCEL_FREQUENCY                  8
#define AS700_HEART_RATE                 55
#define APP_ID                           4
#define ACCEL_FRQ                        8
#define HRM_SYNC                         57
#define HRM_STATUS                       54
#define ACC_DATA                         21
#define HOST_ONE_SECOND_TIME             10
#define ACCEL_SAMPLE                     14
#define HRV_RESULT                       18

uint8_t GetHeart_Rate(uint8_t *temp);
STATUS ReadData_HRM(uint8_t device_addr, uint8_t register_addr, uint8_t * data, uint8_t length);
STATUS WriteData_HRM(uint8_t device_addr, uint8_t register_addr, uint8_t * data, uint8_t length);


//¶ÔÍâÌṩµÄ½Ó¿Ú
void HRM_Init(void);                          //HRM³õʼ»¯º¯Êý
char GetHandshakeStatus(void);                   //handshake¶ÁÈ¡º¯Êý
STATUS GetSDKVerison(STATUS *buffer);            //»ñÈ¡SDKµÄ°æ±¾ºÅ
STATUS SetAccelFrequency(STATUS Frequency);      //ÉèÖüÓËٶȵIJÉÑùƵÂÊ
STATUS SetApplicationID(STATUS ID);              //ÉèÖÃHRMµÄÓ¦ÓÃID
char ReadApplicationID(void);                    //¶ÁÈ¡HRMµÄÓ¦ÓÃID
STATUS ReadHRMSYNC(void);                     //¶ÁÈ¡HRM¼Ä´æÆ÷Ë¢ÐÂλ(SYNC)
void ReadHRM_Status(STATUS *buffer);             //¶ÁÈ¡HRMµÄÐÄÂÊÖµºÍ״ֵ̬
STATUS WriteAccelSample(STATUS sample);          //дAccelSample£¬¾ßÌ庬Òå¼ûdatasheet
STATUS WriteValueOfAccel(float Accel[3]);        //дÈë¼ÓËٶȵÄÖµ
void HRM_Default_Set(void);                   //HRMµÄĬÈÏÉèÖÃ(¼ÓËٶȵIJÉÑùĬÈÏΪ10hz,Ó¦ÓÃIDģʽΪ2)
void DoneClean(float Accel[3]);                  //ÔÚ»ñÈ¡ÍêÐÄÂÊÊý¾Ýºó½øÐÐÇåÀí

//HRMµÄ¿ª¹Øº¯Êý
void OFF_HRM(void);
void ON_HRM(void);


#endif


主函数初始化并调用

#include "HRM.h"
#include "HRM_i2c.h"

int main()
{
    uint8_t myhrm[2];

    HRM_IIC_Init();
	HRM_Init();          //
	HRM_Default_Set();   //

    while(1)
    {
        ReadHRM_Status(myhrm);
        printf("myhrm:%2d\r\n",myhrm[1]);	
        delay_ms(200);
    }
}

标准化I2C程序,只需要两步!!

i2c.h

#ifndef __AS7000_I2C_H__
#define __AS7000_I2C_H__


#include "stm32f10x.h"


#define I2C_PORT      GPIOB
#define I2C_SCL_PIN   GPIO_Pin_6
#define I2C_SDA_PIN   GPIO_Pin_7
#define I2C_CLKCMD		RCC_APB2PeriphClockCmd
#define I2C_CLK       RCC_APB2Periph_GPIOB


#define I2C_SCL_1()     GPIO_SetBits(I2C_PORT,I2C_SCL_PIN)
#define I2C_SCL_0()     GPIO_ResetBits(I2C_PORT,I2C_SCL_PIN)
#define I2C_SDA_1()     GPIO_SetBits(I2C_PORT,I2C_SDA_PIN)
#define I2C_SDA_0()     GPIO_ResetBits(I2C_PORT,I2C_SDA_PIN)
#define I2C_SDA_READ()  GPIO_ReadInputDataBit(I2C_PORT,I2C_SDA_PIN)


//#define SDA_IN()  {GPIOB->MODER&=~(3<<(11*2));GPIOB->MODER|=0<<11*2;}	//PB11ÊäÈëģʽ,Òª½«ÀïÃæµÄ11±ä³ÉSDAµÄÒý½ÅÊý
//#define SDA_OUT() {GPIOB->MODER&=~(3<<(11*2));GPIOB->MODER|=1<<11*2;} //PB11Êä³öģʽ

void SDA_OUT(void);
void SDA_IN(void);
//IICËùÓвÙ×÷º¯Êý
void AS7000_IIC_Init(void);                //³õʼ»¯IICµÄIO¿Ú				 
void IIC_Start(void);				//·¢ËÍIIC¿ªÊ¼ÐźÅ
void IIC_Stop(void);	  			//·¢ËÍIICÍ£Ö¹ÐźÅ
void IIC_Send_Byte(uint8_t txd);			//IIC·¢ËÍÒ»¸ö×Ö½Ú
uint8_t IIC_Read_Byte(unsigned char ack);//IIC¶ÁÈ¡Ò»¸ö×Ö½Ú
uint8_t IIC_Wait_Ack(void); 				//IICµÈ´ýACKÐźÅ
void IIC_Ack(void);					//IIC·¢ËÍACKÐźÅ
void IIC_NAck(void);				//IIC²»·¢ËÍACKÐźÅ








#endif

i2c.c

#include "as7000_i2c.h"
// i2c

static void i2c_Delay(void)
{
	uint8_t i;

	/*¡¡
		¿ÉÓÃÂß¼­·ÖÎöÒDzâÁ¿I2CͨѶʱµÄƵÂÊ
    ¹¤×÷Ìõ¼þ£ºCPUÖ÷Ƶ180MHz £¬MDK±àÒë»·¾³£¬1¼¶ÓÅ»¯
  
		¾­²âÊÔ£¬Ñ­»·´ÎÊýΪ20~250ʱ¶¼ÄÜͨѶÕý³£

	*/
	for (i = 0; i < 100; i++);
}

/*¹ØÓÚI2CµÄ³õʼ»¯ºÍʹÓÃ
//  SCL:PB10
//	SDA:PB11
*/

void AS7000_IIC_Init(void)
{
	GPIO_InitTypeDef GPIO_Initure;
	
	I2C_CLKCMD(I2C_CLK,ENABLE);
	
	GPIO_Initure.GPIO_Mode = GPIO_Mode_Out_OD;
	GPIO_Initure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Initure.GPIO_Pin = I2C_SCL_PIN | I2C_SDA_PIN;
	GPIO_Init(I2C_PORT,&GPIO_Initure);
	I2C_SCL_1();
	I2C_SDA_1();

}

void SDA_OUT(void)
{
	GPIO_InitTypeDef GPIO_Initure;
	
	I2C_CLKCMD(I2C_CLK,ENABLE);
	
	GPIO_Initure.GPIO_Mode = GPIO_Mode_Out_OD;
	GPIO_Initure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Initure.GPIO_Pin = I2C_SDA_PIN;
	GPIO_Init(I2C_PORT,&GPIO_Initure);
}
void SDA_IN(void)
{
	GPIO_InitTypeDef GPIO_Initure;
	
	I2C_CLKCMD(I2C_CLK,ENABLE);
	
	GPIO_Initure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Initure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Initure.GPIO_Pin = I2C_SDA_PIN;
	GPIO_Init(I2C_PORT,&GPIO_Initure);
}

void IIC_Start(void)
{
	SDA_OUT();
	//ÇåÁ㣬PB11 ÖÃΪ1  ÉèÖÃΪÊä³öģʽ
	I2C_SDA_1();
	I2C_SCL_1();
	i2c_Delay();
	I2C_SDA_0();
	i2c_Delay();
	I2C_SCL_0();
}

void IIC_Stop(void)
{
	SDA_OUT();//sdaÏßÊä³ö
	//{GPIOB->MODER&=~(3<<(11*2));GPIOB->MODER|=1<<11*2;} //PB11Êä³öģʽ
	I2C_SCL_0();
	I2C_SDA_0();//STOP:when CLK is high DATA change form low to high
	i2c_Delay();
	I2C_SCL_1(); 
	I2C_SDA_1();//·¢ËÍI2C×ÜÏß½áÊøÐźÅ
	i2c_Delay();							   	
}


//µÈ´ýÓ¦´ðÐźŵ½À´
//·µ»ØÖµ£º1£¬½ÓÊÕÓ¦´ðʧ°Ü
//        0£¬½ÓÊÕÓ¦´ð³É¹¦
uint8_t IIC_Wait_Ack(void)
{
	uint8_t ucErrTime=0; 
	SDA_IN();      //SDAÉèÖÃΪÊäÈë 
	I2C_SDA_1();
	i2c_Delay(); // ÑÓʱº¯Êý	   
	I2C_SCL_1();
	i2c_Delay(); //ÑÓʱº¯Êý
	
/*
//I2C_SDA_READ();
//GPIO_ReadInputDataBit(I2C_PORT,I2C_SDA_PIN);
//GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11); //¶ÁÈ¡PB11 ÊäÈëÊý¾Ý
*/
	while(I2C_SDA_READ()) 
	{
		ucErrTime++;
		if(ucErrTime>250)
		{
			IIC_Stop(); //Í£Ö¹IIC
			return 1;
		}
	}
	I2C_SCL_0();//ʱÖÓÊä³ö0 	   
	return 0;  
} 

//  SCL:PB10
//	SDA:PB11
//²úÉúACKÓ¦´ð
void IIC_Ack(void)
{
	I2C_SCL_0();//GPIO_ResetBits(GPIOB,GPIO_Pin_10);
	SDA_OUT();	//{GPIOB->MODER&=~(3<<(11*2));GPIOB->MODER|=1<<11*2;} //PB11Êä³öģʽ
	 I2C_SDA_0();//GPIO_ResetBits(GPIOB,GPIO_Pin_11);
	i2c_Delay();
	I2C_SCL_1();//GPIO_SetBits(GPIOB,GPIO_Pin_10);
	i2c_Delay();
	I2C_SCL_0();//GPIO_ResetBits(GPIOB,GPIO_Pin_10);
}


//²»²úÉúACKÓ¦´ð		    
void IIC_NAck(void)
{
	I2C_SCL_0();//GPIO_ResetBits(GPIOB,GPIO_Pin_10);
	SDA_OUT();	//{GPIOB->MODER&=~(3<<(11*2));GPIOB->MODER|=1<<11*2;} //PB11Êä³öģʽ
	 I2C_SDA_1();//GPIO_SetBits(GPIOB,GPIO_Pin_11);
	i2c_Delay();
	I2C_SCL_1();//GPIO_SetBits(GPIOB,GPIO_Pin_10);
	i2c_Delay();
	I2C_SCL_0();//GPIO_ResetBits(GPIOB,GPIO_Pin_10);
}					 				  

//IIC·¢ËÍÒ»¸ö×Ö½Ú
//·µ»Ø´Ó»úÓÐÎÞÓ¦´ð
//1£¬ÓÐÓ¦´ð
//0£¬ÎÞÓ¦´ð			  
void IIC_Send_Byte(uint8_t txd)
{                        
		uint8_t t;  
		SDA_OUT();	//{GPIOB->MODER&=~(3<<(11*2));GPIOB->MODER|=1<<11*2;} //PB11Êä³öģʽ
    I2C_SCL_0();//À­µÍʱÖÓ¿ªÊ¼Êý¾Ý´«Êä //GPIO_ResetBits(GPIOB,GPIO_Pin_10);
    for(t=0;t<8;t++)
    {              
			if((txd&0x80)>>7)
			{
				I2C_SDA_1();	//GPIO_SetBits(GPIOB,GPIO_Pin_11);
			}
			else
			{
				I2C_SDA_0();	//GPIO_ResetBits(GPIOB,GPIO_Pin_11);
			}
      txd<<=1; 	  
			i2c_Delay();   //¶ÔTEA5767ÕâÈý¸öÑÓʱ¶¼ÊDZØÐëµÄ
			I2C_SCL_1();	 //GPIO_SetBits(GPIOB,GPIO_Pin_10);
			i2c_Delay(); 
			I2C_SCL_0();	 //GPIO_ResetBits(GPIOB,GPIO_Pin_10);
			i2c_Delay();
    }	 
} 	    
//¶Á1¸ö×Ö½Ú£¬ack=1ʱ£¬·¢ËÍACK£¬ack=0£¬·¢ËÍnACK   
uint8_t IIC_Read_Byte(unsigned char ack)
{
	unsigned char i,receive=0;
	SDA_IN();//SDAÉèÖÃΪÊäÈë
	//{GPIOB->MODER&=~(3<<(11*2));
	//GPIOB->MODER|=0<<11*2;}	
  for(i=0;i<8;i++ )
	{
        I2C_SCL_0(); //GPIO_ResetBits(GPIOB,GPIO_Pin_10);
        i2c_Delay();
				I2C_SCL_1(); //GPIO_SetBits(GPIOB,GPIO_Pin_10);
        receive<<=1;
        if(I2C_SDA_READ()) //GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11); //¶ÁÈ¡PB11 ÊäÈëÊý¾Ý
					receive++;   
				i2c_Delay(); 
    }					 
    if (!ack)
        IIC_NAck();//·¢ËÍnACK   //²»²úÉúACKÓ¦´ð	
    else
        IIC_Ack(); //·¢ËÍACK    //²úÉúACKÓ¦´ð
    return receive;
}

STATUS WriteData_AS7000(uint8_t device_addr, uint8_t register_addr, uint8_t * data, uint8_t length)
{
	uint8_t i;
	IIC_Start();
	IIC_Send_Byte(device_addr<<1|0);
	if(IIC_Wait_Ack())
	{
		IIC_Stop();
		return 1;
	}
	IIC_Send_Byte(register_addr);
	IIC_Wait_Ack();
	for(i=0;i<length;i++)
	{
		IIC_Send_Byte(data[i]);
		if(IIC_Wait_Ack())
		{
			IIC_Stop();
			return 1;
		}
	}
	IIC_Stop();
	return 0;
}

STATUS ReadData_AS7000(uint8_t device_addr, uint8_t register_addr, uint8_t * data, uint8_t length)
{
	uint8_t i = 0;
	IIC_Start();
	IIC_Send_Byte(device_addr<<1|0);
	if(IIC_Wait_Ack()) 
	{
		IIC_Stop();
		return 1;
	}
	IIC_Send_Byte(register_addr);         //д¼Ä´æÆ÷µØÖ·
	IIC_Wait_Ack();             //µÈ´ýÓ¦´ð
	IIC_Start();
	IIC_Send_Byte((device_addr<<1)|1); //·¢ËÍÆ÷¼þµØÖ·+¶ÁÃüÁî
	IIC_Wait_Ack(); 
	while(length)
	{
		if(length==1)
		{
			data[i]=IIC_Read_Byte(0);
		}
		else
		{
			data[i]=IIC_Read_Byte(1);
		}
		length--;
		i++;
	}
	IIC_Stop();
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值