//头一次发布博客,博主是机械系的学生。STM32是第一次接触,还恳请大家多多批评指导
第一部分:
设计基于STM32F103RCT6单片机,实现功能主要是:
(1)通过程序实现传感器的启动采集和停止采集。
(2)接收到启动命令MAX30102开始采集,接收到停止命令暂停数据采集。
(3)STM32F103处理传感器采集的数据。通过ZigBee与上位机进行无线通讯。
(4)串口助手显示采集的关键信息。
首先论文实现遇到的问题就是传感器的接线问题,Max30102的SDA(数据线)引脚和SCL(时钟线)引脚分别接程序中单片机定义的的I2C总线连接的GPIO端口。我的设计一开始用的是5、7引脚,但是后面会发现这两个引脚会被其他(LCD)占用,所以必须考虑更换引脚。如果你的不冲突的话那没问题,可以直接这么定义:
#define PORT_I2C_SCL GPIOA /* GPIO端口 */
#define PIN_I2C_SCL GPIO_Pin_5 /* GPIO引脚5 */
#define PORT_I2C_SDA GPIOA /* GPIO端口 */
#define PIN_I2C_SDA GPIO_Pin_7 /* GPIO引脚7 */
#define I2C_SCL_PIN GPIO_Pin_5 /* 连接到SCL时钟线的GPIO5 */
#define I2C_SDA_PIN GPIO_Pin_7 /* 连接到SDA数据线的GPIO7 */
编程环境是K5,要驱动传感器先找到I2C的头文件“#define max30102_WR_address 0xAE”。然后进行通讯测试,看是否可以正常通讯,采用串行EEPROM随即读取指令序列,连续读取若干字节 :
第1步:发起I2C总线启动信号
第2步:发起控制字节,高7bit是地址,bit0是读写控制位,0表示写,1表示读
第3步:发送ACK
第4步:发送字节地址
第5步:开始写入数据第6步:发送ACK ,发送I2C总线停止信号
第7步:命令执行失败后,切记发送停止信号,避免影响I2C总线上其他设备发送I2C总线停止信号 。接下来就是测试I2C总线的收发信号是否正常,步骤和上面差不多。
下一步就考虑数据采集存放的问题,我们需要定义四个数组,分别用来存取传感器采集的数据:
uint32_t red_led_min,red_min[10],red_led_max,red_max[10];
uint32_t ir_led_min,ir_min[10],ir_led_max,ir_max[10];
接着就是I2C和MAX30102读取数据的测试:
{
uint32_t un_temp;*pun_ir_led = 0;
*pun_red_led = 0;
/* 第1步:发起I2C总线启动信号 */
i2c_Start();
/* 第2步:发起控制字节,高7bit是地址,bit0是读写控制位,0表示写,1表示读 */
i2c_SendByte(max30102_WR_address | I2C_WR); /* 此处是写指令 */
/* 第3步:发送ACK */
if (i2c_WaitAck() != 0)
{
goto cmd_fail; /* EEPROM器件无应答 */
}
/* 第4步:发送字节地址, */
i2c_SendByte((uint8_t)REG_FIFO_DATA);
if (i2c_WaitAck() != 0)
{
goto cmd_fail; /* EEPROM器件无应答 */
}
/* 第6步:重新启动I2C总线。下面开始读取数据 */
i2c_Start();
/* 第7步:发起控制字节,高7bit是地址,bit0是读写控制位,0表示写,1表示读 */
i2c_SendByte(max30102_WR_address | I2C_RD); /* 此处是读指令 */
/* 第8步:发送ACK */
if (i2c_WaitAck() != 0)
{
goto cmd_fail; /* EEPROM器件无应答 */
}
un_temp = i2c_ReadByte();
i2c_Ack();
un_temp <<= 16;
*pun_red_led += un_temp;
un_temp = i2c_ReadByte();
i2c_Ack();
un_temp <<= 8;
*pun_red_led += un_temp;
un_temp = i2c_ReadByte();
i2c_Ack();
*pun_red_led += un_temp;
un_temp = i2c_ReadByte();
.........................................................................//ir_led 一样也一段
i2c_Ack();
*pun_ir_led += un_temp;
*pun_red_led &= 0x03FFFF; //Mask MSB [23:18]
.......................................................................//ir_led 一样也一段
/* 发送I2C总线停止信号 */
// i2c_Stop();
// return true;
cmd_fail: /* 命令执行失败后,切记发送停止信号,避免影响I2C总线上其他设备 */
/* 发送I2C总线停止信号 */
i2c_Stop();
}
到这边第一部分差不多结束,主要写了Max30102如何与STM32F103进行数据传输。第二部分是液晶屏和算法。