SPI转can芯片CSM300详解以及Linux驱动移植调试笔记

2023-11-17

更多嵌入式Linux干货,请关注 一口Linux

一、CSM300概述

CSM300(A)系列是一款可以支持 SPI / UART 接口的CAN模块。

1. 简介

CSM300(A)系列隔离 SPI / UART 转 CAN 模块是集成微处理器、 CAN 收发器、 DC-DC
隔离电源、 信号隔离于一体的通信模块, 该芯片可以很方便地嵌入到具有 SPI 或 UART 接口的设备中, 在不需改变原有硬件结构的前提下使设备获得 CAN 通讯接口, 实现 SPI 设备或 UART 设备和 CAN 总线网络之间的数据通讯。

外观

CSM300

2. 参数

  1. 实现 SPI 或 UART 与 CAN 接口的双向数据通信;
  2. CAN 总线符合“ISO 11898-2”标准;
  3. 集成 1 路 SPI 接口, 支持用户自定义的速率, 最高可达 1.5Mbit/s(非自定义协议转换) ,或 1Mbit/s(自定义协议转换) ;
  4. 集成 1 路 UART 接口, 支持多种速率, 最高可达 921600bps;
  5. 集成 1 路 CAN 通讯接口, 支持多种波特率, 最高可达 1Mbps;
  6. 隔离耐压 2500VDC;
  7. 工作温度: -40℃~+85℃;
  8. 电磁辐射 EME 较低;
  9. 电磁抗干扰 EMS 较高;

型号

如上图所示 CSM300是5V工作电压,CSM300A是3.3V工作电压。

如果MCU、MPU侧工作电压不是1.8V那么久需要增加一个level shift来进行电压转换。

此次调试的板子使用的是CSM300A,只使用其中的SPI接口。

3. 引脚定义及参考电路

使用SPI转CAN功能时, 需要将MODE引脚接至高电平。MCU的SPI接口与CSM300(A)的 SPI 接口连接,同时 MCU 需要提供 GPIO 与 RST、 INT、 CTL0、 CTL1 引脚连接,实现对 CSM300(A)的有效监测与控制。 若需要通过 MCU 对CSM300(A)进行配置,则需要额外的 GPIO 与 CFG 引脚连接。

SPI 转 CAN 参考电路(CSM300A)
引脚说明:

引脚说明
引脚功能说明如下:

  1. MODE脚直接接高电压(高电平对应SPI模式,低电平对应UART模式);
  2. 10、11、12外接CAN总线,主要用于CAN通信;
  3. 3、6、7、24、19引脚接MCU/MPU,配置CSM300A的模式和读写操作都要依靠这几个引脚;
  4. 18、21、22、23这4个引脚需要接到MCU/MPU的SPI控制器引脚,主要是CPU侧发送配置信息和读写数据的SPI通路;
  5. 20 是INT引脚,CSM300A收到数据后,满足一定条件就会下拉该引脚,产生中断信号,通知CPU读取数据。

二、工作模式

1. 工作模式分类

CSM300(A)上电后, MODE、 CFG 引脚电平会决定产品处于 4 种不同的工作模式的其中一种: SPI 转 CAN 模式、 UART 转 CAN 模式、 SPI 配置模式、 UART 配置模式。

CSM300(A)工作模式如上表所示:

  1. 如果我们要配置CSM300A,就是要设置CSM300A模式为SPI配置模式,那么就需要将MODE引脚置为1,CFG置为0,RST置为1;
  2. 如果我们要通过CSM300A读写数据,就是要设置CSM300A模式为SPI转CAN模式,那么就需要将MODE引脚置为1,CFG置为1,RST置为1;
  3. 读写数据的操作,都属于SPI转CAN模式,不需要切换模式。
  4. 若需要切换产品的工作模式,更改引脚电平后,必须对产品进行复位,才能使其进入设
    定的工作模式。需要注意的是,为保证成功复位, 复位保持时间最少为 100us,复位后,
    产品初始化等待时间最少 3ms,待产品初始化完成后,才能进行正常操作。

下图是不同模式切换的时序图。
工作模式切换时序

2. SPI 转 CAN 模式(数据读写)

在此工作模式下, CSM300(A)始终作为 SPI 从机, SPI 限定工作在模式 3(CPOL、 CPHA
均为 1),数据长度限定为 8 位, MSB 高位先传输。透明转换、透明带标识转换下最高通信
速率为 1.5Mbps,自定义协议转换最高通信速率为 1Mbps。

SPI 主机可以发送数据至 CAN 总线端, 且可接收 CAN 总线端收到的数据。 此时 UART
接口无效,不会处理任何出现在 UART 接口的数据,也不会返回 CAN 总线端接收到的数据
至 UART。

  1. SPI 帧
    SPI 一次片选有效至片选无效之间的数据定义为一帧数据。 帧与帧之间读写缓冲区数据应有 40us 的时间间隔。

主机读数据帧主机写数据帧

3. SPI 配置模式

在此模式下, CSM300(A)处于等待配置状态, 无法向 CAN 端发送或接收数据。此模式下仅能通过 SPI 接口进行配置。

三、主机控制

CSM300(A)有两个 SPI 主机控制引脚 CTL0, CTL1, 受主机端控制。主机通过控制 CTL0,
CTL1 引脚, 使 CSM300(A)进入不同的功能状态,实现对 CSM300(A)不同操作目的。 主机端控制引脚电平不同对应功能如下表所示:

SPI 模式下主机控制功能
主机可以通过读从机当前状态来获取产品当前可以读取的字节数以及可以写入的字节
数。主机将功能选择为主机读状态,然后通过 SPI 读出 4 个字节,即为状态码。状态码由
32 个位构成,具体定义如下表所示。
状态码
若定义 status[]数组为 8 位整型, 通过 SPI 读状态依次读出的数据为 status[0]、 status[1]、
status[2]、 status[3],则其数据结构如下图:

状态字节数据结构

四、反馈机制(中断)

CSM300(A)只能作为 SPI 从机,不能主动地控制其他 SPI 总线设备,所以如果接收CAN数据帧之后,必须主动返回给CPU侧。

CSM300(A)硬件上的 INT 反馈引脚, 此引脚与主机连接,出现以下两种情况时, INT
引脚会由高电平变成低电平,通知主机进行读数据操作(为避免数据丢失,建议主机使用低
电平触发方式检测):

  1. CAN 缓冲区 CAN 帧数达到设置的触发点时
    当产品 CAN 总线端接收缓冲区接收到的 CAN 帧数达到触发点时, INT 引脚电平置低,
    直到缓冲区清空, INT 引脚才会恢复高电平。用户可以在获得 INT 信号之后查询 CSM300(A)
    的状态,获取可读字节数,然后读取缓冲区 CAN 数据。

  2. CAN 缓冲区数据少于触发帧数,且在设定时间内主机未读取时
    CAN 缓冲区有数据但少于触发帧数时,若总线长时间未有新增数据,且主机未进行读
    取操作时, CAN 接收缓冲区的数据将有可能长期得不到处理, 这就导致数据的实时性不高。
    为了解决少量数据的实时性问题, CSM300(A)内部设置了一个计时器,若 CAN 缓冲区的数
    据在一定时间内未被读取, 将触发 INT 引脚置低,通知主机读取数据。 CSM300(A)在接收
    到最后一帧数据时, 计时器启动,主机进行读取操作时复位计时器。

五、组网方式

CAN 总线一般使用直线型布线方式,总线节点数可达 110 个。 布线推荐使用屏蔽双绞线, CANH、 CANL 与双绞线线芯连接, CGND 与屏蔽层连接,最后屏蔽层单点接地。

得益于 CSM300(A)的最低波特率 5kbps,总线的最长通信距离可达 10km。
推荐组网示意图

六、移植

1. 硬件连接图

硬件连接图

如上图所示:

  1. SOC上已经集成了SPI控制器,厂家的sdk已经包含了spi控制器的设备树和驱动信息;
  2. SOC的SPI控制器引脚需要先连接level shift进行升压,板子电压是1.8V,而CSM300要求电压是3.3V;
  3. SOC的GPIO 76/107/113/114通过level shift分别连接CSM300A的RST/CFG/CTL1/CTL0;
  4. 在PC上运行CAN-Test软件,可以通过USB转CAN设备从CAN总线上读取和发送数据。

【注】USB转CAN设备,可以自行搜索,杜绝广告。

2. 设备树

以下是官方提供的设备树:

csm300@0 {
	pinctrl-names = "default";
	pinctrl-0 =<&pinctrl_csm300>;
	gpios=<&gpio3 21 0    /*ctl0*/
		&gpio3 22 0 /*ctl1*/
		&gpio3 30 0 /*rst*/
		&gpio3 31 0 /*cfg*/
	>;
	interrupt-parent = <&gpio3>;
	interrupts = <26 IRQ_LEVEL_LOW>;
	compatible = "zhiyuan,csm300";
	spi-max-frequency = <500000>;
	reg = <1>;
	status = "okay";
};

以下是根据自己的平台修改的结果,读者移植的时候需要根据自己的平台来移植,不可教条。

csm300@0 {
	pinctrl-names = "default";
	gpios=<&gpio 114 0    /*ctl0*/
		&gpio 113 0 /*ctl1*/
		&gpio 76 0 /*rst*/
		&gpio 107 0 /*cfg*/
	>;
	interrupt-parent = <&gpio>;
	interrupts = <196 IRQ_LEVEL_LOW>;
	compatible = "zhiyuan,csm300";
	spi-max-frequency = <500000>;
	reg = <0>;
	status = "okay";
};

3. 驱动

官方会提供驱动程序csm300.c,具体实际原理,本篇暂不讨论。

拷贝到以下目录:

drivers/net/can/spi

修改本级目录下的Makefile

 obj-$(CONFIG_CAN_CSM300)	+= csm300.o

修改本级目录下的Kconfig

config CAN_CSM300
	tristate "Microchip CSM300 driver"
	depends on SPI 
	---help---
	  Driver for the Microchip CSM300  .

执行make menuconfig
驱动位置如下:
menuconfig
选中该驱动:

menuconfig重新编译内核即可。

注意:该驱动还需要依赖CAN和SPI,一定要选上 。

4. 增加调试接口

在调试过程中,会有各种原因导致csm300驱动无法注册成功,那如何判定是spi控制器驱动有问题,还是csm300驱动有问题呢?

为了方便通过spi控制器发送出波形,我们增加以下代码,用于在板子目录/sys/bus/spi/drivers/csm300中创建state文件节点,通过写入不同的值来产生spi数据,或者控制RST、 CFG、 CTL0、 CTL1这4个引脚。

  1. 增加函数csm300_spi_store()
    测试接口 重点说明一下函数**check_csm300()**是驱动自带的用于测试CSM300的SPI通信功能的函数。

该函数会先将CSM300A设置为SPI配置模式,然后写入9个数据,然后再读取出数据,进行校验数据是否正确。

  1. 修改probe函数
struct net_device *global_net = NULL ;
csm_probe()
{
	……
	global_net = net;
	ret = check_csm300(net);
	……
	ret = driver_create_file(&(csm300_can_driver.driver),&driver_attr_state);
	if(ret < 0){
		ret = -ENOENT;
		goto out_free;
	}
	……
}
  1. 测试命令
    进入csm300模块目录
cd /sys/bus/spi/drivers/csm300
  1. 产生spi数据
echo 3 > state
  1. 拉高RST、 CFG、 CTL0、 CTL1
echo 1 > state
  1. 拉低RST、 CFG、 CTL0、 CTL1
echo 0 > state

5. 正确的开机log与波形

开机后驱动会调用check_csm300()来测试spi通道,发送的数据为F7:F8:02……
正确的开机log
以下为SPI接口的CLK和MOSI引脚的波形:
开机SPI的波形可以看到数据与我们发送的是一致的。

6. 接收数据波形图

接收数据步骤如下:

  1. 运行于PC上的CAN Test 软件发送数据 00 01 02 03 04 05 06 07,
  2. 经过USB转CAN设备后,转换成了差分信号,
  3. 到达CSM300A之后,信号被调制成举行方波,
  4. CSM300A通过拉低引脚INT向cpu发送中断信号,调用CSM300A注册的中断函数,
  5. 运行于CPU上的CSM300A中断程序通过SPI接口读走CSM300A上的数据,
  6. CSM300A缓冲区数据被读走后,拉高INT,
  7. 驱动程序将接收到的数据上传给应用层,于是candump命令得到了CAN帧的数据。

接收数据流程数据发送过程和上述过程类似。

7. CAN命令

如果文件系统中没有can命令,需要自行移植。

1) 设置波特率并开启can0口

ip link set can0 up type can bitrate 800000

2) 发送数据

cansend can0 1F334455#1122334455667788

3) 查看接收的数据

candump can0

七、出错记录

调试过程中遇到了很多的错误,CSM300A定位问题步骤:

  1. 首先用示波器测试CSM300的MOSI引脚的波形,是不是和第七章第5节的波形一致,如果不一致,说明SPI控制器驱动加载不正确;
  2. 要通过SPI控制器产生数据,使用命令echo 3 > state;
  3. 如果波形一致,就测量RST、 CFG、 CTL0、 CTL1这四个引脚,查看电平是否正确;
  4. RST、 CFG、 CTL0、 CTL1控制是否正确,可以用echo 0 > state、echo 1 > state分别拉低拉高,查看对这几个引脚的控制是否正常。

基本上照着这个思路去调试很快就能定位到问题。

以下是驱动加载出错的log,出错的原因主要是调用check_csm300()函数向CSM300A写入数据再读取出来后数据不匹配,从而判定加载出错。
出错log

1. CFG引脚拉低异常

现象:
check_csm300()函数始终报错。

分析:
check不成功,基本上原因是SPI控制器与CSM300通信出了问题。
首先用示波器,查看SPI发送的数据是否正常到达CSM300(用示波器抓取SSEL、CLK、MOSI),结果是正常的。

于是检测检测 RST、 CFG、 CTL0、 CTL1四个引脚。
如下图所示,使用echo 0 > state 拉低CFG引脚,发现没有拉到0V。
在这里插入图片描述解决方案:

交给硬件工程师去改。这兄弟给CFG加了一个反向电阻,驱动部分需要将所有设置CFG的代码,全部反置。

gpio_set_value(priv->CFG,0);
修改成
gpio_set_value(priv->RST,1);
gpio_set_value(priv->CFG,1);
修改成
gpio_set_value(priv->RST,0);

2. RST 延时不够

现象:
echo 0 > state 可以拉低,测量也是正确的,但是CSM300始终无法接收到数据帧。

分析:
一般数据接收不到,有两种可能:就是CSM300给出的中断信号CPU没有截取到,CSM300没有处于SPI转CAN模式。

先用示波器确定了,USB转CAN的数据已经成功到达CSM300,于是检测对应的引脚电平 RST、 CFG、 CTL0、 CTL1,发现也是对的。

检查中断计数,用cat /proc/interrupts查看CSM300是否有中断计数,结果发现数据为0。

怀疑CSM300没有rst成功,于是执行echo 3 > state,查看rst是否正确设置,结果发现以下波形,确定了该引脚拉高比较缓慢,所以CSM300采样不到这个电平。

在这里插入图片描述

修改方法:
驱动中每次rst操作,都要增加延迟时间:

gpio_set_value(priv->RST,0);
usleep_range(2000,2300);
gpio_set_value(priv->RST,1);

修改后,执行echo 3 > state,RST波形如下所示。
在这里插入图片描述

官方资料下载
https://www.zlg.cn/index.php/power/power/product/id/218.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SPI转can芯片CSM300详解以及Linux驱动移植调试笔记 的相关文章

  • 使用可加载内核模块修改帧缓冲区(/dev/graphics/fb0)参数

    Problem 我必须配置 Android 平台使用的各种 LCD 显示器 几乎在所有情况下 都没有针对感兴趣的 LCD 显示器免费提供的电气规格 但通过经验和逆向工程 可以很好地猜测参数 我正在尝试使用可加载内核模块来微调显示参数 也欢迎
  • 通用 ELF 中的重定位(EM:40)

    我尝试从 Ubuntu 交叉编译到Friendly arm 但出现了奇怪的错误 root kevin VirtualBox home kevin Desktop makef make ARCH arm CROSS COMPILE arm n
  • ARM 汇编 SOS 中的 64 位除法

    我正在计算 16 个 64 位数字相加的平均值 我认为我已经正确完成了所有加法 但现在我需要弄清楚如何将 64 位数字除以 16 但我被困住了 任何帮助都会非常感谢你 到目前为止 这是我的代码 tableSize EQU 16 sum EQ
  • 将 ZeroMQ 交叉编译为 ARM,以便在 MonoTouch iPhone 应用程序配置设置中使用

    我正在尝试在使用 MonoTouch 用 C 开发的 iPhone 应用程序中使用 ZeroMQ 库 我几乎解决了所有的问题 却在最后一道坎倒下了 我正在使用 ZeroMQ 2 1 10 和 C CLR 绑定 包装器 并在 Mac OS X
  • 如何在 ARM 架构上从 RAM 运行代码

    我正在对 ARM Cortex R4 进行编程 并且有一些二进制文件 我想从 TCRAM 执行它们 只是为了看看性能的提升是否足够好 我知道我必须编写一个函数来将二进制文件复制到 RAM 这可以通过链接器脚本来完成 并且知道二进制文件的大小
  • 嵌入式 C++ (ARM9) 单元测试

    我来自 Java 和 JUnit 的世界 我演示了 Hudson 以及我使用 JUnit 取得的所有成果 我想在嵌入式设备上对 C 代码执行相同的操作 但找不到从哪里开始 该项目使用 iccarm exe IAR 编译器 进行编译 现在使用
  • 将结构体偏移属性赋予汇编器

    如何将 C 结构体的偏移量发送到汇编代码 例如 在我的 C 代码中 typedef struct unsigned int a unsigned int b CMyStruct 我向 ASM 函数发送一个 CMyStruct 结构的指针 假
  • 适用于arm(cortex-m3)的位置独立可执行文件(-pie)

    我正在使用codesourcery g lite 基于gcc4 7 2版本 为stm32 Cortex m3 编程 我希望动态加载可执行文件 我知道我有两个选择 1 可重定位的elf 需要一个elf解析器 2 具有全局偏移寄存器的位置无关代
  • 用于 RHEL 的 gdb-multiarch

    我正在尝试寻找方法来运行gdb 多架构RHEL 中的命令 我已经安装了用于 ARM 处理的 QEMU 模拟器 我想安装GDB进行调试 我能够安装GDB 多体系结构在 Ubuntu 中运行命令成功 sudo apt get GDB multi
  • 读取和打印手臂组件中的字符串

    我正在使用 ARMSim 刚刚开始学习汇编 所以如果我看起来一无所知 请原谅我 但我正在尝试从输入文件中读取字符串 然后将其打印到输出屏幕 到目前为止我有 equ SWI Open 0x66 open a file equ SWI Clos
  • Linux malloc() 在 ARM 和 x86 上的行为是否不同?

    这个网站上有很多关于内存分配的问题 但是我 找不到专门解决我的问题的人 这 问题 https stackoverflow com questions 19148296 linux memory overcommit details似乎最接近
  • 尝试使用 qemu-arm 运行arm二进制文件时如何解决“加载共享库时出错”?

    我正在运行 Linux Mint 14 并安装了 qemu qemu user 和 gnueabi 工具链 我编译了 test carm linux gnueabi gcc test c o test 当我尝试跑步时qemu arm usr
  • 有没有办法在 Xcode 4 中为 ARM 而不是 Thumb 进行编译?

    如果有很多浮点运算正在进行 Apple 建议针对 ARM 进行编译 而不是针对拇指进行编译 我的整个应用程序几乎是一个大型浮点运算 iOS 应用程序开发工作流程指南中是这样说的 iOS 设备支持两种指令集 ARM 和 Thumb Xcode
  • 产生并处理软件中断

    有人可以告诉我如何在Linux下生成软件中断然后用request irq处理它吗 或者也许这是不可能的 您可以使用软中断来代替 您可以通过编辑 include linux interrupt h 来定义您的 sofirq 然后使用函数 ra
  • 了解 ctags 文件格式

    我使用 Exhuberant ctags 来索引我的 c 项目中的所有标签 c project 是 Cortex M7 微控制器的嵌入式软件 结果是一个标签文件 我正在尝试阅读该文件并理解所写的内容 根据我找到的 ctags 和 Exhub
  • 为什么当大小大于 50 时,该程序花费的时间会呈指数级增长?

    所以我正在为类编写一个 ARM 汇编快速排序方法 我对大部分内容都有了解 除了复杂性没有意义 我们将其与我们制作的另一种冒泡排序方法进行比较 它对于具有 1 个参数和 10 个参数的示例表现更好 然而 我什至无法比较 100 个参数测试 因
  • 基于 Windows 8 ARM 的平板电脑上的 VB6

    随着 Windows 8 将支持 VB6 我的问题是 Microsoft 是否在任何地方表示 是或否 VB6 应用程序将在基于 ARM 的平板电脑上运行 如果没有 是否有任何 ARM 模拟器 以便我们可以在 Windows 8 ARM 平板
  • Qemu flash 启动不起作用

    我有一本相当旧的 2009 年出版 嵌入式 ARM Linux 书 其中使用u boot and qemu 的用法qemu与u boot书中对二进制的解释如下 qemu system arm M connex pflash u boot b
  • 使用 NEON 内在函数除以浮点数

    我当时正在处理四个像素的图像 这是在armv7对于 Android 应用程序 我想分一个float32x4 t向量由另一个向量组成 但其中的数字与大约不同0 7 to 3 85 在我看来 除法的唯一方法是使用右移 但这是针对一个数字2 n
  • iPhone 3GS 上的 ARM 与 Thumb 性能比较,非浮点代码

    我想知道是否有人有关于 iPhone 3GS 上 ARM 与 Thumb 代码性能的硬性数据 特别是对于非浮点 VFP 或 NEON 代码 我知道 Thumb 模式下的浮点性能问题 更大的 ARM 指令的额外代码大小是否会在某个时刻成为性能

随机推荐

  • Python日志库logging总结(最全的版本)

    转自 https cloud tencent com developer article 1354396 1 日志级别 Python 标准库 logging 用作记录日志 默认分为六种日志级别 括号为级别对应的数值 NOTSET 0 DEB
  • (前端)HTML之表格

    表格标签 table 的基本语法 table 表格容器tr 列td 单元格th 粗体caption 标题列 例子 table width 400 border 1 cellspacing 2 cellpadding 2 align left
  • python中两种getter和setter方法

    当给属性赋值的时候 使用实例 属性 属性值的方式显然把属性暴露出来了 并且也无法对属性值进行限制检查 java中提供了setter和getter方法 那么python是如何做的呢 在绑定属性时 如果我们直接把属性暴露出去 虽然写起来很简单
  • 【指针内功修炼】函数指针 + 函数指针数组 + 回调函数(二)

    文章目录 1 函数指针 2 函数指针数组 函数指针数组的用途 3 指向函数指针数组的指针 4 回调函数 冒泡排序 qsort 排序 qsort 排序整型数组 qsort 排序结构体 模拟实现 qsort 1 函数指针 函数指针 顾名思义 就
  • List转换为String

    public static void main String args List
  • JBOSS实践一:安装

    因为工作关系 需要接受一套基于JBOSS容器的应用 首先从JBOSS环境搭建开始 JBOSS环境可以在一台机器上运行 也可以在一台机器上部署多套JBOSS 一 目标 1 在一台机器上部署JBOSS 4 2 2 GA 原系统运行于此 2 在一
  • Ubuntu18.04安装pcl(过程/坑记录式教程)

    Ubuntu18 04安装pcl 1 下载pcl 2 安装依赖项 3 编译 4 安装 5 网上教程说要安装QT5和VTK 但按照本文的 本文记录了安装时出现的问题 出错的安装命令也记录了 建议浏览一遍再参考 不要错用了错误的指令 1 下载p
  • background属性介绍

    background属性在CSS中有较多的应用 主要用来设置背景颜色 图片 background属性可以分开写 也可以合并 建议合并减少代码量 1 background color 设置背景颜色 设置的背景颜色会填充元素的内容 内边距和边框
  • 【SpringBoot笔记39】SpringBoot + SockJS + Stomp实现WebSocket通信(建立连接、发送消息、订阅消息、断开连接)

    这篇文章 主要介绍SpringBoot SockJS Stomp实现WebSocket通信 建立连接 发送消息 订阅消息 断开连接 目录 一 WebSocket通信 1 1 前端环境 1 2 后端环境 1 3 添加WebSocket配置
  • 传统程序优化与终身程序优化

    传统程序优化示例一 cpu示例 3个方面浅谈程序优化 每一个程序员都有一个大梦想当初在学校实验室的时候 常常写一个算法 让程序跑着四处去晃荡一下回来 结果也就出来了 可工作后 算法效率似乎重要多了 毕竟得真枪实弹放到产品中 卖给客户的 很多
  • uni-app,文本实现展开、收起全文

    效果 思路 1 根据文本显示的布局中 每行大致能显示的文字个数 实例是大致每行26个文字 2 首先加载页面时 根据文字总长度判断是否超出自定义行数 来处理相应的数据 多余自定义行数 截取对应的文字个数做显示 代码与讲解 1 设置参数 scr
  • 【Docker】Docker快速入门,常用网址与常用命令

    目录 一 docker常用网址 建议收藏 docker官方公开库 Docker Hub docker官方网站 Home Docker docker菜鸟联盟教程 Docker 教程 菜鸟教程 二 docker常用命令 一 镜像使用 1 镜像操
  • Mastering Debugging in Visual Studio 2010 - A Beginner's Guide

    Mastering Debugging in Visual Studio 2010 A Beginner s Guide http www codeproject com Articles 79508 Mastering Debugging
  • 非常好用的自动化运维工具------ansible

    目录 一 ansible 简介 1 ansible 是什么 2 ansible 特点 3 ansible 架构图 二 ansible的配置部署 1 使用 yum 安装epel源和ansible 2 修改ansible的仓库文件 3 配置公私
  • 一图看懂 Unity函数执行顺序/Unit脚本生命周期

    温故而知新 有些函数过久了忘了调用顺序 发个文记一下 下边有对各个函数的解释 第一个场景加载 这些函数在场景开始时被调用 场景中的每个对象一次 Awake 这个函数总是在任何 Start 函数之前调用 也只是在一个预制件被实例化 如果游戏对
  • 二叉树交换左右子树的三种实现方式

    二叉树交换左右子树的三种实现方式 顺序存储结构 链式存储结构 顺序存储结构 交换左右子树实际上就是同层之间交换位置 在顺序存储结构下 先确定树的深度 再划分层 每个层内做交换即可 链式存储结构 递归实现很简单 非递归可以借助栈或队列辅助实现
  • 区块链数据库

    大家好 这里是链客区块链技术问答社区 链客 有问必答 区块链是互联网未来十年中举足轻重的技术 区块链 Blockchain 或者说分布式账本 DLT Distributed Ledger Technology 最早是起源于比特币的一个重要概
  • ruoyi框架时间范围range增加今日,近7日,近30日时间选择

    原先layui时间控件是不支持今日 近7日 近30日选择的 网上的解决方法是直接在引用的js中修改代码 这是一种方法 但是对于不能修改源代码的童鞋来说是不行的 所以一下解决方法诞生了 直接添加这三个按钮并和时间控件 laydate 有友好的
  • 【数字图像处理】图像形态学算法C语言实现(图像卷积,膨胀,腐蚀,开运算,闭运算,顶帽,黑帽,雕版,锐化)

    文章目录 一 图像卷积 1 图像卷积 2 数字信号处理中的卷积 3 数字图像处理中的卷积 二 图像卷积实现各种形态学运算 腐蚀 膨胀 形态学梯度 开运算 闭运算 顶帽 黑帽 雕版 锐化 li conv c main c 三 效果展示 原图
  • SPI转can芯片CSM300详解以及Linux驱动移植调试笔记

    更多嵌入式Linux干货 请关注 一口Linux 一 CSM300概述 CSM300 A 系列是一款可以支持 SPI UART 接口的CAN模块 1 简介 CSM300 A 系列隔离 SPI UART 转 CAN 模块是集成微处理器 CAN