MCP3424的使用说明

最近由于项目需要使用到了MCP3424,这款芯片,概述如下:
        MCP3422、 MCP3423 和 MCP3424 器件( MCP3422/3/4)为 Microchip MCP342X 系列的低噪声和高精度 18 位  A/D( delta-sigma analog-to-digital)转换器。这些器件可将模拟输入信号转换成分辨率高达18 位的数字代码。片内 2.048V 基准电压使输入电压范围为 ±2.048V 差分输入 (满量程范围 = 4.096V/PGA)。用户通过 2 线 I2C 串行接口对控制配置位进行设定,从而使这些器件按3.75、 15、 60或240采样/秒( samplesper second, SPS)的速率进行转换。在每个转换周期内,器件自动对失调和增益误差进行校正。器件可以在不同的温度和电源电压波动下,在不同转换周期内提供精确的转换结果。用户可在 A/D 转换之前选择 PGA 增益为 x1、 x2、 x4 或x8 对信号进行放大。这允许 MCP3422/3/4 器件在高分辨率下仍可转换很小的输入信号。MCP3422/3/4 器件提供两种转换模式:( a)单次转换模式和 ( b)连续转换模式。在单次转换模式时,器件在完成一次转换后自动进入低电流待机模式,直至接收到新的转换命令。这样可显著降低空闲周期内的电流消耗。在连续转换模式时,器件以设定的转换速率进行连续转换,并用最新的转换数据来更新输出缓冲器中的数据。器件采用 2.7V 至 5.5V 单电源供电,并使用兼容标准( 100 kHz)、快速 ( 400 kHz)或高速 ( 3.4 MHz)模式的两线 I2C 串行接口。MCP3423和MCP3424的I2C地址位可使用两个外部I2C地址选择引脚 ( Adr0 和 Adr1)进行设置。通过将这两个地址选择引脚连接到 VDD、 VSS 或浮空,用户可以将器件的地址配置成 8 个可选地址中的一个。 MCP3422的 I2C 地址位在工厂生产时进行编程设置。

概述挺多,不过总结起来就是,这款芯片拥有四个通道可以进行18位的模拟信号采集,使用两线 I2C 进行数据通信。

首先这款芯片的使用,要使用I2C进行数据通信,这里采用软件I2C的方式,进行数据通信。使用的代码是用了正点原子的I2C代码,这里就不多赘述了,直接看要如何配置和读取数据。

MCP3424配置

在进行MCP3424配置之前,需要对其可配置的内容进行了解,首先MCP3424的配置包括:工作模式(连续转换模式,单次转换模式)、通道选择、采样速率、PGA增益。而且这款芯片有个配置寄存器需要知道的,定义如下:

MCP3424的使用说明_第1张图片

MCP3424的使用说明_第2张图片

工作模式

连续转换模式

如果 O/C 位设置成逻辑 “高”,器件将进行连续转换。一旦完成转换, RDY 位触发成 0,同时将结果放置在输出数据寄存器中。器件马上开始另外一次转换,并用最新的数据覆盖掉输出数据寄存器中原来的数据。当转换结束时,器件清除数据就绪标志位 ( RDY 位 = 0)。如果主器件读取了最新转换结果,则器件设置数据就绪标志位 ( RDY 位 = 1) 。
写配置寄存器时:
- 在连续模式下设置RDY位不会产生任何效果。
读转换数据时:
- RDY 位 = 0,意味着最新转换结果就绪。
- RDY 位 = 1,意味着自上次转换后,转换结果并没有被更新。新的转换正在进行中,当新的转换结果就绪时, RDY 位将被清除。

单次转换模式

若选择单次转换模式,器件仅进行一次转换,并更新输出数据寄存器,清除数据就绪标志位 ( RDY = 0),然后进入低功耗待机模式。当器件接收到新的写命令且RDY = 1 时,则开始新的单次转换。
写配置寄存器时:
- 在单次转换模式下, RDY 位需要设置,然后才能开始一次新的转换。
读转换数据时:
- RDY 位 = 0 意味着最新转换结果就绪。
- RDY 位 = 1 意味着自上次转换后, 转换结果并没有被更新。新的转换正在进行中,当新的转换结果就绪时, RDY 位将被清除。


代码进行配置

前面已经对MCP3424的配置内容有了了解,后面就开始使用代码进行配置。

对所有配置进行宏定义,从而增加配置时的代码可读性。

#define CMD_READ     0xD1
#define CMD_WRITE 0xD0

//MCP3424
// fields in configuration register
//  RDY C1 C0 nO/C    S1 S0 G1 G0
#define MCP342X_GAIN_X1    0x00 // PGA gain X1
#define MCP342X_GAIN_X2    0x01 // PGA gain X2
#define MCP342X_GAIN_X4    0x02 // PGA gain X4
#define MCP342X_GAIN_X8    0x03 // PGA gain X8

#define MCP342X_12_BIT     0x00 // 12-bit  240 SPS    5ms
#define MCP342X_14_BIT     0x04 // 14-bit   60 SPS   17ms
#define MCP342X_16_BIT     0x08 // 16-bit   15 SPS   67ms
#define MCP342X_18_BIT     0x0C // 18-bit 3.75 SPS  267ms

#define MCP342X_CONTINUOUS 0x10 // 1 = continuous, 0 = one-shot
#define MCP342X_ONESHOT         0x00 // 1 = continuous, 0 = one-shot

#define MCP342X_CHANNEL_1  0x00 // select MUX channel 1
#define MCP342X_CHANNEL_2  0x20 // select MUX channel 2
#define MCP342X_CHANNEL_3  0x40 // select MUX channel 3
#define MCP342X_CHANNEL_4  0x60 // select MUX channel 4

#define MCP342X_START      0x80 // write: start a conversion
#define MCP342X_BUSY       0x80 // read: output not ready

    
#define MCP342X_CHAL_1_CONFIG   MCP342X_CHANNEL_1|MCP342X_CONTINUOUS|MCP342X_16_BIT|MCP342X_GAIN_X1
#define MCP342X_CHAL_2_CONFIG   MCP342X_CHANNEL_2|MCP342X_CONTINUOUS|MCP342X_16_BIT|MCP342X_GAIN_X1
#define MCP342X_CHAL_3_CONFIG   MCP342X_CHANNEL_3|MCP342X_CONTINUOUS|MCP342X_16_BIT|MCP342X_GAIN_X1
#define MCP342X_CHAL_4_CONFIG   MCP342X_CHANNEL_4|MCP342X_CONTINUOUS|MCP342X_16_BIT|MCP342X_GAIN_X1

#define LSB_12BIT        1000   //uV
#define LSB_13BIT        250
#define LSB_16BIT        65.5
#define LSB_18BIT        15.625

使用I2C对MCP3424进行配置的时候,流程如下:

起始信号->发送写控制码->等待ACK->发送配置信息->等待ACK->停止信号。

具体代码如下

/***************************************************************************
 * @fn          IIC_MCP3424_CHANGE_CHL
 *     
 * @brief       对MCP3424进行配置,一共四个通道,每次只配置一个通道
 *     
 * @data        2018年06月05日
 *     
 * @param       u8 channel,通道号(1-4)
 *              
 *              
 * @return      void
 ***************************************************************************
 */ 
void IIC_MCP3424_CHANGE_CHL(u8 channel)
{
    switch (channel)
    {
        case 1:
            IIC_Start();            
            IIC_Send_Byte(CMD_WRITE);//告知MCP3424将要进行写操作
            IIC_Wait_Ack();
            IIC_Send_Byte(MCP342X_CHAL_1_CONFIG);//配置CP3424
            IIC_Wait_Ack();
            IIC_Stop();
            break;
        case 2:
            IIC_Start();
            IIC_Send_Byte(CMD_WRITE);
            IIC_Wait_Ack();
            IIC_Send_Byte(MCP342X_CHAL_2_CONFIG);
            IIC_Wait_Ack();
            IIC_Stop();
            break;
        case 3:
            IIC_Start();
            IIC_Send_Byte(CMD_WRITE);
            IIC_Wait_Ack();
            IIC_Send_Byte(MCP342X_CHAL_3_CONFIG);
            IIC_Wait_Ack();
            IIC_Stop();
            break;
        case 4:
            IIC_Start();
            IIC_Send_Byte(CMD_WRITE);
            IIC_Wait_Ack();
            IIC_Send_Byte(MCP342X_CHAL_4_CONFIG);
            IIC_Wait_Ack();
            IIC_Stop();
            break;
        default:
            break;
    }
}

