STM32F103C8T6驱动LDC1614测试程序

一、LDC1614芯片简介

LDC1614是德州仪器(TI)推出的4通道电感式传感控制器,通过检测电感线圈的频率变化,实现对导电物体(如金属)的距离、位置或材质的高精度测量。其核心特性包括:

  • 4个独立传感通道,支持多目标检测;

  • I2C接口(地址0x2A,7位),兼容标准/快速模式;

  • 可编程驱动电流(1.5mA~32mA),适配不同线圈;

  • 分辨率达28位,测量精度±1%;

  • 低功耗模式,适合电池供电场景。

二、硬件连接

2.1 核心连接表

LDC1614引脚 STM32F103C8T6引脚 功能说明
SCL PB6 (I2C1_SCL) I2C时钟线
SDA PB7 (I2C1_SDA) I2C数据线
VDD 3.3V 电源 (2.3V~3.6V)
GND GND 地线
INTB PA0 (可选) 中断输出(低有效)
CLKIN 悬空(内部RC振荡) 外部时钟输入(可选)

2.2 线圈连接

LDC1614需外接电感线圈(如PCB螺旋线圈,直径5~20mm),线圈两端接LDC1614的CH0-CH3引脚(每个通道对应一个线圈)。

三、STM32 I2C配置(标准库)

3.1 I2C初始化函数

c 复制代码
#include "stm32f10x.h"
#include "i2c.h"

void I2C1_Init(void) {
    GPIO_InitTypeDef GPIO_InitStructure;
    I2C_InitTypeDef I2C_InitStructure;
    
    // 使能时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
    
    // 配置PB6(SCL)、PB7(SDA)为复用开漏输出
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;  // 复用开漏
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    
    // I2C1配置
    I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
    I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;  // 2:1占空比
    I2C_InitStructure.I2C_OwnAddress1 = 0x00;  // 主机地址(可忽略)
    I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;  // 使能ACK
    I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;  // 7位地址
    I2C_InitStructure.I2C_ClockSpeed = 100000;  // 100kHz(标准模式)
    I2C_Init(I2C1, &I2C_InitStructure);
    
    I2C_Cmd(I2C1, ENABLE);  // 使能I2C1
}

3.2 I2C读写函数

c 复制代码
// I2C发送数据(寄存器地址+数据)
void I2C_WriteReg(uint8_t dev_addr, uint8_t reg_addr, uint16_t data) {
    while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));  // 等待总线空闲
    
    // 发送起始信号
    I2C_GenerateSTART(I2C1, ENABLE);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));  // EV5
    
    // 发送设备地址(写)
    I2C_Send7bitAddress(I2C1, dev_addr<<1, I2C_Direction_Transmitter);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));  // EV6
    
    // 发送寄存器地址
    I2C_SendData(I2C1, reg_addr);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));  // EV8
    
    // 发送数据(16位分两次发送)
    I2C_SendData(I2C1, (uint8_t)(data >> 8));  // 高8位
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
    I2C_SendData(I2C1, (uint8_t)(data & 0xFF));  // 低8位
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
    
    // 发送停止信号
    I2C_GenerateSTOP(I2C1, ENABLE);
}

// I2C读取数据(寄存器地址+读取数据)
uint16_t I2C_ReadReg(uint8_t dev_addr, uint8_t reg_addr) {
    uint16_t data = 0;
    
    while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
    
    // 发送起始信号
    I2C_GenerateSTART(I2C1, ENABLE);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));  // EV5
    
    // 发送设备地址(写)
    I2C_Send7bitAddress(I2C1, dev_addr<<1, I2C_Direction_Transmitter);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));  // EV6
    
    // 发送寄存器地址
    I2C_SendData(I2C1, reg_addr);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));  // EV8
    
    // 发送重复起始信号
    I2C_GenerateSTART(I2C1, ENABLE);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));  // EV5
    
    // 发送设备地址(读)
    I2C_Send7bitAddress(I2C1, dev_addr<<1, I2C_Direction_Receiver);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));  // EV6
    
    // 读取数据(16位)
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));  // EV7
    data = I2C_ReceiveData(I2C1) << 8;  // 高8位
    I2C_AcknowledgeConfig(I2C1, DISABLE);  // 最后一次读取关闭ACK
    I2C_GenerateSTOP(I2C1, ENABLE);  // 发送停止信号
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));  // EV7
    data |= I2C_ReceiveData(I2C1);  // 低8位
    
    I2C_AcknowledgeConfig(I2C1, ENABLE);  // 恢复ACK
    return data;
}

四、LDC1614初始化与配置

4.1 寄存器定义(关键寄存器)

c 复制代码
// LDC1614寄存器地址(部分)
#define LDC1614_DEV_ADDR   0x2A  // 7位I2C地址
#define REG_DATA_CH0      0x00  // 通道0数据寄存器(28位)
#define REG_DATA_CH1      0x02  // 通道1数据寄存器(28位)
#define REG_DATA_CH2      0x04  // 通道2数据寄存器(28位)
#define REG_DATA_CH3      0x06  // 通道3数据寄存器(28位)
#define REG_RCOUNT_CH0    0x08  // 通道0转换计数寄存器
#define REG_OFFSET_CH0    0x0C  // 通道0偏移寄存器
#define REG_SETTLECOUNT_CH0 0x10  // 通道0稳定计数寄存器
#define REG_CLOCK_DIVIDERS_CH0 0x14  // 通道0时钟分频寄存器
#define REG_CONFIG         0x1A  // 全局配置寄存器
#define REG_MUX_CONFIG     0x1B  // 多路复用配置寄存器
#define REG_DRIVE_CURRENT  0x1E  // 驱动电流寄存器

4.2 LDC1614初始化函数

c 复制代码
void LDC1614_Init(void) {
    // 1. 复位芯片(写入CONFIG寄存器,bit15=1)
    I2C_WriteReg(LDC1614_DEV_ADDR, REG_CONFIG, 0x8000);
    delay_ms(10);  // 等待复位完成
    
    // 2. 配置全局参数(CONFIG寄存器)
    // bit15=0(正常工作), bit14=1(启用INTB), bit13=0(连续转换模式)
    // bit12-10=000(分频系数1), bit9-0=0x000(保留)
    I2C_WriteReg(LDC1614_DEV_ADDR, REG_CONFIG, 0x4000);
    
    // 3. 配置多路复用(MUX_CONFIG寄存器)
    // bit15-13=000(通道序列0-3), bit12=0(自动扫描), bit11-8=0x0F(所有通道使能)
    // bit7-6=00(SETTLECOUNT分频), bit5-0=0x00(保留)
    I2C_WriteReg(LDC1614_DEV_ADDR, REG_MUX_CONFIG, 0x0F00);
    
    // 4. 配置驱动电流(DRIVE_CURRENT寄存器)
    // CH0-CH3驱动电流:0x1F(约16mA,根据线圈调整)
    I2C_WriteReg(LDC1614_DEV_ADDR, REG_DRIVE_CURRENT, 0x1F1F1F1F);
    
    // 5. 配置通道0参数(以CH0为例)
    I2C_WriteReg(LDC1614_DEV_ADDR, REG_RCOUNT_CH0, 0x0FFF);  // 转换计数(最大值)
    I2C_WriteReg(LDC1614_DEV_ADDR, REG_SETTLECOUNT_CH0, 0x0400);  // 稳定计数(1024 cycles)
    I2C_WriteReg(LDC1614_DEV_ADDR, REG_CLOCK_DIVIDERS_CH0, 0x1001);  // 时钟分频(1:1)
    I2C_WriteReg(LDC1614_DEV_ADDR, REG_OFFSET_CH0, 0x0000);  // 偏移量0
}

参考代码 STM32F103C8T6驱动LDC1614测试程序 www.youwenfan.com/contentcss/183148.html

五、数据读取与处理

5.1 读取通道数据

LDC1614每个通道数据为28位,存储在2个16位寄存器中(高12位+低16位),需拼接后转换为实际频率值。

c 复制代码
// 读取通道0数据(28位)
uint32_t LDC1614_ReadCh0(void) {
    uint16_t data_high = I2C_ReadReg(LDC1614_DEV_ADDR, REG_DATA_CH0);  // 高12位(bit15-4)
    uint16_t data_low = I2C_ReadReg(LDC1614_DEV_ADDR, REG_DATA_CH0+1);  // 低16位(bit15-0)
    uint32_t data_28bit = ((uint32_t)(data_high & 0x0FFF) << 16) | data_low;  // 拼接28位
    return data_28bit;
}

5.2 数据转换为频率

LDC1614的输出频率为:

fOUT=fREF×228RCOUNT×DATAf_{OUT}=\frac{f_{REF}×2^{28}}{RCOUNT×DATA}fOUT=RCOUNT×DATAfREF×228

其中:

  • fREFf_{REF}fREF:参考频率(由CLKIN或内部RC决定,默认4MHz);

  • RCOUNTRCOUNTRCOUNT:转换计数值(REG_RCOUNT_CH0,如0x0FFF=4095);

  • DATADATADATA:28位数据(LDC1614_ReadCh0()返回值)。

c 复制代码
float LDC1614_DataToFreq(uint32_t data_28bit) {
    const float f_ref = 4000000;  // 参考频率4MHz
    const uint16_t rcount = 0x0FFF;  // RCOUNT值(4095)
    float freq = (f_ref * (1UL << 28)) / (rcount * data_28bit);  // 计算频率(Hz)
    return freq;
}

六、主程序测试流程

c 复制代码
#include "stm32f10x.h"
#include "i2c.h"
#include "ldc1614.h"
#include "usart.h"  // 串口初始化(用于打印数据)

int main(void) {
    SystemInit();  // 系统时钟初始化(72MHz)
    USART1_Init(115200);  // 串口初始化(波特率115200)
    I2C1_Init();  // I2C初始化
    LDC1614_Init();  // LDC1614初始化
    
    printf("LDC1614 Test Start...\r\n");
    
    while (1) {
        // 读取通道0数据
        uint32_t data_ch0 = LDC1614_ReadCh0();
        float freq_ch0 = LDC1614_DataToFreq(data_ch0);
        
        // 打印结果(串口)
        printf("CH0 Data: 0x%08lX, Freq: %.2f Hz\r\n", data_ch0, freq_ch0);
        
        delay_ms(500);  // 500ms刷新一次
    }
}

七、测试结果与分析

7.1 预期输出

通过串口助手(如XCOM)可观察到类似以下数据:

c 复制代码
LDC1614 Test Start...
CH0 Data: 0x07A1203F, Freq: 123456.78 Hz
CH0 Data: 0x079F3045, Freq: 123987.65 Hz
...

当金属物体靠近线圈时,频率会降低 (电感增大),远离时频率升高(电感减小)。

7.2 常见问题排查

问题现象 可能原因 解决方案
无数据输出 I2C通信失败 检查接线(SCL/SDA是否接反)、上拉电阻(4.7kΩ)
数据全0或全F 线圈未连接或损坏 用万用表测量线圈电阻(应<10Ω)
频率值异常(如0Hz) RCOUNT或DRIVE_CURRENT配置错误 检查REG_RCOUNT_CH0和REG_DRIVE_CURRENT寄存器值

八、总结

本测试程序实现了STM32F103C8T6对LDC1614的基础驱动,包括I2C通信、寄存器配置、数据读取与转换。通过串口打印的28位数据和频率值,可验证LDC1614的正常工作。实际应用中,需根据线圈参数(电感、Q值)调整驱动电流RCOUNT,以优化测量范围和精度。

扩展方向

  • 添加多通道数据读取(CH1-CH3);

  • 实现距离-频率校准曲线(通过实验数据拟合);

  • 结合中断功能(INTB引脚)实现低功耗检测。

相关推荐
梦..3 小时前
Allegro学习记录(一)
arm开发·单片机·嵌入式硬件·学习·硬件架构·硬件工程·pcb工艺
零一iTEM3 小时前
低功耗开关机电路
嵌入式硬件
2401_858936883 小时前
51 单片机核心知识点:GPIO、中断、定时器与蜂鸣器驱动
单片机·mongodb·nosql
三佛科技-187366133973 小时前
FT838NB1-RT原边反馈5级能效电源控制器5V1A芯片电路图及管脚定义
单片机·嵌入式硬件·物联网
2501_918126913 小时前
学习所有6502写游戏控制器的语句
java·linux·网络·汇编·嵌入式硬件
qqssss121dfd4 小时前
STM32H750XBH6的ETH模块的IPv4 ARP offload功能分析
stm32·单片机·嵌入式硬件
小杨同学494 小时前
STM32 进阶封神之路(二十二):DMA 实战全攻略 ——ADC 采集 + 串口收发 + 内存复制(库函数 + 代码落地)
后端·单片机·嵌入式
修充电器上瘾4 小时前
驱动一个AIP650、数码管、按键、LED、红外、蜂鸣器控制板
单片机·嵌入式硬件
Nan_Feng_ya6 小时前
基于STM32的智能手表复刻成功(完全开源)
arm开发·stm32·pcb工艺·智能手表