SPI/I2C/UART
创始人
2024-05-14 08:59:53
0

SPI/I2C/UART

  • 1. 环境搭建
    • 1.1 USB转UART
    • 1.2 USB转SPI/I2C
    • 1.3 USB转I2C驱动
  • 2. 测试Host上可用性
    • 2.1 UART测试
    • 2.1 SPI测试
    • 2.1 I2C测试

1. 环境搭建

1.1 USB转UART

设备通过USB插入Host环境,通常可枚举出tty设备,如果没有出现,需要对模块进行驱动的安装。可通过Host代码直接访问这些设备

1.2 USB转SPI/I2C

当我们想调试一些SPI、I2C接口的传感器或者模块,可通过CH341 A/B模块作中转,它可通过USB接口将SPI/IIC数据在设备与Host之间进行传输,通过其驱动可在Host环境下注册SPI/IIC字符设备
CH341转SPI

  • 电平限制为3.3V或5V,只支持master模式
  • 速率固定为1.4MHz左右,数据长度固定8bit,模式固定为mode0,支持MSB/LSB
  • 支持最多3个从机,分别使用CS0/1/2作为片选,支持片选高/低有效
    CH341转I2C
  • 内部上拉电平可选3.3V或5V,只支持master模式
  • 速率支持20K/100K/400K/750KHz,只支持7位地址、8位数据

模块上有跳帽可以切换3.3V/5V,切换SPI+I2C/UART

USB转SPI驱动
驱动参考 https://github.com/gschorcht/spi-ch341-usb

git clone https://github.com/gschorcht/spi-ch341-usb.git
cd spi-ch341-usb
make
sudo make install

不将驱动安装到内核的话,可以在需要时手动加载驱动。
加载前先将CH341转串口和转I2C的驱动卸载,CH341转串口、转I2C、转SPI的驱动相互冲突

sudo rmmod ch341        #需要先卸载ch341,才能卸载usbserial
sudo rmmod usbserial
sudo rmmod i2c_ch341_usb

将仓库目录下的spi-ch341-usb.ko加载:

sudo insmod spi-ch341-usb.ko

设备1模块切换到SPI+I2C模式,插到主机USB上,此时通过 lsmod 可以看到spidev0.0/1/2,其中spidev0.x表示是SPI0总线上的设备,x用于区分各个从机(即通信时使能设备1上的CS0/1/2脚)。
电脑重启后需要重新加载spi-ch341-usb.ko

1.3 USB转I2C驱动

驱动参考 https://github.com/gschorcht/i2c-ch341-usb

git clone https://github.com/gschorcht/i2c-ch341-usb.git
cd i2c-ch341-usb
make
sudo make install

不将驱动安装到内核的话,可以在需要时手动加载驱动。
加载前先将CH341转串口和转SPI的驱动卸载,CH341转串口、转I2C、转SPI的驱动相互冲突:

sudo rmmod ch341        #需要先卸载ch341,才能卸载usbserial
sudo rmmod usbserial
sudo rmmod spidev
sudo rmmod spi_ch341_usb

将仓库目录下的i2c-ch341-usb.ko加载:

sudo insmod i2c-ch341-usb.ko

设备1模块切换到SPI+I2C模式,插到主机USB上,此时通过 lsmod 可以看到i2c_ch341_usb,通过 ls /dev 可以看到i2c-x,其中x根据原有的i2c设备编号而有所变化。
电脑重启后需要重新加载i2c-ch341-usb.ko。
如果insmod提示.ko文件invalid format,可能是linux内核版本更新了,需要重新编译。

2. 测试Host上可用性

2.1 UART测试

当插入的设备可接收AT命令时,可通过如下程序向tty设备发送AT\r,读取到OK。

#include 
#include 
#include 
#include 
#include 
#include 
#include int main(int argc, char *argv[])
{struct termios opt;char cmd[] = "AT\r";int fd;int ret;/* Switch TTY to raw mode */memset(&opt, 0, sizeof(opt));cfmakeraw(&opt);errno = 0;fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY);if (fd < 0)return -1;tcflush(fd, TCIOFLUSH);tcsetattr(fd, TCSANOW, &opt);write(fd, cmd, strlen(cmd));read(fd, buf, sizeof(buf));close(fd);
}

2.1 SPI测试

在Linux中编写应用程序测试SPI的可用性,可以使用类似如下代码,读取一个某个开发板/器件/模块的ID等寄存器验证:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
....../* path of spi dev,note the x of spidev0.x, must correspond to the CSx */
#define SPI_DEV "/dev/spidev0.1"
......int main( int argc, char *argv[] )
{....../* open the spi device */int handle_spi = 0;handle_spi = open(SPI_DEV, O_RDWR);/* since tx and rx will complete at the same time,one may use 1 message (the struct below) with rxbuf and txbuf,or may use 2 messages with txbuf and rxbuf respectively -- message 1 for tx first and message 2 for rx later, with a interval between 2 messages */struct spi_ioc_transfer spi_trans = {.tx_buf = (unsigned long)txbuf,.rx_buf = (unsigned long)rxbuf,.len = len,                        /* length of transmitted data */.delay_usecs = 0,                  /* interval between SPI_IOC_MESSAGEs */ */ .speed_hz = 1400000,               /* unavailable for CH341 */.bits_per_word = 8,                /* unavailabel for CH341 */};/* set SPI mode, unavailable for CH341*/     unsigned char mode = SPI_MODE_0;ret = ioctl(handle_spi, SPI_IOC_WR_MODE, &mode);/* transmit data through SPI device. The desired data is ready to read in rxbuf when transmitting completed*/ret = ioctl(handle_spi, SPI_IOC_MESSAGE(1), &spi_trans);/* close the spi device*/close(handle_spi);......
}

2.1 I2C测试

在Linux中编写应用程序测试I2C的可用性,可以使用类似如下代码,读取一个某个开发板/器件/模块的ID等寄存器验证

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
....../* path of i2c device */
#define I2C_DEV "/dev/i2c-7"/* address of the slave to communicate, in 7bit format, not left-shifted*/
#define SLAVE_ADDR  0x6C
......int main( int argc, char *argv[] )
{....../* open i2c device */int handle_i2c = 0;handle_i2c = open(I2C_DEV, O_RDWR);/* config the slave address */ret = ioctl(handle_i2c, I2C_SLAVE, SLAVE_ADDR);/* transmit data through i2c,slave addr and nW bit will be send first automatically */ret = write(i2c_fd, txbuf, tx_count);/* read data from i2c,slave addr and R bit will be send first automatically */   ret = read(i2c_fd, rxbuf, rx_count);/* close i2c device */close(handle_i2c);......
}

相关内容

热门资讯

原生安卓系统怎样升级,从基础到... 你有没有发现,你的安卓手机用久了,有时候就像老牛拉车一样,慢吞吞的?别急,今天就来给你支个招,让你的...
安卓13系统怎么开发,开发者的... 你有没有听说安卓13系统已经发布了?这可是个大新闻呢!作为一个热衷于手机开发的小伙伴,你是不是也跃跃...
安卓q系统镜像下载,轻松升级体... 你有没有听说安卓Q系统已经发布了?这可是安卓家族里的一大亮点呢!今天,我就要来给你详细介绍一下安卓Q...
安卓系统色彩校正软件,打造个性... 你有没有发现,手机屏幕的色彩有时候会让人感觉不太对劲?有时候,画面看起来有点灰蒙蒙的,有时候又太艳丽...
苹果能否下个安卓系统,开启新篇... 你有没有想过,苹果的iOS系统会不会有一天突然宣布,它要拥抱安卓的大家庭呢?想象iPhone和iPa...
树莓派 装 安卓系统,轻松安装... 你有没有想过,用树莓派装上安卓系统,那会是怎样一番景象呢?想象一个迷你电脑,竟然能运行起我们日常使用...
安卓系统怎么打印小票,安卓系统... 你是不是也遇到了这样的烦恼:手机里存了好多重要的小票,但是想打印出来保存或者报销,却发现安卓系统里的...
安卓10安装系统应用,轻松上手... 你有没有发现,你的安卓手机最近是不是有点儿“慢吞吞”的?别急,别急,今天就来给你支个招——升级安卓1...
美国不提安卓系统华为,迈向自主... 华为与美国:一场关于技术、市场与政策的较量在当今这个数字化的世界里,智能手机已经成为我们生活中不可或...
安卓系统怎么打开ppt,选择文... 你有没有遇到过这种情况:手里拿着安卓手机,突然需要打开一个PPT文件,却怎么也找不到方法?别急,今天...
谷歌退回到安卓系统,探索创新未... 你知道吗?最近科技圈可是炸开了锅,谷歌竟然宣布要退回到安卓系统!这可不是一个简单的决定,背后肯定有着...
安卓系统待机耗电多少,深度解析... 你有没有发现,手机电量总是不经用?尤其是安卓系统,有时候明明没怎么用,电量就“嗖”的一下子就下去了。...
小米主题安卓原生系统,安卓原生... 亲爱的手机控们,你是否曾为手机界面单调乏味而烦恼?想要给手机换换“衣服”,让它焕然一新?那就得聊聊小...
voyov1安卓系统,探索创新... 你有没有发现,最近你的手机是不是变得越来越流畅了?没错,我要说的就是那个让手机焕发青春的Vivo V...
电脑刷安卓tv系统,轻松打造智... 你有没有想过,家里的安卓电视突然变得卡顿,反应迟钝,是不是时候给它来个“大保健”了?没错,今天就要来...
安卓系统即将要收费,未来手机应... 你知道吗?最近有个大消息在科技圈里炸开了锅,那就是安卓系统可能要开始收费了!这可不是开玩笑的,这可是...
雷凌车载安卓系统,智能出行新体... 你有没有发现,现在的汽车越来越智能了?这不,我最近就体验了一把雷凌车载安卓系统的魅力。它就像一个聪明...
怎样拍照好看安卓系统,轻松拍出... 拍照好看,安卓系统也能轻松搞定!在这个看脸的时代,拍照已经成为每个人生活中不可或缺的一部分。无论是记...
安卓车机系统音频,安卓车机系统... 你有没有发现,现在越来越多的汽车都开始搭载智能车机系统了?这不,咱们就来聊聊安卓车机系统在音频方面的...
老苹果手机安卓系统,兼容与创新... 你手里那台老苹果手机,是不是已经陪你走过了不少风风雨雨?现在,它竟然还能装上安卓系统?这可不是天方夜...