这样,MCP32424就配置完成了,然后在这里,我是先配置一个通道的参数,然后读取这个通道的数值,然后再配置下一个通道。

MCP3424数据读取

前面配置讲完了,后面进行数据读取的说明。

进行MCP3424的数据读取时,需要注意的是,不同的采样精度,读取的数据长度不同,18位精度的读取回来的数据长度为4,前3个数值都是采样到的数据(高位在前),第4个是MCP3424的配置信息。主要是18位精度有区别,其他的12位,14位,16位读取的长度都为3,前2个数值都是采样到的数据(高位在前),第3个是MCP3424的配置信息。

数据的读取流程如下:

起始信号->发送读控制码->等待ACK->读取第1个数据->等待ACK->读取第2个数据->等待ACK->读取第3个数据->(等待ACK->读取第4个数据->)等待NACK->停止信号。

下面贴出18位和16位的数据读取代码:

/***************************************************************************
 * @fn          IIC_MCP3424_READ_16bit
 *     
 * @brief       读取MCP3424当前通道的数据
 *     
 * @data        2018年06月05日
 *     
 * @param       uint32_t *adcDate :当前通道的测量出来的数值
 *              
 *              
 * @return      uint8_t:当前通道的配置信息
 ***************************************************************************
 */ 
uint8_t IIC_MCP3424_READ_16bit(int16_t *adcDate)
{
	uint8_t readBuff[2] = {0};
	uint8_t configMCP3424 = 0;
	
	IIC_Start();
	IIC_Send_Byte(CMD_READ);//告知MCP3424进行数据读取
	IIC_Wait_Ack();
	readBuff[0] = IIC_Read_Byte(ACK);//第一字节为数据高位
	readBuff[1] = IIC_Read_Byte(ACK);//第二字节为数据低位

	configMCP3424 = IIC_Read_Byte(NACK);//第三字节为MCP3424的配置
	IIC_Stop();
	
	if((configMCP3424 & 0x80) == MCP342X_BUSY) 
	{
		*adcDate = 0x7AAA; //此时MCP3424返回的数值为无效数值
	}
	else
	{
		*adcDate = (int32_t)readBuff[0] << 8;//整合数据
		*adcDate = (int32_t)readBuff[1] | *adcDate;
		
	}
	
	
	return configMCP3424;
}
/***************************************************************************
 * @fn          IIC_MCP3424_READ_18bit
 *     
 * @brief       读取MCP3424当前通道的数据
 *     
 * @data        2018年06月05日
 *     
 * @param       uint32_t *adcDate :当前通道的测量出来的数值
 *              
 *              
 * @return      uint8_t:当前通道的配置信息
 ***************************************************************************
 */ 
uint8_t IIC_MCP3424_READ_18bit(int32_t *adcDate)
{
	uint8_t readBuff[3] = {0};
	uint8_t configMCP3424 = 0;
	
	IIC_Start();
	IIC_Send_Byte(CMD_READ);//告知MCP3424进行数据读取
	IIC_Wait_Ack();
	readBuff[0] = IIC_Read_Byte(ACK);//第一字节为数据高位(数据长度为18bit)
	readBuff[1] = IIC_Read_Byte(ACK);//第二字节为数据中位
	readBuff[2] = IIC_Read_Byte(ACK);//第三字节为数据低位
	configMCP3424 = IIC_Read_Byte(NACK);//第四字节为MCP3424的配置
	IIC_Stop();
	
	if((configMCP3424 & 0x80) == MCP342X_BUSY) 
	{
		*adcDate = 0xAAAAAAAA; //此时MCP3424返回的数值为无效数值
	}
	else
	{
		//*adcDate = ((int32_t)readBuff[0] & 0x80) << 24 | *adcDate;//整合数据
		*adcDate = ((int32_t)readBuff[0] & 0x01) << 16 | *adcDate;//整合数据
		*adcDate = (int32_t)readBuff[1] << 8 | *adcDate;
		*adcDate = (int32_t)readBuff[2] | *adcDate;
		
		if(readBuff[0] & 0x80)
		{
			*adcDate = 0x0001FFFF - *adcDate;
			*adcDate = 0 - *adcDate;
		}
		
	}
	
	return configMCP3424;
}

至此MCP3424的数据读取就完成。

你可能感兴趣的:(C语言)