[AIROC™ 蓝牙]【英飞凌CYW20829测评】进阶任务:I2C主设备收发

进阶任务:I2C主设备收发
一、说明
    I2C总线具有很好的主从仲裁逻辑,本次使用P4.0做SCL,P4.1做SDA进行通信,读取气压计BMP180的温度和气压数据。而BMP180传感器的从设备地址为0xEE。
 
二、编码
    底层对接层i2c_comm.c:
复制
#include "i2c_comm.h"

#include <string.h>

void I2cWriteRegister(uint8_tslave_addr,uint8_t reg_addr,uint8_t instword)

{

    uint8_twrBuff[2];

    wrBuff[0]=reg_addr;

    wrBuff[1]=instword;

    cyhal_i2c_master_write(&mI2C,slave_addr,wrBuff,2,0,true);

}

void I2cWriteRegisters(uint8_tslave_addr,uint8_t reg_addr,uint8_tinstword[],uint8_t len)

{

    uint8_twrBuff[len+1];

    wrBuff[0]=reg_addr;

    memcpy(wrBuff+1,instword,len);

    cyhal_i2c_master_write(&mI2C,slave_addr,wrBuff,len+1,0,true);

}

uint8_t I2cReadRegister(uint8_tslave_addr,uint8_t reg_addr)

{

    uint8_t rdBuff=0;

    cyhal_i2c_master_write(&mI2C,slave_addr,®_addr,1,0,true);

    cyhal_i2c_master_read(&mI2C,slave_addr,&rdBuff,1,0,true);

    return rdBuff;

}

uint16_t I2cReadWord(uint8_tslave_addr,uint8_t reg_addr)

{

    uint8_trdBuff[2];

    cyhal_i2c_master_write(&mI2C,slave_addr,®_addr,1,0,true);

    cyhal_i2c_master_read(&mI2C,slave_addr,rdBuff,2,0,true);

   return (((uint16_t)rdBuff[0]))<<8|(rdBuff[1]);

}

void I2cReadRegisters(uint8_tslave_addr,uint8_t reg_addr,uint8_t*p_buffer,uint8_t num)

{

    uint8_trdBuff[num];

    cyhal_i2c_master_write(&mI2C,slave_addr,®_addr,1,0,true);

    cyhal_i2c_master_read(&mI2C,slave_addr,rdBuff,num,0,true);

}
传感器驱动层sensor_bmp180.h:
复制
#ifndef_SENSOR_BMP180_H

#define_SENSOR_BMP180_H

#define BMP180 1

#if BMP180

#define BMP180_SA           0x77   //0xEE

#define BMP180_MANUID       0x55

#define RESET               0xB6

#define OSS 0              //oversamplingsetting(pressure)

#define REG_OUT_XLSB       (0xF8)

#define REG_OUT_LSB        (0xF7)

#define REG_OUT_MSB        (0xF6)

#define REG_CTRL_MEAS      (0xF4)

#define REG_RESET          (0XE0)

#define REG_MANUID         (0XD0)

#define REG_AC1            (0xAA)    //便于理解,提高可阅读性

#define REG_AC2            (0xAC)

#define REG_AC3            (0xAE)

#define REG_AC4            (0xB0)

#define REG_AC5            (0xB2)

#define REG_AC6            (0xB4)

#define REG_B1             (0xB6)

#define REG_B2             (0xB8)

#define REG_MB             (0xBA)

#define REG_MC             (0xBC)

#define REG_MD             (0xBE)

extern short ac1,ac2,ac3,b1,b2;//EEPROM的11个校正系数(全局变量)

extern unsigned shortac4,ac5,ac6;

extern short mb,mc,md;

void delay(uint32_t n);

void BMP180_Init(void);

long BMP180_ReadTemperature(void);

long BMP180_ReadPressure(void);

extern void BMP180_Calibration(longtemp,long press);

#endif  //BMP180

#endif  //_SENSOR_BMP180_H
传感器驱动文件sensor_bmp180.c:
复制
#include "sensor_BMP180.h"

#include "i2c_comm.h"

#include <stdio.h>

void delay(uint32_t n)

{

    cyhal_system_delay_ms(n);

}

void BMP180_Init(void)

