stm32驱动16位ADC(ADS1113)

相关原理图:this

其中VDD:3d

 

 

引脚定义:code

/*
* I2C1
* @ADC_SDA		PB7
* @ADC_SCL      PB6
* @CU_BE_EN     PC8  (1 : ON , 0: OFF)
* @CU_BE_SELE   PB12 (here should be low, reference current.c)
*/

PB12能够忽略,咱们这里使用了一个开关控制电流采集和电流输出,这里PB12 = 0blog

先看IICip

头文件包含内容:it

#include "stm32f10x.h"
#include "sys.h"

/*
*  ADC I2C1
*      SCL  :  PB6
*      SDA  :  PB7
* Temp I2C2
*      SCL  : PB10
*      SDA  : PB11
*/

#define I2C_PORT		GPIOB      
#define I2C_SCK		    GPIO_Pin_6 
#define I2C_SDA		    GPIO_Pin_7 

#define RCC_APB2Periph_I2C_PORT		RCC_APB2Periph_GPIOB


#define ACK	 0  
#define	NACK 1 


#define I2C_SCK_H()	    GPIO_SetBits(I2C_PORT, I2C_SCK)
#define I2C_SCK_L()	    GPIO_ResetBits(I2C_PORT, I2C_SCK)

#define I2C_SDA_H()	    GPIO_SetBits(I2C_PORT, I2C_SDA)
#define I2C_SDA_L()	    GPIO_ResetBits(I2C_PORT, I2C_SDA)

#define I2C_SDA_PIN()	    GPIO_ReadInputDataBit(I2C_PORT, I2C_SDA)

static inline void I2C_SDASetAsInput(void)
{
	// pin 7
	GPIOB->CRL &= 0X0FFFFFFF ;
	GPIOB->CRL |= (u32) 4 << 28; 
}

static inline void I2C_SDASetAsOutput(void)
{
	// pin 7
	GPIOB->CRL &= 0X0FFFFFFF ;
	GPIOB->CRL |= (u32) 3 << 28; 
}


/***********************************************************************/
void IIC_Start(void);
void IIC_Stop(void);


u8 IIC_Send_Byte(u8 data);
u8 IIC_Read_Byte(u8 ack_nack);

void IIC_Init(void);                // initial

初始化io

void IIC_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(	RCC_APB2Periph_GPIOB, ENABLE );	//使能GPIOB时钟
    
    GPIO_InitStructure.GPIO_Pin = I2C_SCK | I2C_SDA;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(I2C_PORT, &GPIO_InitStructure);
    
	I2C_SCK_H();
    I2C_SDA_H();
}

起始信号:ast

void IIC_Start(void)
{
    I2C_SDASetAsOutput();
	
    I2C_SDA_H();		// Set SDA line
    I2C_SCK_H();		// Set SCL line
    I2C_Delay(2);	    // Generate bus free time between Stop
    I2C_SDA_L();		// Clear SDA line
    I2C_Delay(2);	    // Hold time after (Repeated) Start
    // Condition. After this period, the first clock is generated.
    //(Thd:sta=4.0us min)
    I2C_SCK_L();	    // Clear SCL line
    I2C_Delay(2);	    // Wait a few microseconds
}

结束信号:class

void IIC_Stop(void)
{
	I2C_SDASetAsOutput();
	
    I2C_SDA_L();		// Clear SDA line
    I2C_Delay(2);	    // Wait a few microseconds
    I2C_SCK_H();		// Set SCL line
    I2C_Delay(2);	    // Stop condition setup time(Tsu:sto=4.0us min)
    I2C_SDA_H();		// Set SDA line					   	
}

接收一个位原理

static u8 I2C_ReceiveBit(void)
{
    u8 Ack_bit;
	I2C_SDASetAsInput();

    I2C_SDA_H();            //
	I2C_Delay(2);			// High Level of Clock Pulse
    I2C_SCK_H();			// Set SCL line
    I2C_Delay(5);			// High Level of Clock Pulse
    if (I2C_SDA_PIN())
    {
        Ack_bit=1;
    }
    else
    {
        Ack_bit=0;
    }
    I2C_SCK_L();			// Clear SCL line
    I2C_Delay(3);			// Low Level of Clock Pulse

    return	Ack_bit;
}

发送一个位:

static void I2C_SendBit(u8 bit_out)
{
	I2C_SDASetAsOutput();
	
    if(bit_out==0)
    {
        I2C_SDA_L();
    }
    else
    {
        I2C_SDA_H();
    }
    I2C_Delay(2);					// Tsu:dat = 250ns minimum
    I2C_SCK_H();					// Set SCL line
    I2C_Delay(6);					// High Level of Clock Pulse
    I2C_SCK_L();					// Clear SCL line
    I2C_Delay(3);					// Low Level of Clock Pulse
//	I2C_SDA_H();				    // Master release SDA line ,
    return;
}

接收一个byte:

u8 IIC_Read_Byte(u8 ack)
{
    u8 	RX_buffer;
    u8	Bit_Counter;

    for(Bit_Counter=8; Bit_Counter; Bit_Counter--)
    {
        if(I2C_ReceiveBit())			// Get a bit from the SDA line
        {
            RX_buffer <<= 1;			// If the bit is HIGH save 1  in RX_buffer
            RX_buffer |=0x01;
        }
        else
        {
            RX_buffer <<= 1;			// If the bit is LOW save 0 in RX_buffer
            RX_buffer &=0xfe;
        }
    }
    I2C_SendBit(ack);			// Sends acknowledgment bit
    return RX_buffer;
}

发送一个byte:

u8 IIC_Send_Byte(u8 data)
{                        
    u8	Bit_counter;
    u8	Ack_bit;
    u8	bit_out;

    for(Bit_counter=8; Bit_counter; Bit_counter--)
    {
        if (data & 0x80)
        {
            bit_out = 1;   // If the current bit of Tx_buffer is 1 set bit_out
        }
        else
        {
            bit_out = 0;  // else clear bit_out
        }
        I2C_SendBit(bit_out);		// Send the current bit on SDA
        data <<= 1;				// Get next bit for checking
    }

    Ack_bit = I2C_ReceiveBit();		// Get acknowledgment bit
    return	Ack_bit;
}

相关延时:

static void I2C_Delay(u16 time)
{
	delay_us(time);
}

从机地址:查看ADS1113手册知道,默认0x90

#define I2C_SLAVE_ADDR     0x90

ADS1113初始化:

static void ADS1113_Enable(void)
{
	GPIO_SetBits(GPIOC, GPIO_Pin_8);
}

static void ADS_GPIO_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOB, ENABLE );

	// CU_BE_EN
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; 
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOC, &GPIO_InitStructure);

	// power on
	ADS1113_Enable();

	// CU_BE_SELE
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; 
	GPIO_Init(GPIOB, &GPIO_InitStructure); 
	// CU_BE_SELE = 0;
	GPIO_ResetBits(GPIOB, GPIO_Pin_12); 
}




void ADS1113_Init(void)
{
	ADS_GPIO_Config();

	IIC_Init();
}

ADS1113配置:

/*
* args:
* @id : slave address  : 0x90 / 0x91
* @write_address: 0x00 : Conversion register
*                 0x01 : Config register
*                 0x02 : Lo_thresh register
*                 0x03 : Hi_thresh register
* @byte1 : 
* @byte2 :
* return : none
*/
#define CMD_Write  		0x90 
#define CMD_Read   		0x91
#define CMD_POINT_REG  	0x00 
#define CMD_CONF_REG  	0x01 




static void Ads1113_Config(void)
{
	u8 i;
	u8 WriteIntBuf[4];

	WriteIntBuf[0] = CMD_Write; 
	WriteIntBuf[1] = CMD_CONF_REG;       /* config register */
	WriteIntBuf[2] = 0xC2; 
	WriteIntBuf[3] = 0xE2;

	IIC_Start(); 

	for(i = 0 ; i < 4 ; i++)
	{
		IIC_Send_Byte(WriteIntBuf[i]);
		delay_us(20);
	}

	IIC_Stop(); 
}

PointRegister:

static void PointRegister (void)
{
	unsigned char i;
	u8 buf[2];
	
	buf[0] = CMD_Write; //90
	buf[1] = CMD_POINT_REG; //00

	IIC_Start(); 
	for(i = 0 ; i < 2 ; i++)
	{
		IIC_Send_Byte(buf[i]); 
		delay_us(20);
	}
	IIC_Stop(); 
}

最重要的读数据:

static u16 ReadData (void)
{ 
	u16 data;
	u8 readBuf[2];

	IIC_Start();

	IIC_Send_Byte(CMD_Read); 
	delay_us(20);

	readBuf[0] = IIC_Read_Byte(ACK);
	delay_us(200);

	readBuf[1] = IIC_Read_Byte(ACK); 
	delay_us(200);

	IIC_Stop();
	data = readBuf[0] * 256 + readBuf[1];

	return data;
}

读值:

u16 ADS1113_GetValue(void)
{
	u16 value = 0;

	GPIO_ResetBits(GPIOB, GPIO_Pin_12); 
	Ads1113_Config();
	
	delay_us(1000);
	PointRegister();	 
	delay_us(1000); 
	
	value = ReadData(); 
	delay_us(1000); 

	GPIO_SetBits(GPIOB, GPIO_Pin_12);

	return value;
}

到此,能够正常驱动ADS1113了。截图: