实操:按这四步走 完成NCV84090DR2G软硬件协同设计

实操:按这四步走 完成NCV84090DR2G软硬件协同设计

TechForum分享者:yinxiangxv

关键词:驱动,IO,ADC,开发板


第一步:NCV80490硬件电路搭建和负载驱动

要让上面的模块能够正常工作首先要提供一个稳定的直流电压12V。并且要明确每个引脚的功能和定义:

引脚连接说明:

VD (电源): 这是芯片的功率电源输入。

连接: 将这两个引脚(VD)直接连接到汽车电池的正极 (V_BAT, 通常为12V)。

设计要点: 在VD和GND之间放置一个100nF的陶瓷电容作为退耦电容,尽可能靠近芯片引脚。这能滤除电源噪声,保证芯片稳定工作。

GND (地): 芯片的参考地。

连接: 连接到系统的地平面 (GND)。

OUT (输出): 功率输出端。

连接: 将这两个引脚(OUT)连接到负载 Z_L 的一端。负载的另一端连接到系统地 (GND)。

IN (输入): 逻辑控制输入。

连接: 连接到MCU的一个GPIO输出引脚。MCU通过输出高电平(例如5V或3.3V)来命令芯片导通,输出低电平(0V)来命令芯片关断。

设计要点: 可以在MCU和IN引脚之间串联一个小电阻(如 1kΩ),用于限流保护MCU的GPIO口。

CS_EN (电流检测使能): 诊断功能使能。

连接: 连接到MCU的另一个GPIO输出引脚。MCU输出高电平来激活电流检测和所有诊断功能,输出低电平来关闭它们以降低功耗。

CS (电流检测): 模拟反馈输出。

连接: 连接到MCU的一个ADC(模数转换器)输入引脚。

设计要点: 这是最关键的外围电路设计。

在CS引脚和GND之间连接一个精密电阻 R_CS。芯片输出的检测电流 I_CS 流过这个电阻,产生一个MCU可以测量的电压 V_CS。R_CS 的值需要根据最大负载电流和MCU的ADC量程来计算(具体见应用案例)。

在CS引脚和GND之间并联一个小电容 C_CS(如 1nF)。它与 R_CS 组成一个RC低通滤波器,滤除噪声,为ADC提供一个稳定的信号。

image
image

如果上面的12v满足之后就要进行控制了。

按照这个思路进行:

. 简易原理图描述:

电源部分: V_BAT或者12v直流电源 → NCV84090的 VD 引脚。

负载部分: NCV84090的 OUT 引脚 → 负载 Z_L → GND。

控制部分 (MCU):

MCU GPIO_1 → 1kΩ电阻 → IN 引脚。

MCU GPIO_2 → CS_EN 引脚。

MCU ADC_1 → CS 引脚。

反馈部分: CS 引脚 → R_CS → GND。同时,CS 引脚 → C_CS → GND。

根据上面提到的控制部分,刚好手边有一个开发板,是创龙的t113,正好用来进行控制的逻辑。

为此要实现这些函数:

1. 驱动函数接口 (API) 设计:

void NCV84090_Init(pin_IN, pin_CS_EN, pin_CS): 初始化函数,配置MCU的GPIO和ADC引脚。

void NCV84090_TurnOn(): 打开开关。内部实现是将 IN 引脚置为高电平。

void NCV84090_TurnOff(): 关闭开关。内部实现是将 IN 引脚置为低电平。

void NCV84090_EnableDiagnostics(bool enable): 使能/禁能诊断。控制 CS_EN 引脚。

float NCV84090_ReADCurrent(): 核心功能,读取并返回以安培(A)为单位的负载电流。

FaultType NCV84090_CheckFault(): 诊断函数,返回当前检测到的故障类型(如正常、开路、短路等)。

2. 核心函数实现逻辑:

NCV84090_ReADCurrent() 实现:

确保开关已导通 (IN = High) 且诊断已使能 (CS_EN = High)。

等待稳定时间! 根据数据手册,从 IN 变高到 CS 信号稳定需要一个延迟 t_CS_High2。程序必须等待超过这个时间。

通过MCU的ADC读取 CS 引脚的电压 V_CS。

计算检测电流: I_CS = V_CS / R_CS。

查表计算真实电流: NCV84090的电流检测比 K 是非线性的。需要根据数据手册中的 K vs I_OUT 曲线创建一个查找表。通过 I_CS 估算 I_OUT 范围,然后在表中查找或插值得到准确的 K 值。

计算最终电流: I_OUT = I_CS * K。

返回 I_OUT。

NCV84090_CheckFault() 实现:

导通状态故障:

读取 V_CS 电压。如果 V_CS 远高于正常工作范围,达到了一个固定的故障电压 V_CS_FAULT,则说明发生了过流、短路或过热故障。

关断状态开路故障:

执行诊断序列:将 IN 置低,CS_EN 置高。

等待延迟 t_d_OL_off。

读取 V_CS 电压。如果此时 V_CS 被拉高到 V_CS_FAULT,则说明发生了开路负载故障。

第二步:确定T113上使用的GPIO

你需要查看你的 T113 开发板的原理图或引脚分布图,找到一个空闲的、可以作为 GPIO 输出的引脚。全志的芯片引脚命名通常是 P + 组号 + 序号,例如 PB5 (第B组的第5个引脚) 或 PG13 (第G组的第13个引脚)。

假设我们选择了 PB5 这个引脚。

image

第三步:在T113的Linux系统中控制GPIO

在 root@T113-Tronlong:~# 这个运行环境中,控制 GPIO 最直接、最标准的方法是通过 Linux 的 sysfs GPIO 接口。这是一种通过读写虚拟文件来控制硬件的方式,非常方便。

以下是完整的命令行操作步骤:

1. 导出 (Export) GPIO

首先,你需要告诉内核,你想要使用 PB5 这个引脚。你需要计算出它的编号。

GPIO 编号计算公式: (组号 ASCII – ‘A’) * 32 + 序号

对于 PB5: (‘B’的ASCII – ‘A’的ASCII) * 32 + 5 → (1) * 32 + 5 = 37

现在,导出这个GPIO:

echo 37 > /sys/class/gpio/export

执行成功后,系统会创建一个新的目录 /sys/class/gpio/gpio37。

2. 设置GPIO方向 (Direction)

接下来,你需要将这个GPIO设置为输出模式。

echo “out” > /sys/class/gpio/gpio37/direction

3. 控制GPIO输出高低电平

现在,你可以通过向 value 文件写入 1 或 0 来控制GPIO输出高电平或低电平了。

输出高电平 (3.3V) → 导通NCV84090 → 负载工作:

echo 1 > /sys/class/gpio/gpio37/value

当你执行这条命令时,T113的PB5引脚会输出高电平,NCV84090的IN引脚收到高电平,其内部开关导通,OUT引脚被拉到地,电流流过你的负载,负载开始工作(例如,继电器吸合,LED点亮)。

输出低电平 (0V) → 关断NCV84090 → 负载停止:

echo 0 > /sys/class/gpio/gpio37/value

当你执行这条命令时,PB5引脚输出低电平,NCV84090的IN引脚收到低电平,其内部开关断开,OUT引脚变为高阻态,负载上没有电流流过,负载停止工作。

4. (可选) 释放 (Unexport) GPIO

当你不再使用这个GPIO时,可以将其释放,让其他程序使用。

echo 37 > /sys/class/gpio/unexport

第四步:编写Shell脚本实现自动化控制

你可以把上述命令写到一个Shell脚本里,方便调用。例如,创建一个名为 control_load.sh 的脚本:

如何使用这个脚本:

在T113上,用vi control_load.sh创建并编辑这个文件,把代码粘贴进去。

给脚本添加执行权限: chmod +x control_load.sh

打开负载: ./control_load.sh on

关闭负载: ./control_load.sh off

这样,就成功地在你的T113运行环境中,通过编程(Shell脚本)的方式,利用GPIO控制了外部的NCV84090芯片,并驱动了一个12V的负载。

上面的代码是通过shell代码的方式进行运行的。不过也可以通过c代码的方式进行。

A screenshot of a computer program

AI-generated content may be incorrect.

下面看看相关函数的c代码如何实现:

使用C语言(推荐用于最终产品)

这是最正规、最高效的方式。我们需要利用Linux提供的系统调用来访问sysfs接口。

1. 环境准备

你的T113开发板的Linux系统里通常已经内置了C语言的交叉编译工具链(gcc)或者你可以通过opkg或apt安装它。

2. C语言代码实现

下面是一个C语言实现的示例,它基本实现了你设计的API。

文件: ncv84090_driver.c

# 运行编译好的程序

这样的就必须要启用虚拟机的环境进行编译,为此还是用这个shell代码比较直接:

image

后面的测试等下次再进行吧,这个逻辑上和硬件的连线上面没什么问题,调试没什么问题,应该就可以连接硬件后运行代码,并也可以配合示波器进行检测。

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <unistd.h>

#include <fcntl.h>

#include <stdbool.h>

// — 定义GPIO编号 (根据你的硬件连接修改) —

// 假设 IN -> PB5 -> 37

// 假设 CS_EN -> PG13 -> 205

#define PIN_IN_NUM 37

#define PIN_CS_EN_NUM 205

// — 全局变量存储引脚编号 —

static int pin_IN = -1;

static int pin_CS_EN = -1;

// ADC引脚通常通过IIO子系统访问,这里简化处理

// static int pin_CS = -1;

// — 底层GPIO操作函数 —

int gpio_export(int pin) {

char buffer[64];

int fd = open(“/sys/class/gpio/export”, O_WRONLY);

if (fd < 0) {

perror(“Failed to open export for writing”);

return -1;

}

int len = snprintf(buffer, sizeof(buffer), “%d”, pin);

if (write(fd, buffer, len) < 0) {

// Ignore error if already exported

}

close(fd);

return 0;

}

int gpio_set_direction(int pin, const char* dir) {

char path[64];

snprintf(path, sizeof(path), “/sys/class/gpio/gpio%d/direction”, pin);

int fd = open(path, O_WRONLY);

if (fd < 0) {

perror(“Failed to open direction for writing”);

return -1;

}

if (write(fd, dir, strlen(dir)) < 0) {

perror(“Failed to set direction”);

close(fd);

return -1;

}

close(fd);

return 0;

}

int gpio_set_value(int pin, int value) {

char path[64];

snprintf(path, sizeof(path), “/sys/class/gpio/gpio%d/value”, pin);

int fd = open(path, O_WRONLY);

if (fd < 0) {

perror(“Failed to open value for writing”);

return -1;

}

char val_str = (value == 1) ? ‘1’ : ‘0’;

if (write(fd, &val_str, 1) != 1) {

perror(“Failed to write value”);

close(fd);

return -1;

}

close(fd);

return 0;

}

// — ADC读取函数 (这是一个简化的示例) —

// 在真实的T113系统中,你需要通过IIO (Industrial I/O)子系统来读取ADC

// 通常是读取 /sys/bus/iio/devices/iio:deviceX/in_voltageY_raw 文件

float read_ADC_voltage() {

// 伪代码: 实际实现会更复杂

int raw_value;

float voltage;

char buffer[16];

// 假设ADC在iio:device0的通道1

int fd = open(“/sys/bus/iio/devices/iio:device0/in_voltage1_raw”, O_RDONLY);

if (fd < 0) {

perror(“Failed to open ADC raw file”);

return -1.0;

}

read(fd, buffer, sizeof(buffer)-1);

close(fd);

raw_value = atoi(buffer);

// 假设ADC是12位(4096),参考电压是1.8V

voltage = (float)raw_value / 4095.0 * 1.8;

printf(“ADC Raw: %d, Voltage: %.3fV\n”, raw_value, voltage);

return voltage;

}

// — API 实现 —

/**

* @brief 初始化NCV84090驱动

* @note 在Linux sysfs中,不需要传入pin号,硬编码或从配置文件读取

*/

void NCV84090_Init() {

pin_IN = PIN_IN_NUM;

pin_CS_EN = PIN_CS_EN_NUM;

printf(“Initializing NCV84090 driver…\n”);

gpio_export(pin_IN);

gpio_export(pin_CS_EN);

gpio_set_direction(pin_IN, “out”);

gpio_set_direction(pin_CS_EN, “out”);

// Set initial state

NCV84090_TurnOff();

NCV84090_EnableDiagnostics(false);

printf(“Initialization complete.\n”);

}

/**

* @brief 打开开关

*/

void NCV84090_TurnOn() {

gpio_set_value(pin_IN, 1);

}

/**

* @brief 关闭开关

*/

void NCV84090_TurnOff() {

gpio_set_value(pin_IN, 0);

}

/**

* @brief 使能/禁能诊断

*/

void NCV84090_EnableDiagnostics(bool enable) {

gpio_set_value(pin_CS_EN, enable ? 1 : 0);

}

/**

* @brief 读取并返回以安培(A)为单位的负载电流

*/

float NCV84090_ReADCurrent() {

// 1. 确保开关导通且诊断使能

NCV84090_TurnOn();

NCV84090_EnableDiagnostics(true);

// 2. 等待稳定时间 (t_CS_High2), 例如 200微秒

usleep(200);

// 3. 读取CS引脚电压

float v_cs = read_ADC_voltage();

if (v_cs < 0) {

return -1.0; // Read error

}

// — 简化处理,实际需要查找表 —

// 假设R_CS = 1kΩ, 那么 I_CS = V_CS / 1000

// 假设在工作点 K ≈ 5000 (需要查数据手册)

float i_cs = v_cs / 1000.0;

float k_ratio = 5000.0;

float i_out = i_cs * k_ratio;

// 操作完成后可以关闭诊断以降低功耗

NCV84090_EnableDiagnostics(false);

return i_out;

}

// FaultType NCV84090_CheckFault() { … } // 故障诊断函数实现类似

// — 主函数:测试API —

int main() {

NCV84090_Init();

printf(“Turning ON the load…\n”);

NCV84090_TurnOn();

sleep(2); // 保持开启2秒

printf(“Reading current…\n”);

float current = NCV84090_ReADCurrent();

if (current >= 0) {

printf(“Measured Load Current: %.3f A\n”, current);

} else {

printf(“Failed to read current.\n”);

}

sleep(1);

printf(“Turning OFF the load…\n”);

NCV84090_TurnOff();

return 0;

}

想参与一起讨论?欢迎到TechForum原文下留言:

【DigiKey免单狂欢】NCV84090DR2G软硬件设计-1

【DigiKey免单狂欢】NCV80490DR2G软硬件设计-2 

【DigiKey免单狂欢】NCV84090DR2G软硬件设计-3 

帖文内容源自DigiKey与21电源网 – 电子研习社的活动:

A screenshot of a computer

AI-generated content may be incorrect.

想知道更多不同活动资讯,请到热点活动页面了解更多→

A logo with black lines and red text

AI-generated content may be incorrect.

头像
得捷电子

评论已关闭。

Copyright©DigiKey Electronics