{   

    uint8_t manu_id=0;//uint8_t coeff[22];

   manu_id=I2cReadRegister(BMP180_SA,REG_MANUID);

    printf("ChipID=0x%x\r\n",manu_id);

    if(manu_id==BMP180_MANUID)

    {   

        ac1=I2cReadWord(BMP180_SA,REG_AC1);

        ac2=I2cReadWord(BMP180_SA,REG_AC2);

        ac3=I2cReadWord(BMP180_SA,REG_AC3);

        ac4=I2cReadWord(BMP180_SA,REG_AC4);

        ac5=I2cReadWord(BMP180_SA,REG_AC5);

        ac6=I2cReadWord(BMP180_SA,REG_AC6);

        b1=I2cReadWord(BMP180_SA,REG_B1);

        b2=I2cReadWord(BMP180_SA,REG_B2);

        mb=I2cReadWord(BMP180_SA,REG_MB);

        mc=I2cReadWord(BMP180_SA,REG_MC);

        md=I2cReadWord(BMP180_SA,REG_MD);               

    }

    printf("%d%d %d %d %d %d %d %d %d %d %d\r\n",ac1,ac2,ac3,ac4,ac5,ac6,b1,b2,mb,mc,md);

}

long BMP180_ReadTemperature()

{   

    uint8_t tempdata[2];uint8_ti;

    long ut;

   I2cWriteRegister(BMP180_SA,REG_CTRL_MEAS,0x2E);//ADC

    delay(50);

    I2cReadRegisters(BMP180_SA,REG_OUT_MSB,tempdata,2);

   ut=tempdata[1] | ((uint16_t)tempdata[0])<<8;

    printf("Getut data:%d ",(int)ut);

    for(i=0;i<2;i++)

        printf("%d",tempdata);

    return ut;

}

long BMP180_ReadPressure()  //ultra low power mode

{   

    uint8_t pressdata[3];uint8_tn;

    long up;

   I2cWriteRegister(BMP180_SA,REG_CTRL_MEAS,0x34);//ADC

    delay(50);

   I2cReadRegisters(BMP180_SA,REG_OUT_MSB,pressdata,3);

    up=((uint32_t)pressdata[2] | ((uint32_t)pressdata[1])<<8| \

       ((uint32_t)pressdata[0])<<16)>>(8-OSS);

    printf("\r\nGetup data:%d",(int)up);

    for(n=0;n<3;n++)

        printf("%d",pressdata[n]);  

    return up;

}

extern void BMP180_Calibration(longtemp,long press) 

{   

    long x1,x2,x3,b3,b5,b6;

    unsigned longb4,b7,p;

    long up,ut;

   ut=BMP180_ReadTemperature();

   up=BMP180_ReadPressure();

    x1 = ((long)ut - (long)ac6)* (long)ac5 >> 15;

    x2 = ((long) mc << 11) / (x1 + md);

    b5 = x1 + x2;

    temp = (b5 +8) >> 4;

   

    b6 = b5 -4000;

    x1 = (b2 * (b6* b6 >> 12)) >> 11;

    x2 = ac2 * b6>> 11;

    x3 = x1 + x2;

    b3 = ((((long)ac1 * 4 + x3)<<OSS) + 2)/4;

    x1 = ac3 * b6>> 13;

    x2 = (b1 * (b6* b6 >> 12)) >> 16;

    x3 = ((x1 +x2) + 2) >> 2;

    b4 = (ac4 * (unsigned long)(x3 + 32768)) >> 15;

    b7 = ((unsigned long)up - b3) * (50000 >> OSS);

    if( b7 < 0x80000000)

         p = (b7 * 2) / b4 ;

    else  

         p = (b7 / b4) * 2;

    x1 = (p>> 8) * (p >> 8);

    x1 = (x1 *3038) >> 16;

    x2 = (-7357 *(long)p) >> 16;

    press = p +((x1 + x2 + 3791) >> 4);

    printf("\n%ld%ld",temp,press);

    printf("\nTemp:%ld.%ldDegC,Press:%ld Pa",temp/10,temp%10,press);

}
 
三、效果
    有成功读出11个补偿系数、芯片ID和ADC原始值,但校准可能不太对,计算有问题:


---------------------
作者:mingxiangjun
链接:https://bbs.21ic.com/icview-3389380-1-1.html
来源:21ic.com
此文章已获得原创/原创奖标签,著作权归21ic所有,任何人未经允许禁止转载。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值