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

[复制链接]
 楼主| mingxiangjun 发表于 2024-7-14 18:18 | 显示全部楼层 |阅读模式
<
本帖最后由 mingxiangjun 于 2024-7-14 18:25 编辑

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

二、编码
    底层对接层i2c_comm.c:
  1. #include "i2c_comm.h"
  2. #include <string.h>
  3. void I2cWriteRegister(uint8_tslave_addr,uint8_t reg_addr,uint8_t instword)
  4. {
  5.     uint8_twrBuff[2];
  6.     wrBuff[0]=reg_addr;
  7.     wrBuff[1]=instword;
  8.     cyhal_i2c_master_write(&mI2C,slave_addr,wrBuff,2,0,true);
  9. }
  10. void I2cWriteRegisters(uint8_tslave_addr,uint8_t reg_addr,uint8_tinstword[],uint8_t len)
  11. {
  12.     uint8_twrBuff[len+1];
  13.     wrBuff[0]=reg_addr;
  14.     memcpy(wrBuff+1,instword,len);
  15.     cyhal_i2c_master_write(&mI2C,slave_addr,wrBuff,len+1,0,true);
  16. }
  17. uint8_t I2cReadRegister(uint8_tslave_addr,uint8_t reg_addr)
  18. {
  19.     uint8_t rdBuff=0;
  20.     cyhal_i2c_master_write(&mI2C,slave_addr,®_addr,1,0,true);
  21.     cyhal_i2c_master_read(&mI2C,slave_addr,&rdBuff,1,0,true);
  22.     return rdBuff;
  23. }
  24. uint16_t I2cReadWord(uint8_tslave_addr,uint8_t reg_addr)
  25. {
  26.     uint8_trdBuff[2];
  27.     cyhal_i2c_master_write(&mI2C,slave_addr,®_addr,1,0,true);
  28.     cyhal_i2c_master_read(&mI2C,slave_addr,rdBuff,2,0,true);
  29.    return (((uint16_t)rdBuff[0]))<<8|(rdBuff[1]);
  30. }
  31. void I2cReadRegisters(uint8_tslave_addr,uint8_t reg_addr,uint8_t*p_buffer,uint8_t num)
  32. {
  33.     uint8_trdBuff[num];
  34.     cyhal_i2c_master_write(&mI2C,slave_addr,®_addr,1,0,true);
  35.     cyhal_i2c_master_read(&mI2C,slave_addr,rdBuff,num,0,true);
  36. }
传感器驱动层sensor_bmp180.h:
  1. #ifndef_SENSOR_BMP180_H
  2. #define_SENSOR_BMP180_H
  3. #define BMP180 1
  4. #if BMP180
  5. #define BMP180_SA           0x77   //0xEE
  6. #define BMP180_MANUID       0x55
  7. #define RESET               0xB6
  8. #define OSS 0              //oversamplingsetting(pressure)
  9. #define REG_OUT_XLSB       (0xF8)
  10. #define REG_OUT_LSB        (0xF7)
  11. #define REG_OUT_MSB        (0xF6)
  12. #define REG_CTRL_MEAS      (0xF4)
  13. #define REG_RESET          (0XE0)
  14. #define REG_MANUID         (0XD0)
  15. #define REG_AC1            (0xAA)    //便于理解,提高可阅读性
  16. #define REG_AC2            (0xAC)
  17. #define REG_AC3            (0xAE)
  18. #define REG_AC4            (0xB0)
  19. #define REG_AC5            (0xB2)
  20. #define REG_AC6            (0xB4)
  21. #define REG_B1             (0xB6)
  22. #define REG_B2             (0xB8)
  23. #define REG_MB             (0xBA)
  24. #define REG_MC             (0xBC)
  25. #define REG_MD             (0xBE)
  26. extern short ac1,ac2,ac3,b1,b2;//EEPROM的11个校正系数(全局变量)
  27. extern unsigned shortac4,ac5,ac6;
  28. extern short mb,mc,md;
  29. void delay(uint32_t n);
  30. void BMP180_Init(void);
  31. long BMP180_ReadTemperature(void);
  32. long BMP180_ReadPressure(void);
  33. extern void BMP180_Calibration(longtemp,long press);
  34. #endif  //BMP180
  35. #endif  //_SENSOR_BMP180_H
