HC32F005C6PA 硬件I2C采集ADS1115,亲测可用

HC32时钟为22.12MHz,继而I2C传输速率如果为100k的话,根据公式

Fscl = Fpclk / 8 / (I2Cx_TM.tm+1)

在这里将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)
*功能描述:I2C初始化函数
*输入参数:none
*输出参数:none
*返回值:none
*其他说明:
*修改日期         版本号                   修改人             修改内容
*------------------------------------------------------------------------------------
*************************************************************************************/
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)
*功能描述:ADS1115配置
*输入参数:u8DevAddr: 芯片写地址
*         channel: 采样通道
*输出参数:none
*返回值:en_result_t
*其他说明:
*修改日期         版本号                   修改人             修改内容
*------------------------------------------------------------------------------------
*************************************************************************************/
en_result_t I2C_MasterSendStart(uint8_t u8DevAddr, uint8_t channel)
{
	int timeout = 0;
	
	/* START */
  I2C_SetFunc(I2cStart_En);  // Step5, 发送 Start 信号
	I2C_ClearIrq();

	timeout = TOUTVAL;
	while(0 == I2C_GetIrq() || timeout--);
	
	if(0x08 != I2C_GetState()) {return Error;}

	/* WR_REG */
	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;

	/* CONF_REG 0x01 */
	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());	

	/* channel */
	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());

	/* 0xe3 */
	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());

	/* END */
	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[2])
*功能描述:ADS1115数据处理函数
*输入参数:uint16_t ADC_Readbuff_i[2]:寄存器读出的数据
*输出参数:none
*返回值:uint32_t:解析后的数据
*其他说明:
*修改日期         版本号                   修改人             修改内容
*------------------------------------------------------------------------------------
*************************************************************************************/
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[])
*功能描述:从ADS1115寄存器中读取I2C数据
*输入参数:u8DevAddr: 芯片写地址
*         Reg: 芯片读地址
*输出参数:Readbuff[]:读取的高低位数据
*返回值:en_result_t
*其他说明:
*修改日期         版本号                   修改人             修改内容
*------------------------------------------------------------------------------------
*************************************************************************************/
en_result_t I2C_Read(uint8_t u8DevAddr, uint8_t Reg, uint16_t Readbuff[])
{
	int timeout = 0;
	
	/* START */
  I2C_SetFunc(I2cStart_En);  // Step5, 发送 Start 信号
	I2C_ClearIrq();
  timeout = TOUTVAL;
	while(0 == I2C_GetIrq() || timeout--);
	if(0x08 != I2C_GetState()) return Error;

	/* WR_REG */
	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;

	/* DATA_REG */
	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());	

	/* END */
	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,数据已发送到总线上

	/* START */
  I2C_SetFunc(I2cStart_En);  // Step5, 发送 Start 信号
	I2C_ClearIrq();
  timeout = TOUTVAL;
	while(0 == I2C_GetIrq() || timeout--);
	if(0x08 != I2C_GetState()) return Error;

	/* RE_REG 0x91 */
	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;
	/* RECV DATA1 */
	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);

	/* END */
	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)
*功能描述:ADS1115读取数据
*输入参数:u8DevAddr: 芯片写地址
*         Reg: 芯片读地址
*输出参数:adc_rawdata:ADC采集到的数据(uint)
*返回值:en_result_t
*其他说明:
*修改日期         版本号                   修改人             修改内容
*------------------------------------------------------------------------------------
*************************************************************************************/
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 GetAdcValue(uint8_t chip, uint32_t channel)
*功能描述:ADS1115采集单次数据
*输入参数:chip:芯片号
*         channel:通道号
*输出参数:none
*返回值:uint32_t ADC采集到的数据(uint)
*其他说明:
*修改日期         版本号                   修改人             修改内容
*------------------------------------------------------------------------------------
*************************************************************************************/
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)
*功能描述:ADS1115采集数据,均值滤波
*输入参数:chip:芯片号
*         channel:通道号
*输出参数:none
*返回值:uint32_t ADC采集到的带均值滤波的数据(uint)
*其他说明:
*修改日期         版本号                   修改人             修改内容
*------------------------------------------------------------------------------------
*************************************************************************************/
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    /*I2C传输速率*/
#define  TOUTVAL   100     /*while超时处理*/
#define  AVGTIMES  5

/** ADS1115个数 */
#define  CHIP1 0x01      /*ADS1115 1*/
#define  CHIP2 0x02      /*ADS1115 2*/

#define  CHANNEL0 0x00      /*ADS1115 CH0*/
#define  CHANNEL1 0x01      /*ADS1115 CH1*/
#define  CHANNEL2 0x02      /*ADS1115 CH2*/
#define  CHANNEL3 0x03      /*ADS1115 CH3*/


/** ADS1115寄存器设置 */
#define  WR_REG1 0x90      /*ADS1115 1写*/
#define  RE_REG1 0x91      /*ADS1115 1读*/
#define  WR_REG2 0x92      /*ADS1115 2写*/
#define  RE_REG2 0x93      /*ADS1115 2写*/

#define  DATA_REG  0x00		/*转换数据寄存器*/
#define  CONF_REG  0x01   /*控制字设置寄存器*/
#define  LOTH_REG  0x02		/*最低阀值寄存器*/
#define  HITH_REG  0x03		/*最高阀值寄存器*/

/** ADS1115通道设置 */
#define  AD_CH0  0xC0   /*通道0*/
#define  AD_CH1  0xD0   /*通道1*/
#define  AD_CH2  0xE0   /*通道2*/
#define  AD_CH3  0xF0   /*通道3*/

#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
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值