基于STM32F4的智能手表(HAl库)

          玩具共4个功能,心率(hp6),血压测量(hp6),6轴陀螺仪计步(mpu6050),温湿度获取(sh20t).

         hp6模块介绍

               

        HP6与主机间通信协议适用于i2c接口通信,7bite硬件地址(0x66);通信速率为100k,HP6与主机间通信对时序较为严格,软件模拟io口速率为建议设置为50MHZ,模拟i2c间加适量延时,等待从机响应,陀螺仪与温湿度可设置100MHZ,且不用加延时等待。

        协议信息

1.开始血压测量

//开启血压测量
const uint8_t cmd_bp_open[]=
        {0xc8,0xd7,0xb6,0xa5,0x90,0x01,0x00,0x00,
         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

2.关闭血压测量

//关闭血压测量
const uint8_t cmd_bp_close[]=
        {0xc8,0xd7,0xb6,0xa5,0x90,0x00,0x00,0x00,
         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

3.读取血压测量信息

//获取血压测量结果
const uint8_t cmd_bp_result[]=
        {0xc8,0xd7,0xb6,0xa5,0x90,0x02,0x00,0x00,
         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

buff[10]高压  buff[11]低压

4.开启心率测量

//开启心率测量
const uint8_t cmd_rate_open[]=
        {0xc8,0xd7,0xb6,0xa5,0xD0,0x01,0x00,0x00,
         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

5.关闭心率测量

//关闭心率测量
const uint8_t cmd_rate_close[]=
        {0xc8,0xd7,0xb6,0xa5,0xD0,0x00,0x00,0x00,
         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

6.读取心率信息

//获取心率测量结果
const uint8_t cmd_rate_result[]=
        {0xc8,0xd7,0xb6,0xa5,0xD0,0x02,0x00,0x00,
         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

buff【7】心率结果

7.低功耗

8.校验算法

const uint16_t crc16_tab[256] =
        {
                0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
                0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
                0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
                0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
                0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
                0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
                0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
                0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
                0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
                0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
                0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
                0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
                0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
                0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
                0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
                0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
                0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
                0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
                0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
                0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
                0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
                0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
                0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
                0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
                0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
                0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
                0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
                0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
                0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
                0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
                0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
                0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
        };
uint16_t Crc16(uint8_t *data,uint16_t len)
{
    uint16_t crc16 = 0xFFFF;
    uint32_t uIndex ; //CRC查询表索引
    while (len --)
    {
        uIndex = (crc16&0xff) ^ ((*data) & 0xff) ; //计算CRC
        data = data + 1;
        crc16 = ((crc16>>8) & 0xff) ^ crc16_tab[uIndex];
    }
    return crc16 ;//返回CRC校验值
}

六轴陀螺仪

六轴分别测了x,y,z的加速度(acc)和角速度(gry),陀螺仪初始化代码如下

陀螺仪用i2c接口,我用软件i2c

#define	MPU6050_SMPLRT_DIV		0x19
#define	MPU6050_CONFIG			0x1A
#define	MPU6050_GYRO_CONFIG		0x1B
#define	MPU6050_ACCEL_CONFIG	0x1C

#define	MPU6050_ACCEL_XOUT_H	0x3B
#define	MPU6050_ACCEL_XOUT_L	0x3C
#define	MPU6050_ACCEL_YOUT_H	0x3D
#define	MPU6050_ACCEL_YOUT_L	0x3E
#define	MPU6050_ACCEL_ZOUT_H	0x3F
#define	MPU6050_ACCEL_ZOUT_L	0x40
#define	MPU6050_TEMP_OUT_H		0x41
#define	MPU6050_TEMP_OUT_L		0x42
#define	MPU6050_GYRO_XOUT_H		0x43
#define	MPU6050_GYRO_XOUT_L		0x44
#define	MPU6050_GYRO_YOUT_H		0x45
#define	MPU6050_GYRO_YOUT_L		0x46
#define	MPU6050_GYRO_ZOUT_H		0x47
#define	MPU6050_GYRO_ZOUT_L		0x48

#define	MPU6050_PWR_MGMT_1		0x6B
#define	MPU6050_PWR_MGMT_2		0x6C
#define	MPU6050_WHO_AM_I		0x75
#define MPU6050_ADDRESS		0xD0		//MPU6050的I2C从机地址

/**
  * 函    数:MPU6050写寄存器
  * 参    数:RegAddress 寄存器地址,范围:参考MPU6050手册的寄存器描述
  * 参    数:Data 要写入寄存器的数据,范围:0x00~0xFF
  * 返 回 值:无
  */
void MPU6050_WriteReg(uint8_t RegAddress, uint8_t Data)
{
    MyI2C_Start();						//I2C起始
    MyI2C_SendByte(MPU6050_ADDRESS);	//发送从机地址,读写位为0,表示即将写入
    MyI2C_ReceiveAck();					//接收应答
    MyI2C_SendByte(RegAddress);			//发送寄存器地址
    MyI2C_ReceiveAck();					//接收应答
    MyI2C_SendByte(Data);				//发送要写入寄存器的数据
    MyI2C_ReceiveAck();					//接收应答
    MyI2C_Stop();						//I2C终止
}

/**
  * 函    数:MPU6050读寄存器
  * 参    数:RegAddress 寄存器地址,范围:参考MPU6050手册的寄存器描述
  * 返 回 值:读取寄存器的数据,范围:0x00~0xFF
  */
uint8_t MPU6050_ReadReg(uint8_t RegAddress)
{
    uint8_t Data;

    MyI2C_Start();						//I2C起始
    MyI2C_SendByte(MPU6050_ADDRESS);	//发送从机地址,读写位为0,表示即将写入
    MyI2C_ReceiveAck();					//接收应答
    MyI2C_SendByte(RegAddress);			//发送寄存器地址
    MyI2C_ReceiveAck();					//接收应答

    MyI2C_Start();						//I2C重复起始
    MyI2C_SendByte(MPU6050_ADDRESS | 0x01);	//发送从机地址,读写位为1,表示即将读取
    MyI2C_ReceiveAck();					//接收应答
    Data = MyI2C_ReceiveByte();			//接收指定寄存器的数据
    MyI2C_SendAck(1);					//发送应答,给从机非应答,终止从机的数据输出
    MyI2C_Stop();						//I2C终止

    return Data;
}

/**
  * 函    数:MPU6050初始化
  * 参    数:无
  * 返 回 值:无
  */
void MPU6050_Init(void)
{
    								//先初始化底层的I2C

    /*MPU6050寄存器初始化,需要对照MPU6050手册的寄存器描述配置,此处仅配置了部分重要的寄存器*/
    MPU6050_WriteReg(MPU6050_PWR_MGMT_1, 0x01);		//电源管理寄存器1,取消睡眠模式,选择时钟源为X轴陀螺仪
    MPU6050_WriteReg(MPU6050_PWR_MGMT_2, 0x00);		//电源管理寄存器2,保持默认值0,所有轴均不待机
    MPU6050_WriteReg(MPU6050_SMPLRT_DIV, 0x09);		//采样率分频寄存器,配置采样率
    MPU6050_WriteReg(MPU6050_CONFIG, 0x06);			//配置寄存器,配置DLPF
    MPU6050_WriteReg(MPU6050_GYRO_CONFIG, 0x18);	//陀螺仪配置寄存器,选择满量程为±2000°/s
    MPU6050_WriteReg(MPU6050_ACCEL_CONFIG, 0x18);	//加速度计配置寄存器,选择满量程为±16g
}

/**
  * 函    数:MPU6050获取ID号
  * 参    数:无
  * 返 回 值:MPU6050的ID号
  */
uint8_t MPU6050_GetID(void)
{
    return MPU6050_ReadReg(MPU6050_WHO_AM_I);		//返回WHO_AM_I寄存器的值
}

/**
  * 函    数:MPU6050获取数据
  * 参    数:AccX AccY AccZ 加速度计X、Y、Z轴的数据,使用输出参数的形式返回,范围:-32768~32767
  * 参    数:GyroX GyroY GyroZ 陀螺仪X、Y、Z轴的数据,使用输出参数的形式返回,范围:-32768~32767
  * 返 回 值:无
  */
void MPU6050_GetData(int16_t *AccX, int16_t *AccY, int16_t *AccZ,
                     int16_t *GyroX, int16_t *GyroY, int16_t *GyroZ)
{
    uint8_t DataH, DataL;								//定义数据高8位和低8位的变量

    DataH = MPU6050_ReadReg(MPU6050_ACCEL_XOUT_H);		//读取加速度计X轴的高8位数据
    DataL = MPU6050_ReadReg(MPU6050_ACCEL_XOUT_L);		//读取加速度计X轴的低8位数据
    *AccX = (DataH << 8) | DataL;						//数据拼接,通过输出参数返回

    DataH = MPU6050_ReadReg(MPU6050_ACCEL_YOUT_H);		//读取加速度计Y轴的高8位数据
    DataL = MPU6050_ReadReg(MPU6050_ACCEL_YOUT_L);		//读取加速度计Y轴的低8位数据
    *AccY = (DataH << 8) | DataL;						//数据拼接,通过输出参数返回

    DataH = MPU6050_ReadReg(MPU6050_ACCEL_ZOUT_H);		//读取加速度计Z轴的高8位数据
    DataL = MPU6050_ReadReg(MPU6050_ACCEL_ZOUT_L);		//读取加速度计Z轴的低8位数据
    *AccZ = (DataH << 8) | DataL;						//数据拼接,通过输出参数返回

    DataH = MPU6050_ReadReg(MPU6050_GYRO_XOUT_H);		//读取陀螺仪X轴的高8位数据
    DataL = MPU6050_ReadReg(MPU6050_GYRO_XOUT_L);		//读取陀螺仪X轴的低8位数据
    *GyroX = (DataH << 8) | DataL;						//数据拼接,通过输出参数返回

    DataH = MPU6050_ReadReg(MPU6050_GYRO_YOUT_H);		//读取陀螺仪Y轴的高8位数据
    DataL = MPU6050_ReadReg(MPU6050_GYRO_YOUT_L);		//读取陀螺仪Y轴的低8位数据
    *GyroY = (DataH << 8) | DataL;						//数据拼接,通过输出参数返回

    DataH = MPU6050_ReadReg(MPU6050_GYRO_ZOUT_H);		//读取陀螺仪Z轴的高8位数据
    DataL = MPU6050_ReadReg(MPU6050_GYRO_ZOUT_L);		//读取陀螺仪Z轴的低8位数据
    *GyroZ = (DataH << 8) | DataL;						//数据拼接,通过输出参数返回
}

温湿度sh20t也采用i2c接口废话不多说我们直接上代码

#define SHT20ADDR       0x80         //SHT20写地址
#define ACK             0            //应答信号
#define NACK            1            //非应答信号
#define FAIL            1            //读取温湿度失败的返回值。
#define READ_TEMP_COMD  0xf3         //读取温度命令
#define READ_HUMI_COMD  0xf5         //读取湿度命令
#define u8 uint8_t
#define  u16 uint16_t
#define  u32 uint32_t
/*******************************************************************************
 * TYPEDEFS
 */


/*******************************************************************************
 * LOCAL VARIABLES
 */
TempHumiValue_t temp_humi_Value;

/*******************************************************************************
 * LOCAL FUNCTIONS
 */
static void SHT20_setResolution(void);
static void SHT20_setResolution(void);
void SHT20_softReset(void);
/*******************************************************************************
 * PROFILE CALLBACKS
 */



/*******************************************************************************
 * PUBLIC FUNCTIONS
 */
/*******************************************************************************
* 函数名:SHT20_writeOneByte
* 功能描述:写一个字节
* 作者:Jahol Fan
* 参数说明:  写一个字节的数据
* 返回值说明:返回的是应答信号
* 修改记录:
*******************************************************************************/
static u8 SHT20_writeOneByte(u8 dataToWrite)
{
    u8 ack;
    MyI2C_SendByte(dataToWrite);
    ack= MyI2C_ReceiveAck();

    return ack;
}
/*******************************************************************************
* 函数名:SHT20_softReset
* 功能描述:SHT20软件复位,主函数中调用
* 作者:Jahol Fan
* 参数说明:
* 返回值说明:
* 修改记录:
*******************************************************************************/
void SHT20_softReset(void)
{
    MyI2C_Start();                   //start I2C
    SHT20_writeOneByte(SHT20ADDR&0xfe);  //I2C address + write
    SHT20_writeOneByte(0xfe);                         //soft reset
    MyI2C_Stop();                     //stop I2C
}
/*******************************************************************************
* 函数名:SHT20_Init
* 功能描述:初始化iic总线
* 作者:Jahol Fan
* 参数说明:
* 返回值说明:成功返回测量的结果,失败返回 1
* 修改记录:
*******************************************************************************/
void SHT20_Init(void)
{

    SHT20_softReset();
}
/*******************************************************************************
* 函数名:SHT20_readOneByte
* 功能描述:读一个字节
* 作者:Jahol Fan
* 参数说明:
* 返回值说明:
* 修改记录:
*******************************************************************************/
static u8 SHT20_readOneByte(u8 ack)
{
    u8 temp;
    temp=MyI2C_ReceiveByte();
    MyI2C_SendAck(ack);
    return temp;
}


/*******************************************************************************
 * 函数名:SHT20_setResolution
 * 功能描述:写寄存器,设置帧率
 * 作者:Jahol Fan
 * 参数说明:
 * 返回值说明:
 * 修改记录:
*******************************************************************************/
static void SHT20_setResolution(void)
{
    MyI2C_Start();                                                                       //Start I2C
    if(SHT20_writeOneByte(SHT20ADDR&0xfe)==ACK)             //I2C address + write + ACK
    {
        if(SHT20_writeOneByte(0xe6)==ACK)                               //写用户寄存器
        {
            if(SHT20_writeOneByte(0x83)==ACK);    //设置分辨率   11bit RH% 测量时间:12ms(typ.) & 11bit T℃ 测量时间:9ms(typ.)
        }
    }
    MyI2C_Stop();                                 //Stop I2C
}
/*******************************************************************************
 * 函数名:SHT20_readTemOrHum
 * 功能描述:读取SHT20的温度或读取湿度测量值
 * 作者:Jahol Fan
 * 参数说明:
 * 返回值说明:成功返回测量的结果,失败返回 1
 * 修改记录:
*******************************************************************************/
float SHT20_readTemOrHum(u8 commod)
{
    float temp;                 //温度
    u8 ack=1;
    u8  MSB,LSB;              //温度、相对湿度的寄存器数据
    float Humidity,Temperature; //温湿度的转换结果

    SHT20_setResolution();           //设置帧率8bit,9bit,10 bit,11bit ,12bit,13bit,14bit
    MyI2C_Start();                   //iic开始信号
    ack = SHT20_writeOneByte(SHT20ADDR&0xfe);
    if( ack == ACK )                //写地址,并等待ACK
    {
        if(SHT20_writeOneByte(commod)==ACK)                      //写命令
        {
            do
            {
             HAL_Delay(6);                                      //延时
                MyI2C_Start();                                       //发送开始信号
            }while(SHT20_writeOneByte(SHT20ADDR|0x01)==NACK);      //无应答则整形,还在测量中,如果有应答,则结束当前循环

            MSB = SHT20_readOneByte(ACK);                          //读Data(MSB),给应答ACK
            LSB = SHT20_readOneByte(ACK);                          //读Data(LSB),给应答ACK
            SHT20_readOneByte(NACK);                               //读Checksum ,不给应答NACK
            MyI2C_Stop();                                          //Stop I2C
            LSB &= 0xfc;                                       //Data (LSB) 的后两位在进行物理计算前前须置‘0’
            temp = MSB*256 + LSB;                              //十六进制转成十进制

            if (commod==((u8)READ_HUMI_COMD))                         //命令为读取湿度的命令
            {
                /*-- calculate relative humidity [%RH] --*/
                Humidity =(temp*125)/65536-6;                   //公式: RH%= -6 + 125 * SRH/2^16
                return Humidity;                                //返回值:humidity
            }
            else if(commod==((u8)READ_TEMP_COMD))                     //命令为读取温度的命令
            {
                /*-- calculate temperature [°C] --*/
                Temperature = (temp*175.72f)/65536-46.85f;       //公式:T= -46.85 + 175.72 * ST/2^16
                return Temperature;                             //返回值:temperature
            }
        }
    }
    return FAIL;
}
/*******************************************************************************
 * 函数名:SHT20_readTemAndHum
 * 功能描述:读取SHT20的温度和湿度测量值
 * 作者:Jahol Fan
 * 参数说明:
 * 返回值说明:成功返回测量的结果,失败返回 1
 * 修改记录:
*******************************************************************************/

TempHumiValue_t * SHT20_readTemAndHum(void)
{
    temp_humi_Value.hum = SHT20_readTemOrHum(READ_HUMI_COMD);//读取湿度
    temp_humi_Value.tem = SHT20_readTemOrHum(READ_TEMP_COMD);//读取湿度
    return &temp_humi_Value;
}

  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值