传感器驱动文件sensor_bmp180.c:
  1. #include "sensor_BMP180.h"
  2. #include "i2c_comm.h"
  3. #include <stdio.h>
  4. void delay(uint32_t n)
  5. {
  6.     cyhal_system_delay_ms(n);
  7. }
  8. void BMP180_Init(void)
  9. {   
  10.     uint8_t manu_id=0;//uint8_t coeff[22];
  11.    manu_id=I2cReadRegister(BMP180_SA,REG_MANUID);
  12.     printf("ChipID=0x%x\r\n",manu_id);
  13.     if(manu_id==BMP180_MANUID)
  14.     {   
  15.         ac1=I2cReadWord(BMP180_SA,REG_AC1);
  16.         ac2=I2cReadWord(BMP180_SA,REG_AC2);
  17.         ac3=I2cReadWord(BMP180_SA,REG_AC3);
  18.         ac4=I2cReadWord(BMP180_SA,REG_AC4);
  19.         ac5=I2cReadWord(BMP180_SA,REG_AC5);
  20.         ac6=I2cReadWord(BMP180_SA,REG_AC6);
  21.         b1=I2cReadWord(BMP180_SA,REG_B1);
  22.         b2=I2cReadWord(BMP180_SA,REG_B2);
  23.         mb=I2cReadWord(BMP180_SA,REG_MB);
  24.         mc=I2cReadWord(BMP180_SA,REG_MC);
  25.         md=I2cReadWord(BMP180_SA,REG_MD);               
  26.     }
  27.     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);
  28. }
  29. long BMP180_ReadTemperature()
  30. {   
  31.     uint8_t tempdata[2];uint8_ti;
  32.     long ut;
  33.    I2cWriteRegister(BMP180_SA,REG_CTRL_MEAS,0x2E);//ADC
  34.     delay(50);
  35.     I2cReadRegisters(BMP180_SA,REG_OUT_MSB,tempdata,2);
  36.    ut=tempdata[1] | ((uint16_t)tempdata[0])<<8;
  37.     printf("Getut data:%d ",(int)ut);
  38.     for(i=0;i<2;i++)
  39.         printf("%d",tempdata);
  40.     return ut;
  41. }
  42. long BMP180_ReadPressure()  //ultra low power mode
  43. {   
  44.     uint8_t pressdata[3];uint8_tn;
  45.     long up;
  46.    I2cWriteRegister(BMP180_SA,REG_CTRL_MEAS,0x34);//ADC
  47.     delay(50);
  48.    I2cReadRegisters(BMP180_SA,REG_OUT_MSB,pressdata,3);
  49.     up=((uint32_t)pressdata[2] | ((uint32_t)pressdata[1])<<8| \
  50.        ((uint32_t)pressdata[0])<<16)>>(8-OSS);
  51.     printf("\r\nGetup data:%d",(int)up);
  52.     for(n=0;n<3;n++)
  53.         printf("%d",pressdata[n]);  
  54.     return up;
  55. }
  56. extern void BMP180_Calibration(longtemp,long press)
  57. {   
  58.     long x1,x2,x3,b3,b5,b6;
  59.     unsigned longb4,b7,p;
  60.     long up,ut;
  61.    ut=BMP180_ReadTemperature();
  62.    up=BMP180_ReadPressure();
  63.     x1 = ((long)ut - (long)ac6)* (long)ac5 >> 15;
  64.     x2 = ((long) mc << 11) / (x1 + md);
  65.     b5 = x1 + x2;
  66.     temp = (b5 +8) >> 4;
  67.    
  68.     b6 = b5 -4000;
  69.     x1 = (b2 * (b6* b6 >> 12)) >> 11;
  70.     x2 = ac2 * b6>> 11;
  71.     x3 = x1 + x2;
  72.     b3 = ((((long)ac1 * 4 + x3)<<OSS) + 2)/4;
  73.     x1 = ac3 * b6>> 13;
  74.     x2 = (b1 * (b6* b6 >> 12)) >> 16;
  75.     x3 = ((x1 +x2) + 2) >> 2;
  76.     b4 = (ac4 * (unsigned long)(x3 + 32768)) >> 15;
  77.     b7 = ((unsigned long)up - b3) * (50000 >> OSS);
  78.     if( b7 < 0x80000000)
  79.          p = (b7 * 2) / b4 ;
  80.     else  
  81.          p = (b7 / b4) * 2;
  82.     x1 = (p>> 8) * (p >> 8);
  83.     x1 = (x1 *3038) >> 16;
  84.     x2 = (-7357 *(long)p) >> 16;
  85.     press = p +((x1 + x2 + 3791) >> 4);
  86.     printf("\n%ld%ld",temp,press);
  87.     printf("\nTemp:%ld.%ldDegC,Press:%ld Pa",temp/10,temp%10,press);
  88. }

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

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
您需要登录后才可以回帖 登录 | 注册

本版积分规则

7

主题

38

帖子

0

粉丝

7

主题

38

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部