声明:
本文章是根据官方数据手册整理而来,文章写的较简单,只用作个人学习用途。
参考资料:
CS5560数据手册
内部电路:
引脚分布&引脚功能:
寄存器介绍:
主要看寄存器地址,位的介绍。
A/D转换器传输率定义:
传输率= fADCK/OSR = (MCLK/N)/OSR = fMCLK/NxOSR)
例如:例如:需要-个10HZ的传输率,可以选择A/D时钟源MCLK为4.9152MHz, 设置FLMS[2:0]=000b,即获得时钟源的30分频,在设置ADOR[3:0]=0001b,选择过取样速率为16384。 传输率=4.9152MHZ/(30*16384)=10HZ。
A/D值转化为电压值:
A/D转换资料存在寄存器ADRL,ADRM和ADRH中,A/D输出以二进制补码形式输出,长度为24位,最高位是符号位,最高位“0”表示输出正数,最高位“1”表示输出为负数。
电压推导公式如下:(这里的电压输出都是正数)
①如果MSB=0 (转换资料为正数) :输入电压= (转换资料xLSB-DCSET) / (PGAxADGN)
②如果MSB=1 (转换资料为负数) :输入电压= (转换资料的补码xLSB-DCSET) / (PGAxADGN)
备注:
①: 1 LSB= ∆VR-I/8388608 ;
②:∆VR-I =VREFGN × ∆ VR±,其中VREFGN = 1,差分参考电压∆ VR± =VREFP - VREFN;
③:DCSET :偏置电压
④:差分增益:PGA ×ADGN = 1。
A/D工作流程:
步骤1:提供电源给PGA和ADC;
步骤2:通过PGAC0寄存器,选择PGA, ADC和参考电压的增益;
步骤3:通过PGAC1寄存器,选择PGA的引脚连接;
步骤4:通过ADCS寄存器中的ADCK4~ADCK0,选择A/D时钟源为4.9152MHZ;
步骤5:通过ADCR0寄存器中的ADOR[2:0]位及ADCR1寄存器中的FLMS[2:0]位,选择数据传输率;
步骤6:通过PGACS寄存 器中的CHSP2~CHSP0和CHSN2~CHSN0位,选择连接至内部PGA的通道;
步骤7:通过ADCR0寄存器中的ADOFF和ADSLP位,关闭暂停和休眠模式;
步骤8:通过置高ADCR0寄存器中的ADRST位来复位A/D转换器,清除该位来释放重定模式;
步骤9:轮询ADCR1寄存器中EOC位,检查模数转换过程是否完成。当此位为1 (高)时,表示转换 过程已经完成。转换完成后,读取A/D资料寄存器ADRL, ADRM和ADRH获得转换后的值。
参考代码
引脚及输出配置宏定义:
/******CS5560宏定义*****/
#define IIC_CS5560_ADDR 0xd0 //CS5560芯片地址
#define IIC_CS5560_SDA_IO GPIO_Pin_21 //CS5560-SDA-IO口 PB21
#define IIC_CS5560_SCL_IO GPIO_Pin_20 //CS5560-SCL-IO口 PB20
#define IIC_CS5560_RDY_IO GPIO_Pin_14 //CS5560-RDY-IO口 PA14
#define IIC_CS5560_SDA_OUT GPIOB_ModeCfg(IIC_CS5560_SDA_IO, GPIO_ModeOut_PP_5mA) //CS5560-SDA-IO口定义,推挽输出
#define IIC_CS5560_SCL_OUT GPIOB_ModeCfg(IIC_CS5560_SCL_IO, GPIO_ModeOut_PP_5mA) //CS5560-SCL-IO口定义,推挽输出
#define IIC_CS5560_SCL_IN GPIOB_ModeCfg(IIC_CS5560_SCL_IO, GPIO_ModeIN_PU) //CS5560-SCL-IO口定义,上拉输出
#define IIC_CS5560_SDA_IN GPIOB_ModeCfg(IIC_CS5560_SDA_IO, GPIO_ModeIN_PU) //CS5560-SDA-IO口定义,上拉输出
#define IIC_CS5560_RDY_IN GPIOA_ModeCfg(IIC_CS5560_RDY_IO, GPIO_ModeIN_PU) //CS5560-RDY-IO口定义,上拉输出
#define IIC_CS5560_READ_SDA GPIOB_ReadPortPin(IIC_CS5560_SDA_IO) //读SDA引脚电平
#define IIC_CS5560_READ_RDY GPIOA_ReadPortPin( IIC_CS5560_RDY_IO) //读RDY引脚电平
#define IIC_CS5560_SDA_H GPIOB_SetBits(IIC_CS5560_SDA_IO) //!<CS5560-SDA高电平
#define IIC_CS5560_SDA_L GPIOB_ResetBits(IIC_CS5560_SDA_IO) //!<CS5560-SDA低电平
#define IIC_CS5560_SCL_H GPIOB_SetBits(IIC_CS5560_SCL_IO) //!<CS5560-SCL高电平
#define IIC_CS5560_SCL_L GPIOB_ResetBits(IIC_CS5560_SCL_IO) //!<CS5560-SCL低电平
#define IIC_CS5560_RDY_L GPIOB_ResetBits(IIC_CS5560_RDY_IO) //!<CS5560-SCL低电平
#define IIC_CS5560_DELAY DelayUs(4) //延时
寄存器宏定义:
/*******CS5560寄存器宏定义*********/
#define CS5560_REG_PWRC 0x00
#define CS5560_REG_PGAC0 0x01
#define CS5560_REG_PGAC1 0x02
#define CS5560_REG_PGACS 0x03
/*************存放AD值寄存器********************/
#define CS5560_REG_ADLdata 0x04
#define CS5560_REG_ADMdata 0x05
#define CS5560_REG_ADHdata 0x06
/************************************/
#define CS5560_REG_ADCR0 0x07
#define CS5560_REG_ADCR1 0x08
#define CS5560_REG_ADCS 0x09
#define CS5560_REG_HIRCC 0x11
#define CS5560_REG_ADCTE 0x0a
CS5560状态枚举:
typedef enum
{
Channel0=0x00, //!<差分通道0,配置信息:10010000 channal0 AN0 AN1
Channel1=0x01, //!<差分通道1,配置信息:10100000 channal1 AN2 AN1
Channel2=0x08, //!<差分通道2,配置信息:10110000 channel2 AN0 AN3 目前采用该通道
Channel3=0x09, //!<差分通道3,配置信息:11000000 channel1 AN2 AN3
} CS5560_Channel; //CS5560通道选择
typedef enum
{
Rate_1280=0x11, //!<速率1280Hz
Rate_640=0x0F, //!<速率640Hz
Rate_320=0x0D, //!<速率320Hz
Rate_160=0x0B, //!<速率160Hz
Rate_80 =0x09 //!<速率80Hz
} CS5560_Rate_30; //30分频下的采样速率
typedef enum
{
PGA_1 = 0x20, //!< 差分增益1
PGA_2 = 0x28, //!< 差分增益2
PGA_4 = 0x29, //!<差分增益4
PGA_8 = 0x2A, //!<差分增益8
PGA_16 = 0x2B, //!<差分增益16
PGA_32 = 0x2C, //!<差分增益32
PGA_64 = 0x2D //!<差分增益64
} CS5560_PGA; //CS5560采样差分增益 VREFGN=0.5
初始化函数:
Write_Adr(IIC_CS5560_ADDR, CS5560_REG_ADCTE,0xE7); //ADCTE 固定,不可修改
Write_Adr(IIC_CS5560_ADDR, CS5560_REG_HIRCC,0x01); //
Write_Adr(IIC_CS5560_ADDR, CS5560_REG_PWRC ,0x28); // 使能VCM
Write_Adr(IIC_CS5560_ADDR, CS5560_REG_PGAC0,PGA_1); // 00101001 差分增益选择
Write_Adr(IIC_CS5560_ADDR, CS5560_REG_PGAC1,0x00); // 差分输入端
Write_Adr(IIC_CS5560_ADDR, CS5560_REG_PGACS,Channel2); // 输入通道AN0 AN3
Write_Adr(IIC_CS5560_ADDR, CS5560_REG_ADCR0,Rate_640); // 采样率 640HZ
Write_Adr(IIC_CS5560_ADDR, CS5560_REG_ADCS ,0x1F); // 时钟源=系统时钟 4.9152MHZ
Write_Adr(IIC_CS5560_ADDR, CS5560_REG_ADCR1,0x00); // 30分频
CS5560寄存器的读写操作与IIC读写方式一致:
void I2C_Start(void)
{
IIC_CS5560_SDA_OUT; //不能省略
IIC_CS5560_SDA_H;
IIC_CS5560_SCL_H;
IIC_CS5560_DELAY;
IIC_CS5560_SDA_L;
IIC_CS5560_DELAY;
IIC_CS5560_SCL_L;
IIC_CS5560_DELAY ;
}
void I2C_Stop(void)
{
IIC_CS5560_SDA_OUT; //不能省略
IIC_CS5560_SCL_L ;
IIC_CS5560_SDA_L ;
IIC_CS5560_DELAY;
IIC_CS5560_SCL_H ;
IIC_CS5560_DELAY;
IIC_CS5560_SDA_H;
IIC_CS5560_DELAY;
}
void I2C_ACK(void) //产生ACK应答
{
IIC_CS5560_SCL_H; IIC_5560_DELAY_1;
IIC_CS5560_SCL_L; IIC_5560_DELAY_1;
}
/******************************** CS5560 Byte Write ******************************/
void ByteTo_I2C(unsigned char DData) //写单字节
{
unsigned char temp;
unsigned char m,Pos;
m=0x80;
for(Pos=0; Pos<8; Pos++)
{
if(m&DData) //(m&DData)>=1
{
IIC_CS5560_SDA_H;
}
else {
IIC_5560_SDA_L;
}
m=m>>1;
IIC_CS5560_SCL_L; IIC_CS5560_DELAY_1;
IIC_CS5560_SCL_H; IIC_CS5560_DELAY_2;
IIC_CS5560_SCL_L; IIC_CS5560_DELAY_1;
}
IIC_CS5560_DELAY_1;
}
//DAddr 芯片地址
//RAddr 寄存器地址
//WData 寄存器配置信息
/****************************** CS5560 I2C RegWrite *****************************/
void I2C_Write(unsigned char DAddr,unsigned char RAddr,unsigned char WData) //写寄存器 配置信息
{
I2C_Start();
ByteTo_I2C(DAddr); I2C_ACK();
ByteTo_I2C(RAddr); I2C_ACK();
ByteTo_I2C(WData); I2C_ACK();
I2C_Stop();
}
/******************************** CS5560 I2C Byte Read ******************************/
unsigned char ByteFrom_I2C(void) //读取单字节
{
uint8_t i;
unsigned char Rdata = 0;
IIC_CS5560_SCL_L;
IIC_CS5560_DELAY;
IIC_CS5560_SDA_H;
IIC_CS5560_DELAY;
IIC_CS5560_SDA_IN;
for (i = 0; i < 8; i++) {
IIC_CS5560_SCL_H;
IIC_CS5560_DELAY;
Rdata = (Rdata << 1);
if (IIC_CS5560_READ_SDA)
Rdata++;
IIC_CS5560_SCL_L;
IIC_CS5560_DELAY;
}
return Rdata;
}
/****************************** CS5560 data Read *****************************/
unsigned char I2C_Read(unsigned char DAddr,unsigned char RAddr) //读寄存器值
{
unsigned char ad_read;
I2C_Start();
ByteTo_I2C(DAddr); I2C_ACK();
ByteTo_I2C(RAddr); I2C_ACK();
I2C_Start();
ByteTo_I2C(DAddr+1); I2C_ACK();
ad_read = ByteFrom_I2C(); I2C_ACK();
I2C_Stop();
return ad_read ;
}
int16_t Read_AD_Value(void) //读取AD值
{
int16_t value;
AD_L = I2C_Read(0xd0,0x04);
//
AD_M = I2C_Read(0xd0,0x05);
AD_H = I2C_Read(0xd0,0x06);
I2C_Write(0xd0,0x08,0x00); //AD转换结束后 ,软件置0
value=AD_H;
value=value<<8;
value=value+AD_M;
return value;
}