F407_MAX30102数字心率血氧

MAX30102是基于I2C进行数据传输

I2C采用软件I2C




static GPIO_InitTypeDef GPIO_InitStructure;


void i2c_init(void)
{

	//使能端口B的硬件时钟
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);	


	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8|GPIO_Pin_9;	//第 8 9 个引脚
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT;		//输出模式
	GPIO_InitStructure.GPIO_Speed=GPIO_High_Speed;		//引脚高速工作,收到指令立即工作;缺点:功耗高
	GPIO_InitStructure.GPIO_OType=GPIO_OType_OD;		//开漏
	GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL;		//不需要上下拉电阻
	GPIO_Init(GPIOB,&GPIO_InitStructure);
	
	
	//只要是输出模式,肯定会有初始电平状态,看时序图,空闲状态为高电平
	SCL_W=1;
	SDA_W=1;

}

void sda_pin_mode(GPIOMode_TypeDef pin_mode)
{
	//配置硬件,配置GPIO,端口F,第9个引脚
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;			//第9 个引脚
	GPIO_InitStructure.GPIO_Mode=pin_mode;				//输出模式
	GPIO_InitStructure.GPIO_Speed=GPIO_High_Speed;		//引脚高速工作,收到指令立即工作;缺点:功耗高
	GPIO_InitStructure.GPIO_OType=GPIO_OType_OD;		//开漏
	GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL;		//不需要上下拉电阻
	GPIO_Init(GPIOB,&GPIO_InitStructure);


}


void i2c_start(void)
{	
	//保证SDA引脚为输出模式
	sda_pin_mode(GPIO_Mode_OUT);
	
	SDA_W=1;
	SCL_W=1;
	delay_us(1);
	
	SDA_W=0;
	delay_us(1);
	
	SCL_W=0;//总线进入忙状态
	delay_us(1);
}


void i2c_stop(void)
{
	//保证SDA引脚为输出模式
	sda_pin_mode(GPIO_Mode_OUT);
	
	SDA_W=0;
	SCL_W=1;
	delay_us(1);
	
	SDA_W=1;
	delay_us(1);

}


void i2c_send_byte(uint8_t byte)
{
	int32_t i=0;
	
	//保证SDA引脚为输出模式
	sda_pin_mode(GPIO_Mode_OUT);

	SDA_W=0;
	SCL_W=0;
	delay_us(1);
	
	//最高有效位优先传输,通过时序图观察到
	for(i=7; i>=0; i--)
	{
		//检测对应的bit位是1还是0
		if(byte & (1<<i))
			SDA_W=1;
		else
			SDA_W=0;
	
		delay_us(1);
	
		//时钟线拉高,数据有效
		SCL_W=1;
		delay_us(1);

	
		//时钟线拉低,数据变更
		SCL_W=0;
		delay_us(1);		
	
	}
}


uint8_t i2c_recv_byte(void)
{
	uint8_t d=0;
	int32_t i;
	
	//保证SDA引脚为输入模式
	sda_pin_mode(GPIO_Mode_IN);

	for(i=7; i>=0; i--)
	{
		//时钟线拉高,数据有效
		SCL_W=1;
		delay_us(1);
		
		//读取SDA引脚电平
		if(SDA_R)
			d|=1<<i;


		//时钟线拉低,保持占用总线,总线是忙状态
		SCL_W=0;
		delay_us(1);	
	
	}

	return d;
}


void i2c_ack(uint8_t ack)
{

	//保证SDA引脚为输出模式
	sda_pin_mode(GPIO_Mode_OUT);

	SDA_W=0;
	SCL_W=0;
	delay_us(1);
	

	if(ack)
		SDA_W=1;
	else
		SDA_W=0;

	delay_us(1);

	//时钟线拉高,数据有效
	SCL_W=1;
	delay_us(1);


	//时钟线拉低,数据变更
	SCL_W=0;
	delay_us(1);		
}

uint8_t i2c_wait_ack(void)
{
	uint8_t ack=0;
	//保证SDA引脚为输入模式
	sda_pin_mode(GPIO_Mode_IN);

	//时钟线拉高,数据有效
	SCL_W=1;
	delay_us(1);
	
	//读取SDA引脚电平
	if(SDA_R)
		ack=1;//无应答
	else
		ack=0;//有应答

	//时钟线拉低,保持占用总线,总线是忙状态
	SCL_W=0;
	delay_us(1);


	return ack;
}

void IIC_WriteBytes(u8 WriteAddr,u8* data,u8 dataLength)
{		
	u8 i;	
    i2c_start();  

	i2c_send_byte(WriteAddr);	    //发送写命令
	i2c_wait_ack();
	
	for(i=0;i<dataLength;i++)
	{
		i2c_send_byte(data[i]);
		i2c_wait_ack();
	}				    	   
    i2c_stop();//产生一个停止条件 
	delay_ms(10);	 
}

void IIC_ReadBytes(u8 deviceAddr, u8 writeAddr,u8* data,u8 dataLength)
{		
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值