很多传感器喜欢使用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;
}