HC32时钟为22.15MHz,继而I2C传输速率如果为100k的话,根据公式
在这里将stcI2cCfg.u8Tm设置为 0x10。
I2C端口定义 SDA -> P25 SCL -> P26
ADS1115写地址可选择0x90,0x92,在这里选择了0x92
废话不多说,先上代码
【ADS1115.c】
#include "ads1115.h" #include "usartApp.h" #include "i2c.h" #define GPIO_I2C_SDA_PORT 2 #define GPIO_I2C_SDA_PIN 5 #define GPIO_I2C_SCL_PORT 2 #define GPIO_I2C_SCL_PIN 6 void I2C_init(void) { stc_i2c_config_t stcI2cCfg; DDL_ZERO_STRUCT(stcI2cCfg); Gpio_InitIOExt(GPIO_I2C_SDA_PORT,GPIO_I2C_SDA_PIN,GpioDirOut,FALSE,FALSE,TRUE,FALSE); Gpio_InitIOExt(GPIO_I2C_SCL_PORT,GPIO_I2C_SCL_PIN,GpioDirOut,FALSE,FALSE,TRUE,FALSE); Gpio_SetFunc_I2CDAT_P25(); Gpio_SetFunc_I2CCLK_P26(); Clk_SetPeripheralGate(ClkPeripheralI2c,TRUE); stcI2cCfg.enFunc = I2cBaud_En; stcI2cCfg.u8Tm = I2C_DRATE; stcI2cCfg.pfnI2cCb = NULL; stcI2cCfg.bTouchNvic = FALSE; I2C_DeInit(); I2C_Init(&stcI2cCfg); I2C_SetFunc(I2cMode_En); } en_result_t I2C_MasterSendStart(uint8_t u8DevAddr, uint8_t channel) { int timeout = 0; I2C_SetFunc(I2cStart_En); // Step5, 发送 Start 信号 I2C_ClearIrq(); timeout = TOUTVAL; while(0 == I2C_GetIrq() || timeout--); if(0x08 != I2C_GetState()) {return Error;} I2C_WriteByte(u8DevAddr); // Step 10-1 I2C_ClearFunc(I2cStart_En); // Step 10-2 I2C_ClearIrq(); // Step 10-3 M0P_I2C->CR_f.SI = 0; timeout = TOUTVAL; while(0 == I2C_GetIrq() || timeout--); // Step 11, 等待 I2Cx_CR.si 变为 1,SLA+W 已发送到总线上 if(0x18 != I2C_GetState()) return Error; do{ I2C_WriteByte(CONF_REG); // Step 13-1 I2C_ClearIrq(); // Step 13-2 I2Cx_CR.si = 0 timeout = TOUTVAL; while(0 == I2C_GetIrq() || timeout--); // Step 14, 等待 I2Cx_CR.si 变为 1,数据已发送到总线上 }while(0x28 != I2C_GetState()); do{ I2C_WriteByte(channel); // Step 13-1 I2C_ClearIrq(); // Step 13-2 timeout = TOUTVAL; while(0 == I2C_GetIrq() || timeout--); // Step 14, 等待 I2Cx_CR.si 变为 1,数据已发送到总线上 }while(0x28 != I2C_GetState()); do{ I2C_WriteByte(0xe3); // Step 13-1 I2C_ClearIrq(); // Step 13-2 timeout = TOUTVAL; while(0 == I2C_GetIrq() || timeout--); // Step 14, 等待 I2Cx_CR.si 变为 1,数据已发送到总线上 }while(0x28 != I2C_GetState()); I2C_ClearIrq(); // Step 15-2 I2Cx_CR.si = 0 I2C_SetFunc(I2cStop_En); // Step 15-1 I2Cx_CR.sto = 1 I2C_ClearIrq(); // Step 15-2 I2Cx_CR.si = 0 timeout = TOUTVAL; while(0 == I2C_GetIrq() || timeout--); // Step 16, 等待 I2Cx_CR.si 变为 1,数据已发送到总线上 return Ok; } uint32_t ADCDataProcess(uint16_t ADC_Readbuff_i[]) { uint32_t adc_rawdata_o; adc_rawdata_o = (ADC_Readbuff_i[0] << 8) + ADC_Readbuff_i[1]; if(adc_rawdata_o >= 0x8000) adc_rawdata_o = ((0xffff - adc_rawdata_o) / 32767.0) * ADS1115_PGA_6144; else adc_rawdata_o = (adc_rawdata_o/32768.0)*ADS1115_PGA_6144; return adc_rawdata_o; } en_result_t I2C_Read(uint8_t u8DevAddr, uint8_t Reg, uint16_t Readbuff[]) { int timeout = 0; I2C_SetFunc(I2cStart_En); // Step5, 发送 Start 信号 I2C_ClearIrq(); timeout = TOUTVAL; while(0 == I2C_GetIrq() || timeout--); if(0x08 != I2C_GetState()) return Error; I2C_WriteByte(u8DevAddr); // Step 10-1 I2C_ClearFunc(I2cStart_En); // Step 10-2 I2C_ClearIrq(); // Step 10-3 M0P_I2C->CR_f.SI = 0; timeout = TOUTVAL; while(0 == I2C_GetIrq() || timeout--); // Step 11, 等待 I2Cx_CR.si 变为 1,SLA+W 已发送到总线上 if(0x18 != I2C_GetState()) return Error; do{ I2C_WriteByte(DATA_REG); // Step 13-1 I2C_ClearIrq(); // Step 13-2 I2Cx_CR.si = 0 timeout = TOUTVAL; while(0 == I2C_GetIrq() || timeout--); // Step 14, 等待 I2Cx_CR.si 变为 1,数据已发送到总线上 }while(0x28 != I2C_GetState()); I2C_ClearIrq(); // Step 15-2 I2Cx_CR.si = 0 I2C_SetFunc(I2cStop_En); // Step 15-1 I2Cx_CR.sto = 1 I2C_ClearIrq(); // Step 15-2 I2Cx_CR.si = 0 timeout = TOUTVAL; while(0 == I2C_GetIrq() || timeout--); // Step 16, 等待 I2Cx_CR.si 变为 1,数据已发送到总线上 I2C_SetFunc(I2cStart_En); // Step5, 发送 Start 信号 I2C_ClearIrq(); timeout = TOUTVAL; while(0 == I2C_GetIrq() || timeout--); if(0x08 != I2C_GetState()) return Error; I2C_WriteByte(Reg); // Step 8-1 I2C_ClearFunc(I2cStart_En); // Step 8-2 CR_f.STA = 0; I2C_ClearIrq(); // Step 8-3 CR_f.SI = 0; timeout = TOUTVAL; while(0 == I2C_GetIrq() || timeout--); // Step 9, 等待 I2Cx_CR.si 变为 1,SLA+W 已发送到总线上 if(0x40 != I2C_GetState()) return Error; I2C_SetFunc(I2cAck_En); // CR_f.AA = 1; I2C_ClearIrq(); // 设置 I2Cx_CR.si 为 0 timeout = TOUTVAL; while(0 == I2C_GetIrq() || timeout--); Readbuff[0] = I2C_ReadByte(); if((0x50 != I2C_GetState())) return Error; I2C_ClearIrq(); // 设置 I2Cx_CR.si 为 0 timeout = TOUTVAL; while(0 == I2C_GetIrq() || timeout--); Readbuff[1] = I2C_ReadByte(); if((0x50 != I2C_GetState())) return Error; I2C_ClearFunc(I2cAck_En); I2C_ClearIrq(); I2C_SetFunc(I2cStop_En); I2C_ClearIrq(); // 设置 I2Cx_CR.si 为 0 timeout = TOUTVAL; while(0 == I2C_GetIrq() || timeout--); // Step 9, 等待 I2Cx_CR.si 变为 1 return Ok; } en_result_t ADS1115Read(uint8_t u8DevAddr, uint8_t Reg, uint32_t *adc_rawdata) { uint16_t ADC_Readbuff[2]; if(I2C_Read(u8DevAddr, Reg, ADC_Readbuff) != Ok){return Error;} //芯片读取数据 *adc_rawdata = ADCDataProcess(ADC_Readbuff); //数据处理 return Ok; } uint32_t Getonevalue(uint8_t chip, uint32_t channel) { uint32_t ADC_data; if(chip == CHIP1){ switch(channel) { case CHANNEL0: I2C_MasterSendStart(WR_REG1, AD_CH0); ADS1115Read(WR_REG1, RE_REG1, &ADC_data); break; case CHANNEL1: I2C_MasterSendStart(WR_REG1, AD_CH1); ADS1115Read(WR_REG1, RE_REG1, &ADC_data); break; case CHANNEL2: I2C_MasterSendStart(WR_REG1, AD_CH2); ADS1115Read(WR_REG1, RE_REG1, &ADC_data); break; case CHANNEL3: I2C_MasterSendStart(WR_REG1, AD_CH3); ADS1115Read(WR_REG1, RE_REG1, &ADC_data); break; } } else if(chip == CHIP2) { switch(channel) { case CHANNEL0: I2C_MasterSendStart(WR_REG2, AD_CH0); ADS1115Read(WR_REG2, RE_REG2, &ADC_data); break; case CHANNEL1: I2C_MasterSendStart(WR_REG2, AD_CH1); ADS1115Read(WR_REG2, RE_REG2, &ADC_data); break; case CHANNEL2: I2C_MasterSendStart(WR_REG2, AD_CH2); ADS1115Read(WR_REG2, RE_REG2, &ADC_data); break; case CHANNEL3: I2C_MasterSendStart(WR_REG2, AD_CH3); ADS1115Read(WR_REG2, RE_REG2, &ADC_data); break; } } return ADC_data; } uint32_t GetAdcValue(uint8_t chip, uint32_t channel) { uint32_t adcvalue; int i = 0, sum = 0; for(i = 0; i < AVGTIMES; i++){ adcvalue = Getonevalue(chip, channel); sum = sum + adcvalue; } adcvalue = sum / AVGTIMES; return adcvalue; }
【ADS1115.h】
#ifndef __ADS1115_H #define __ADS1115_H #include "hc32l110.h" #include "base_types.h" #define I2C_DRATE 0x10 #define TOUTVAL 100 #define AVGTIMES 5 #define CHIP1 0x01 #define CHIP2 0x02 #define CHANNEL0 0x00 #define CHANNEL1 0x01 #define CHANNEL2 0x02 #define CHANNEL3 0x03 #define WR_REG1 0x90 #define RE_REG1 0x91 #define WR_REG2 0x92 #define RE_REG2 0x93 #define DATA_REG 0x00 #define CONF_REG 0x01 #define LOTH_REG 0x02 #define HITH_REG 0x03 #define AD_CH0 0xC0 #define AD_CH1 0xD0 #define AD_CH2 0xE0 #define AD_CH3 0xF0 #define ADS1115_PGA_6144 6144 //FS=6.144V #define ADS1115_PGA_4096 4096 //FS=4.096V #define ADS1115_PGA_2048 2048 //FS=2.048V #define ADS1115_PGA_1024 1024 //FS=1.024V #define ADS1115_PGA_0512 512 //FS=0.512V #define ADS1115_PGA_0256 256 //FS=0.256V uint32_t GetAdcValue(uint8_t chip, uint32_t channel); uint32_t AvgFilter(uint32_t adcvalue); uint32_t ADCDataProcess(uint16_t ADC_Readbuff_i[]); uint32_t Getonevalue(uint8_t chip, uint32_t channel); en_result_t I2C_MasterSendStart(uint8_t u8DevAddr, uint8_t channel); en_result_t I2C_Read(uint8_t u8DevAddr, uint8_t Reg, uint16_t Readbuff[]); en_result_t ADS1115Read(uint8_t u8DevAddr, uint8_t Reg, uint32_t *adc_rawdata); void I2C_init(void); #endif
这里ADS1115的ADDR管脚接高电平,所以写地址为0x92,已经封装好。如ADDR管脚接低电平,则将 GetAdcValue(CHIP2, CHANNEL2); 中CHIP2改成CHIP1即可
最后附上完整代码链接
BigHero47/HC32F005-ADS1115: HC32F005C6PA ADS1115 (github.com)https://github.com/BigHero47/HC32F005-ADS1115
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)