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)
*功能描述: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即可
|
共1人点赞
|