打印
[AIROC™ 蓝牙]

【英飞凌CYW20829测评】进阶任务:I2C主设备收发

[复制链接]
399|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 mingxiangjun 于 2024-7-14 18:25 编辑

进阶任务: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原始值,但校准可能不太对,计算有问题:

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

7

主题

36

帖子

0

粉丝