BH45B1225 是一款内建可编程增益放大器的多通道24-bit的Delta Sigma A/D转换器,专门为与模拟信号差分接口应用而设计。该芯片具有低噪声和高精度的性能,并可通过内部 I2C 总线与外部硬件进行通信。这种功能高度集成的 Delta Sigma A/D 转换器具有高精度和低功耗的规格,为与外部传感器的接口提供了卓越的解决方案,特别适用于电池供电应用。
CH32软件I2C驱动24位ADC,BH45B1225.
BH45B1225是24位ADC,有效位数最高为21.5bit,可差分可单端,内部含有1.25v参考基准,RC振荡器,10SPS时对50HZ60HZ工频干扰有陷波器作用,以降低成本。
本程序使用单端采集内部基准,AN0连接ch32-dac,AN1内部通道选择VCM,数据传输率为10SPS。
代码如下(示例):
#include "BH45B1225.h"
#include "MyI2C.h"
#include "debug.h"
/*
*SOP-8,ADDRESS -->0XD0
*NSOP-16
*XTSB=0,ADDRESS-->0XA0
*XTSB=1 0SC2 OSC1 ADDRESS
* 0 0 0XA0
* 0 1 0XB0
* 1 0 0XC0
* 1 1 0XD0
*/
//#define BH45B1225_ADDRESS 0xA0
//#define BH45B1225_ADDRESS 0xB0
//#define BH45B1225_ADDRESS 0xC0
#define BH45B1225_ADDRESS 0xD0
/**********寄存器设置*************/\
#define VR 1.25
#define LSB VR/8388608
#define PGAGN 1
#define ADGN 1
#define VREFGN 1
#define DCSET 0
void BH45B1225_WriteReg(uint8_t RegAddress, uint8_t Data)
{
MyI2C_Start();
MyI2C_SendByte(BH45B1225_ADDRESS);
MyI2C_ReceiveAck();
MyI2C_SendByte(RegAddress);
MyI2C_ReceiveAck();
MyI2C_SendByte(Data);
MyI2C_ReceiveAck();
MyI2C_Stop();
}
uint8_t BH45B1225_ReadReg(uint8_t RegAddress)
{
uint8_t Data;
MyI2C_Start();
MyI2C_SendByte(BH45B1225_ADDRESS);
MyI2C_ReceiveAck();
MyI2C_SendByte(RegAddress);
MyI2C_ReceiveAck();
MyI2C_Start();
MyI2C_SendByte(BH45B1225_ADDRESS | 0x01);
MyI2C_ReceiveAck();
Data = MyI2C_ReceiveByte();
MyI2C_SendAck(1);
MyI2C_Stop();
return Data;
}
void BH45B1225_Temptuer_Init()
{
//内部基准温度传感器
MyI2C_Init(); //I2C初始化
BH45B1225_WriteReg(BH45B1225_HIRCC,0X01);
while(!(BH45B1225_ReadReg(BH45B1225_HIRCC) & (1 << 1))); //内部osc稳定
BH45B1225_WriteReg(BH45B1225_PWRC,0x80);//使能VCM
BH45B1225_WriteReg(BH45B1225_ADCR0,0X02);
BH45B1225_WriteReg(BH45B1225_PGAC0,0X00);
BH45B1225_WriteReg(BH45B1225_PGAC1,0X40);
BH45B1225_WriteReg(BH45B1225_ADCS,0X1F);
BH45B1225_WriteReg(BH45B1225_ADCR0,0X02);
BH45B1225_WriteReg(BH45B1225_ADCR1,0X40);
BH45B1225_WriteReg(BH45B1225_PGACS,0X3F);//00101110
BH45B1225_WriteReg(BH45B1225_ADCR0,0X02);
BH45B1225_WriteReg(BH45B1225_ADCR0,0X82);
BH45B1225_WriteReg(BH45B1225_ADCR0,0X02);
}
void BH45B1225_Init()
{
MyI2C_Init(); //I2C初始化
BH45B1225_WriteReg(BH45B1225_HIRCC,0X01);
while(!(BH45B1225_ReadReg(BH45B1225_HIRCC) & (1 << 1))); //内部osc稳定
BH45B1225_WriteReg(BH45B1225_PWRC,0x80);//使能VCM
BH45B1225_WriteReg(BH45B1225_ADCR0,0X02);//正常模式,设置采样率,参考选择
BH45B1225_WriteReg(BH45B1225_PGAC0,0X00);//参考增益1,差分信号增益1,差分通道增益1.
BH45B1225_WriteReg(BH45B1225_PGAC1,0X00);//使能选择差分通道
BH45B1225_WriteReg(BH45B1225_ADCS,0X1F);//Fmclk=Fsys
BH45B1225_WriteReg(BH45B1225_ADCR0,0X02);//关闭暂停和休眠模式
BH45B1225_WriteReg(BH45B1225_ADCR1,0X00);//时钟分频,使能AD数据锁存
BH45B1225_WriteReg(BH45B1225_PGACS,0X30);//00101110 差分通道选择,单通道模式正相通道AN0,反相通道VCM
BH45B1225_WriteReg(BH45B1225_ADCR0,0X02);//拉低
BH45B1225_WriteReg(BH45B1225_ADCR0,0X82);//复位ADC准备转换数据
BH45B1225_WriteReg(BH45B1225_ADCR0,0X02);//拉低
}
uint8_t BH45B1225_EOC_FLAG()
{
if(BH45B1225_ReadReg(BH45B1225_ADCR1) & ( 1 << 1 ))
{
return 1;
}
else return 0;
}
float BH45B1225_Get_temp()
{
u8 DataH,DataM,DataL;
float Voltage;
u32 DATA_Value;
while(!BH45B1225_EOC_FLAG()); //等待EOC置1转换完成
{
BH45B1225_WriteReg(BH45B1225_ADCR1,0X44); //采样ADC锁存数据
DataH = BH45B1225_ReadReg(BH45B1225_ADRH); //读取ADC数据高为寄存器
DataM = BH45B1225_ReadReg(BH45B1225_ADRM); //读取ADC数据中为寄存器
DataL = BH45B1225_ReadReg(BH45B1225_ADRL); //读取ADC数据低为寄存器
BH45B1225_WriteReg(BH45B1225_ADCR1,0X40); //清除eoc标志位
DATA_Value = (DataH<<16) | (DataM<<8) | (DataL);
if(!((DATA_Value & (1 << 23)) == 0x00800000)) //MSB=0,adc数据正
{
Voltage=(DATA_Value * (LSB)-DCSET)/(PGAGN*ADGN);
}
return Voltage;
}
}
float BH45B1225_Get_Data()
{
u8 DataH,DataM,DataL;
float Voltage;
u32 DATA_Value;
while(!BH45B1225_EOC_FLAG()); //等待EOC置1转换完成
{
BH45B1225_WriteReg(BH45B1225_ADCR1,0X44); //采样ADC锁存数据
DataH = BH45B1225_ReadReg(BH45B1225_ADRH); //读取ADC数据高为寄存器
DataM = BH45B1225_ReadReg(BH45B1225_ADRM); //读取ADC数据中为寄存器
DataL = BH45B1225_ReadReg(BH45B1225_ADRL); //读取ADC数据低为寄存器
BH45B1225_WriteReg(BH45B1225_ADCR1,0X40); //清除eoc标志位
DATA_Value = (DataH<<16) | (DataM<<8) | (DataL);
if(!((DATA_Value & (1 << 23)) == 0x00800000)) //MSB=0,adc数据正
{
Voltage=(DATA_Value * (LSB)-DCSET)/(PGAGN*ADGN);
return Voltage;
}
else { //MSB=1,ADC数据负
DATA_Value = ~DATA_Value + 1;
DATA_Value = DATA_Value & 0x00ffffff;
Voltage = (DATA_Value * (LSB)-DCSET)/(PGAGN*ADGN);
return (-Voltage);
}
}
}
代码如下(示例):
#ifndef __BH45B1225_H
#define __BH45B1225_H
#include "ch32f10x.h"
#define BH45B1225_PWRC 0x00 //电源控制寄存器
#define BH45B1225_PGAC0 0x01 //PGA1控制寄存器
#define BH45B1225_PGAC1 0x02 //PGA2控制寄存器
#define BH45B1225_PGACS 0x03 //PGA通道控制寄存器
#define BH45B1225_ADRL 0x04
#define BH45B1225_ADRM 0x05
#define BH45B1225_ADRH 0x06
#define BH45B1225_ADCR0 0x07 //PGA2控制寄存器
#define BH45B1225_ADCR1 0x08
#define BH45B1225_ADCS 0x09
#define BH45B1225_ADCTE 0x0A
#define BH45B1225_DAH 0x0B //DAC高位寄存器
#define BH45B1225_DAL 0x0C //DAC低位寄存器
#define BH45B1225_DACC 0x0D //DAC控制寄存器
#define BH45B1225_SIMC0 0x0E
#define BH45B1225_SIMTOC 0x10
#define BH45B1225_HIRCC 0x11 //振荡器控制寄存器
#define BH45B1225_HXTC 0x12 //振荡器控制寄存器
void BH45B1225_WriteReg(uint8_t RegAddress, uint8_t Data);
uint8_t BH45B1225_ReadReg(uint8_t RegAddress);
void BH45B1225_Init();
void BH45B1225_Temptuer_Init();
uint8_t BH45B1225_EOC_FLAG();
float BH45B1225_Get_Data();
float BH45B1225_Get_temp();
#endif
使用CH32DAC输出电压供ADC采集,考虑到DAC输出的误差,ADC数据未滤波处理,2块一个ADC很好了。
完整工程:https://download.csdn.net/download/hhhhwdnmd/88234964