相关原理图:
其中VDD:
引脚定义:
/*
* 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 = 0
先看IIC
头文件包含内容:
#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
初始化
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();
}
起始信号:
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
}
结束信号:
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了。截图: