相关原理图: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了。截图: