stm32驅動16位ADC(ADS1113)
阿新 • • 發佈:2018-12-11
相關原理圖:
其中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了。截圖: