0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

安卓端的串口通信實(shí)踐講解1

jf_78858299 ? 來(lái)源:Android技術(shù)之家 ? 作者:Android技術(shù)之家 ? 2023-04-23 17:59 ? 次閱讀

前言

在上一篇文章中我們講解了關(guān)于串口的基礎(chǔ)知識(shí),沒(méi)有看過(guò)的同學(xué)推薦先看一下,否則你可能會(huì)不太理解這篇文章所述的某些內(nèi)容。

這篇文章我們將講解安卓端的串口通信實(shí)踐,即如何使用串口通信實(shí)現(xiàn)安卓設(shè)備與其他設(shè)備例如PLC主板之間數(shù)據(jù)交互。

需要注意的是正如上一篇文章所說(shuō)的,我目前的條件只允許我使用 ESP32 開(kāi)發(fā)版燒錄 Arduino 程序與安卓真機(jī)(小米10U)進(jìn)行串口通信演示。

準(zhǔn)備工作

由于我們需要使用 ESP32 燒錄 Arduino 程序演示安卓端的串口通信,所以在開(kāi)始之前我們應(yīng)該先把程序燒錄好。

那么燒錄一個(gè)怎樣的程序呢?

很簡(jiǎn)單,我這里直接燒了一個(gè) ESP32 使用 9600 的波特率進(jìn)行串口通信,程序內(nèi)容就是 ESP32 不斷的向串口發(fā)送數(shù)據(jù) “e” ,并且監(jiān)聽(tīng)串口數(shù)據(jù),如果接收到數(shù)據(jù) “o” 則打開(kāi)開(kāi)發(fā)版上自帶的 LED 燈,如果接收到數(shù)據(jù) “c” 則關(guān)閉這個(gè) LED 燈。

代碼如下:

#define LED 12


void setup() {
  Serial.begin(9600);
  pinMode(LED, OUTPUT);
}


void loop() {
  if (Serial.available()) {
    char c = Serial.read();
    if (c == 'o') {
      digitalWrite(LED, HIGH);
    }
    if (c == 'c') {
      digitalWrite(LED, LOW);
    }
  }


  Serial.write('e');


  delay(100);
}

上面的 12 號(hào) Pin 是這塊開(kāi)發(fā)版的 LED。

使用 Arduino自帶串口監(jiān)視器測(cè)試結(jié)果:

圖片

可以看到,確實(shí)如我們?cè)O(shè)想的通過(guò)串口不斷的發(fā)送字符 “e”,并且在接收到字符 “o” 后點(diǎn)亮了 LED。

安卓實(shí)現(xiàn)串口通信

原理概述

眾所周知,安卓其實(shí)是基于 Linux操作系統(tǒng),所以在安卓中對(duì)于串口的處理與 Linux 一致。

在 Linux 中串口會(huì)被視為一個(gè)“設(shè)備”,并體現(xiàn)為 /dev/ttys 文件。

/dev/ttys 又被稱為字符終端,例如 ttys0 對(duì)應(yīng)的是 DOS/Windows 系統(tǒng)中的 COM1 串口文件。

通常,我們可以簡(jiǎn)單理解,如果我們插入了某個(gè)串口設(shè)備,則這個(gè)設(shè)備與 Linux 的通信會(huì)由 /dev/ttys 文件進(jìn)行 “中轉(zhuǎn)”。

即,如果 Linux 想要發(fā)送數(shù)據(jù)給串口設(shè)備,則可以通過(guò)往 /dev/ttys 文件中直接寫(xiě)入要發(fā)送的數(shù)據(jù)來(lái)實(shí)現(xiàn),如:

echo test > /dev/ttyS1 這個(gè)命令會(huì)將 “test” 這串字符發(fā)送給串口設(shè)備。

如果想讀取串口發(fā)送的數(shù)據(jù)也是一樣的,可以通過(guò)讀取 /dev/ttys 文件內(nèi)容實(shí)現(xiàn)。

所以,如果我們?cè)诎沧恐邢胍獙?shí)現(xiàn)串口通信,大概率也會(huì)想到直接讀取/寫(xiě)入這個(gè)特殊文件。

android-serialport-api

在上文中我們說(shuō)到,在安卓中也可以通過(guò)與 Linux 一樣的方式--直接讀寫(xiě) /dev/ttys 實(shí)現(xiàn)串口通信。

但是其實(shí)并不需要我們自己去處理讀寫(xiě)和數(shù)據(jù)的解析,因?yàn)楣雀韫俜浇o出了一個(gè)解決方案:android-serialport-api

為了便于理解,我們會(huì)大致說(shuō)一下這個(gè)解決方案的源碼,但是就不上示例了,至于為什么,同學(xué)們往下看就知道了。另外,雖然這個(gè)方案歷史比較悠久,也很長(zhǎng)時(shí)間沒(méi)有人維護(hù)了,但是并不意味著不能使用了,只是使用條件比較苛刻,當(dāng)然,我司目前使用的還是這套方案(哈哈哈哈)。

不過(guò)這里我們不直接看 android-serialport-api 的源碼,而是通過(guò)其他大佬二次封裝的庫(kù)來(lái)看: Android-SerialPort-API

在這個(gè)庫(kù)中,通過(guò)

// 默認(rèn)直接初始化,使用8N1(8數(shù)據(jù)位、無(wú)校驗(yàn)位、1停止位),path為串口路徑(如 /dev/ttys1),baudrate 為波特率
SerialPort serialPort = new SerialPort(path, baudrate);


// 使用可選參數(shù)配置初始化,可配置數(shù)據(jù)位、校驗(yàn)位、停止位 - 7E2(7數(shù)據(jù)位、偶校驗(yàn)、2停止位)
SerialPort serialPort = SerialPort 
    .newBuilder(path, baudrate)
// 校驗(yàn)位;0:無(wú)校驗(yàn)位(NONE,默認(rèn));1:奇校驗(yàn)位(ODD);2:偶校驗(yàn)位(EVEN)
//    .parity(2) 
// 數(shù)據(jù)位,默認(rèn)8;可選值為5~8
//    .dataBits(7) 
// 停止位,默認(rèn)1;1:1位停止位;2:2位停止位
//    .stopBits(2) 
    .build();

初始化串口,然后通過(guò):

InputStream in = serialPort.getInputStream();
OutputStream out = serialPort.getOutputStream();

獲取到輸入/輸出流,通過(guò)讀取/寫(xiě)入這兩個(gè)流來(lái)實(shí)現(xiàn)與串口設(shè)備的數(shù)據(jù)通信。

我們首先來(lái)看看初始化串口是怎么做的。

圖片

首先檢查了當(dāng)前是否具有串口文件的讀寫(xiě)權(quán)限,如果沒(méi)有則通過(guò) shell 命令更改權(quán)限為 666 ,更改后再次檢查是否有權(quán)限,如果還是沒(méi)有就拋出異常。

注意這里的執(zhí)行 shell 時(shí)使用的 runtime 是 Runtime.getRuntime().exec(sSuPath); 也就是說(shuō),它是通過(guò) root 權(quán)限來(lái)執(zhí)行這段命令的!

換句話說(shuō),如果想要通過(guò)這種方式實(shí)現(xiàn)串口通信,必須要有 ROOT 權(quán)限!這就是我說(shuō)我不會(huì)給出示例的原因,因?yàn)槲沂诸^的設(shè)備無(wú)法 ROOT 啊。至于為啥我司還能繼續(xù)使用這種方案的原因也很簡(jiǎn)單,因?yàn)槲覀児た貦C(jī)的安卓設(shè)備都是定制版的啊,擁有 ROOT 權(quán)限不是基本操作?

確定權(quán)限可用后通過(guò) open 方法拿到一個(gè)類型為 FileDescriptor 的變量 mFd ,最后通過(guò)這個(gè) mFd 拿到輸入輸出流。

所以核心在于 open 方法,而 open 方法是一個(gè) native 方法,即 C 代碼:

private native FileDescriptor open(String absolutePath, int baudrate, int dataBits, int parity,
    int stopBits, int flags);

C 的源碼這里就不放了,只需要知道它做的工作就是打開(kāi)了 /dev/ttys 文件(準(zhǔn)確的說(shuō)是“終端”),然后通過(guò)傳遞進(jìn)去的這些參數(shù)去按串口規(guī)則解析數(shù)據(jù),最后返回一個(gè) javaFileDescriptor 對(duì)象。

在 java 中我們?cè)偻ㄟ^(guò)這個(gè) FileDescriptor 對(duì)象可以拿到輸入/輸出流。

原理說(shuō)起來(lái)是十分的簡(jiǎn)單。

看完通信部分的原理后,我們?cè)賮?lái)看看我們?nèi)绾尾檎铱捎玫拇谀兀?/p>

其實(shí)和 Linux 上也一樣:

public Vector<File> getDevices() {
    if (mDevices == null) {
        mDevices = new Vector<File>();
        File dev = new File("/dev");

        File[] files = dev.listFiles();


        if (files != null) {
            int i;
            for (i = 0; i < files.length; i++) {
                if (files[i].getAbsolutePath().startsWith(mDeviceRoot)) {
                    Log.d(TAG, "Found new device: " + files[i]);
                    mDevices.add(files[i]);
                }
            }
        }
    }
    return mDevices;
}

也是通過(guò)直接遍歷 /dev 下的文件,只不過(guò)這里做了一些額外的過(guò)濾。

或者也可以通過(guò)讀取 /proc/tty/drivers 配置文件后過(guò)濾:

Vector

關(guān)于讀取可用串口設(shè)備,其實(shí)從這里的路徑也可以看出,都是系統(tǒng)路徑,也就是說(shuō),如果沒(méi)有權(quán)限,大概率也是讀取不到東西的。

這就是使用與 Linux 一樣的方式去讀取串口數(shù)據(jù)的基本原理,那么問(wèn)題來(lái)了,既然我說(shuō)這個(gè)方法使用條件比較苛刻,那么更易用的替代方案是什么呢?

我們下面就會(huì)介紹,那就是使用安卓的 USB host (USB主機(jī))的功能。

USB host

Android 3.1(API 級(jí)別 12)或更高版本的平臺(tái)直接支持 USB 配件和主機(jī)模式。USB 配件模式還作為插件庫(kù)向后移植到 Android 2.3.4(API 級(jí)別 10)中,以支持更廣泛的設(shè)備。設(shè)備制造商可以選擇是否在設(shè)備的系統(tǒng)映像中添加該插件庫(kù)。

在安卓 3.1 版本開(kāi)始,支持將USB作為主機(jī)模式(USB host)使用,而我們?nèi)绻胍ㄟ^(guò) USB 讀取串口數(shù)據(jù)則需要依賴于這個(gè)主機(jī)模式。

在正式開(kāi)始介紹USB主機(jī)模式前,我們先簡(jiǎn)要介紹一下安卓上支持的USB模式。

安卓上的USB支持三種模式:設(shè)備模式、主機(jī)模式、配件模式。

設(shè)備模式即我們常用的直接將安卓設(shè)備連接至電腦上,此時(shí)電腦上顯示為 USB 外設(shè),即可以當(dāng)成 “U盤(pán)” 使用拷貝數(shù)據(jù),不過(guò)現(xiàn)在安卓普遍還支持 MTP模式(作為攝像頭)、文件傳輸模式(即當(dāng)U盤(pán)用)、網(wǎng)卡模式等。

主機(jī)模式即將我們的安卓設(shè)備作為主機(jī),連接其他外設(shè),此時(shí)安卓設(shè)備就相當(dāng)于上面設(shè)備模式中的電腦。此時(shí)安卓設(shè)備可以連接鍵盤(pán)、鼠標(biāo)、U盤(pán)以及嵌入式應(yīng)用USB轉(zhuǎn)串口、轉(zhuǎn)I2C等設(shè)備。但是如果想要將安卓設(shè)備作為主機(jī)模式可能需要一條支持 OTG 的數(shù)據(jù)線或轉(zhuǎn)接頭。(Micro-USB 或 USB type-c 轉(zhuǎn) USB-A 口)

而在 USB 配件模式下,外部 USB 硬件充當(dāng) USB 主機(jī)。配件示例可能包括機(jī)器人控制器、擴(kuò)展塢、診斷和音樂(lè)設(shè)備、自助服務(wù)終端、讀卡器等等。這樣,不具備主機(jī)功能的 Android 設(shè)備就能夠與 USB 硬件互動(dòng)。Android USB 配件必須設(shè)計(jì)為與 Android 設(shè)備兼容,并且必須遵守 Android 配件通信協(xié)議。

設(shè)備模式與配件模式的區(qū)別在于在配件模式下,除了 adb 之外,主機(jī)還可以看到其他 USB 功能。

圖片

使用USB主機(jī)模式與外設(shè)交互數(shù)據(jù)

在介紹完安卓中的三種USB模式后,下面我們開(kāi)始介紹如何使用USB主機(jī)模式。當(dāng)然,這里只是大概介紹原生APi的使用方法,我們?cè)趯?shí)際使用中一般都都是直接使用大佬編寫(xiě)的第三方庫(kù)。

準(zhǔn)備工作

在開(kāi)始正式使用USB主機(jī)模式時(shí)我們需要先做一些準(zhǔn)備工作。

首先我們需要在清單文件(AndroidManifest.xml)中添加:

name="android.hardware.usb.host" />






name="android.hardware.usb.action.USB_DEVICE_ATTACHED" /

一個(gè)完整的清單文件示例如下:

<manifest ...>
    <uses-feature android:name="android.hardware.usb.host" />
    <uses-sdk android:minSdkVersion="12" />
    ...
    <application>
        <activity ...>
            ...
            <intent-filter>
                <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
            <span class="hljs-name"intent-filter>
        <span class="hljs-name"activity>
    <span class="hljs-name"application>
<span class="hljs-name"manifest>

聲明好清單文件后,我們就可以查找當(dāng)前可用的設(shè)備信息了:

private fun scanDevice(context: Context) {
    val manager = context.getSystemService(Context.USB_SERVICE) as UsbManager
    val deviceList: HashMap

將 ESP32 開(kāi)發(fā)版插上手機(jī),運(yùn)行程序,輸出如下:

圖片

可以看到,正確的查找到了我們的 ESP32 開(kāi)發(fā)版。

這里提一下,因?yàn)槲覀兊氖謾C(jī)只有一個(gè) USB 口,此時(shí)已經(jīng)插上了 ESP32 開(kāi)發(fā)版,所以無(wú)法再通過(guò)數(shù)據(jù)線直接連接電腦的 ADB 了,此時(shí)我們需要使用無(wú)線 ADB,具體怎么使用無(wú)線 ADB,請(qǐng)自行搜索。

另外,如果我們想要通過(guò)查找到設(shè)備后請(qǐng)求連接的方式連接到串口設(shè)備的話,還需要額外申請(qǐng)權(quán)限。(同理,如果我們直接在清單文件中提前聲明需要連接的設(shè)備則不需要額外申請(qǐng)權(quán)限,具體可以看看參考資料5,這里不再贅述)

首先聲明一個(gè)廣播接收器,用于接收授權(quán)結(jié)果:

private lateinit var permissionIntent: PendingIntent


private const val ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION"


private val usbReceiver = object : BroadcastReceiver() {


    override fun onReceive(context: Context, intent: Intent) {
        if (ACTION_USB_PERMISSION == intent.action) {
            synchronized(this) {
                val device: UsbDevice? = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE)


                if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                    device?.apply {
                      // 已授權(quán),可以在這里開(kāi)始請(qǐng)求連接
                        connectDevice(context, device)
                    }
                } else {
                    Log.d(TAG, "permission denied for device $device")
                }
            }
        }
    }
}

聲明好之后在 Acticity 的 OnCreate 中注冊(cè)這個(gè)廣播接收器:

permissionIntent = PendingIntent.getBroadcast(this, 0, Intent(ACTION_USB_PERMISSION), FLAG_MUTABLE)
val filter = IntentFilter(ACTION_USB_PERMISSION)
registerReceiver(usbReceiver, filter)

最后,在查找到設(shè)備后,調(diào)用 manager.requestPermission(deviceList.values.first(), permissionIntent) 彈出對(duì)話框申請(qǐng)權(quán)限。

連接到設(shè)備并收發(fā)數(shù)據(jù)

完成上述的準(zhǔn)備工作后,我們終于可以連接搜索到的設(shè)備并進(jìn)行數(shù)據(jù)交互了:

private fun connectDevice(context: Context, device: UsbDevice) {
    val usbManager = context.getSystemService(Context.USB_SERVICE) as UsbManager


    CoroutineScope(Dispatchers.IO).launch {
        device.getInterface(0).also { intf ->
            intf.getEndpoint(0).also { endpoint ->
                usbManager.openDevice(device)?.apply {
                    claimInterface(intf, forceClaim)
                    while (true) {
                        val validLength = bulkTransfer(endpoint, bytes, bytes.size, TIMEOUT)
                        if (validLength > 0) {
                            val result = bytes.copyOfRange(0, validLength)
                            Log.i(TAG, "connectDevice: length = $validLength")
                            Log.i(TAG, "connectDevice: byte = ${result.contentToString()}")
                        }
                        else {
                            Log.i(TAG, "connectDevice: Not recv data!")
                        }
                    }
                }
            }
        }
    }
}

在上面的代碼中,我們使用 usbManager.openDevice 打開(kāi)了指定的設(shè)備,即連接到設(shè)備。

然后通過(guò) bulkTransfer 接收數(shù)據(jù),它會(huì)將接收到的數(shù)據(jù)寫(xiě)入緩沖數(shù)組 bytes 中,并返回成功接收到的數(shù)據(jù)長(zhǎng)度。

運(yùn)行程序,連接設(shè)備,日志打印如下:

圖片

可以看到,輸出的數(shù)據(jù)并不是我們預(yù)料中的數(shù)據(jù)。

這是因?yàn)檫@是非常原始的數(shù)據(jù),如果我們想要讀取數(shù)據(jù),還需要針對(duì)不同的串口轉(zhuǎn)USB芯片或協(xié)議編寫(xiě)驅(qū)動(dòng)程序才能獲取到正確的數(shù)據(jù)。

順道一提,如果想要將數(shù)據(jù)寫(xiě)入串口數(shù)據(jù)的話可以使用 controlTransfer()

所以,我們?cè)趯?shí)際生產(chǎn)環(huán)境中使用的都是基于此封裝好的第三方庫(kù)。

這里推薦使用 usb-serial-for-android

usb-serial-for-android

使用這個(gè)庫(kù)的第一步當(dāng)然是導(dǎo)入依賴:

// 添加倉(cāng)庫(kù)
allprojects {
    repositories {
        ...
        maven { url 'https://jitpack.io' }
    }
}
// 添加依賴
dependencies {
    implementation 'com.github.mik3y:usb-serial-for-android:3.4.6'
}

添加完依賴同樣需要在清單文件中添加相應(yīng)字段以及處理權(quán)限,因?yàn)楹蜕鲜鍪褂迷鶤PI一致,所以這里不再贅述。

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • plc
    plc
    +關(guān)注

    關(guān)注

    5011

    文章

    13297

    瀏覽量

    463376
  • 串口通信
    +關(guān)注

    關(guān)注

    34

    文章

    1626

    瀏覽量

    55529
  • 安卓
    +關(guān)注

    關(guān)注

    5

    文章

    2130

    瀏覽量

    57203
  • ESP32
    +關(guān)注

    關(guān)注

    18

    文章

    971

    瀏覽量

    17276
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    STM32的USART串口通信實(shí)踐

    STM32的USART串口通信實(shí)踐
    發(fā)表于 08-16 07:20

    Matlab的串口通信實(shí)現(xiàn)

    第9章 Matlab的串口通信實(shí)現(xiàn)本章節(jié)主要為大家講解Matlab的串口方式波形數(shù)據(jù)傳輸和后期數(shù)據(jù)分析功能,非常實(shí)用。目錄第9章 Matlab的串口
    發(fā)表于 08-17 06:48

    串口通信實(shí)驗(yàn)分享

    實(shí)驗(yàn)四、串口通信實(shí)驗(yàn)? 自律學(xué)習(xí)堅(jiān)強(qiáng) ,拒絕迷茫。作者:行走的皮卡丘時(shí)間:2021/4/4喜歡就去追,這個(gè)紅燈等不到,說(shuō)不定下一個(gè)紅燈等到了,嘻嘻?。。。。。?!文章目錄實(shí)驗(yàn)四、串口通信實(shí)
    發(fā)表于 01-14 09:08

    與ESP8266串口WIFI模塊的通信實(shí)現(xiàn)相關(guān)資料推薦

    Button分別對(duì)應(yīng)相應(yīng)的功能鍵。通信實(shí)現(xiàn)原理使用基于tcp協(xié)議的socket通信。串口WiFi模塊配置成tcp Service模式,然后
    發(fā)表于 01-18 08:34

    STM32 USART串口通信實(shí)踐

    STM32串口通訊USART串口通信實(shí)踐USART串口通信實(shí)踐1、實(shí)驗(yàn)環(huán)境參考資料 野火官方的
    發(fā)表于 02-10 07:06

    基于串口的LABVIEW與PLC的通信實(shí)現(xiàn)

    基于串口的LABVIEW與PLC的通信實(shí)現(xiàn):介紹使用ADAM5000的通信協(xié)議實(shí)現(xiàn)LABVIEW與ADAM5510通信。
    發(fā)表于 09-19 07:55 ?62次下載

    串口通信實(shí)例教程

    串口通信實(shí)例教程,感興趣的可以看看。
    發(fā)表于 06-23 17:56 ?0次下載

    STM32 串口通信實(shí)驗(yàn)

    USB轉(zhuǎn)RS485線在F103環(huán)境下進(jìn)行UART通信實(shí)驗(yàn)和RS232通信實(shí)驗(yàn)在F407環(huán)境下進(jìn)行RS485實(shí)驗(yàn)(1.我的103板子沒(méi)有485口,2.正好看下開(kāi)發(fā)板環(huán)境不同的差異)UART
    發(fā)表于 12-20 19:26 ?15次下載
    STM32 <b class='flag-5'>串口</b><b class='flag-5'>通信實(shí)</b>驗(yàn)

    STM32下的USART串口通信程序

    STM32的USART串口通信實(shí)踐
    發(fā)表于 12-24 18:42 ?13次下載
    STM32下的USART<b class='flag-5'>串口</b><b class='flag-5'>通信</b>程序

    實(shí)驗(yàn)四、串口通信實(shí)驗(yàn)

    堅(jiān)強(qiáng) ,拒絕迷茫。作者:行走的皮卡丘時(shí)間:2021/4/4喜歡就去追,這個(gè)紅燈等不到,說(shuō)不定下一個(gè)紅燈等到了,嘻嘻?。。。。。?!文章目錄實(shí)驗(yàn)四、串口通信實(shí)驗(yàn)一、 實(shí)驗(yàn)?zāi)康亩?實(shí)驗(yàn)設(shè)備三、 實(shí)驗(yàn)原理3.1、狀態(tài)寄存器USART_SR及函數(shù)3.2、USATR
    發(fā)表于 01-14 10:09 ?2次下載
    實(shí)驗(yàn)四、<b class='flag-5'>串口</b><b class='flag-5'>通信實(shí)</b>驗(yàn)

    串口通信實(shí)驗(yàn)

    串口通信實(shí)驗(yàn)串口通信實(shí)驗(yàn)代碼圖像串口通信實(shí)驗(yàn)晶振12MHz,波特率1200, 程序啟動(dòng)后單片機(jī)主
    發(fā)表于 01-14 10:12 ?6次下載
    <b class='flag-5'>串口</b><b class='flag-5'>通信實(shí)</b>驗(yàn)

    串口通信入門(mén)之modbus(上)

    在之前的兩篇文章中,我們講解串口的基礎(chǔ)知識(shí)和在中使用串口通信的方法,如果還沒(méi)看過(guò)之前文章的
    的頭像 發(fā)表于 04-23 17:40 ?1928次閱讀
    <b class='flag-5'>安</b><b class='flag-5'>卓</b>與<b class='flag-5'>串口</b><b class='flag-5'>通信</b>入門(mén)之modbus(上)

    串口通信入門(mén)之modbus(下)

    在之前的兩篇文章中,我們講解串口的基礎(chǔ)知識(shí)和在中使用串口通信的方法,如果還沒(méi)看過(guò)之前文章的
    的頭像 發(fā)表于 04-23 17:40 ?5024次閱讀
    <b class='flag-5'>安</b><b class='flag-5'>卓</b>與<b class='flag-5'>串口</b><b class='flag-5'>通信</b>入門(mén)之modbus(下)

    串口通信實(shí)踐講解2

    這篇文章我們將講解串口通信實(shí)踐,即如何使用串口
    的頭像 發(fā)表于 04-23 17:59 ?1700次閱讀
    <b class='flag-5'>安</b><b class='flag-5'>卓</b><b class='flag-5'>端</b>的<b class='flag-5'>串口</b><b class='flag-5'>通信實(shí)踐</b><b class='flag-5'>講解</b>2

    串口通信實(shí)驗(yàn)資料分享

    串口通信實(shí)驗(yàn)資料分享
    發(fā)表于 06-29 15:03 ?5次下載