>

CH341T GPIO实验

2017-04-17 by Stavros

沁恒的CH341A是个多功能的USB总线转发器. 淘宝搜CH341A会搜出一大堆用它做的EEPROM/FLASH编程器, 而它的实际功能还要强大得多, 可以从USB提供异步串口、打印口、EPP/MEM并口、I2C、SPI等接口. 此外CH341A在EPP/MEM并口状态下还可以用沁恒提供的API直接操作引脚, 除了8位并口的8个脚以外, 若干状态引脚也能操作, 总共可以得到16个左右的GPIO. (其中有个别引脚只能输入或者只能输出. )

这东西的主要缺点就是封装是SOP28宽体, 体积实在大了点. 它的两个小兄弟, CH341T和CH341H都是SSOP20封装, 苗条了很多, 前者只提供异步串口和I2C, 后者只提供SPI.

CH341A配置不同功能是靠SDA的不同接法实现的, SDA/SCL悬空时连接PC会识别成异步串口, SDA拉低会识别成转EPP/MEM并口和I2C/SPI串口, SDA和SCL短接会识别成USB打印机. CH341T也提供了SDA和SCL引脚, 如果SDA接地, 能不能也把它的若干状态引脚当GPIO用呢?

做了块小板, 实际测试, 果然可以! PC直接把它识别成了CH341A.

接下来要实测哪些引脚可以使用. 这里要吐槽一下沁恒的API, 只提供了ch341dll.h, ch341dll.dll和ch341dll.lib; 试了各种办法想把ch341dll.lib转成mingw环境下的.a或者.o, 均失败. 没想到直接gcc ch341dll.dll main.o -o main.exe, 居然成功了.

先试验输入状态, 程序如下:

#include <stdio.h> 
#include <stdlib.h> 
#include <windows.h>
#include "ch341dll.h"

int main(void)
{
    HANDLE hdlCh341;

    hdlCh341 = CH341OpenDeviceEx(0);
    printf("%lu\n", (unsigned long)hdlCh341);
    printf("%lu\n", CH341GetVersion());
    CH341ResetDevice(0);

    CH341SetOutput(0, 0xffffffff, 0x00000000, 0x00000000); 
    while(1) { 
        unsigned long status;
        CH341GetInput(0, &status);
        printf("%08lx\n", status);
        sleep(1);
    }

    return 0;
}

运行, 屏幕上不断输出0000efff.

之后用杜邦线把模块的各个引脚逐个与地短接, 观察屏幕上的输出.

短接5脚INT#/4脚RXD/3脚TXD/2脚ROV#/19脚TEN#/14脚SLP#到地时, 屏幕上的输出分别变为0000ebff, 0000edff, 0000eeff, 0000afff, 0000cfff, 0000ef7f. 说明这6个脚可以作为输入脚使用.

再试验输出状态, 程序如下:

#include <stdio.h> 
#include <stdlib.h> 
#include <windows.h>
#include "ch341dll.h"

int main(void)
{
    HANDLE hdlCh341;

    hdlCh341 = CH341OpenDeviceEx(0);
    printf("%lu\n", (unsigned long)hdlCh341);
    printf("%lu\n", CH341GetVersion());
    CH341ResetDevice(0);

    CH341SetOutput(0, 0xffffffff, 0xffffffff, 0x00000000); 
    while(1) { 
        CH341SetOutput(0, 0b11111, 0xffffffff, 0xffffffff); 
        CH341SetOutput(0, 0b11111, 0xffffffff, 0x0);     } 
    return 0;
}

之后用示波器观察各个引脚的波形, 结果发现除了上面的6个脚以外, 18脚TNOW/17脚RDY#/16脚SCL/15脚SDA也都有方波输出. 可见除了ACT#之外的10个脚都可以作为输出脚使用. 就是方波频率低了点, 只有1kHz左右.

这么看来CH341T的潜力还挺大, 6个脚输入输出两用, 另外4个只输出, 足够实现很多功能了. 速度慢点, 做点简单的控制是没有问题的.

更新: 今天想到, 可能某些管脚其实是没有内部上拉, 所以作为输入时拉到地没反应? 于是再在输入状态下把18~15这四个管脚分别上拉, 果然当SDA上拉时屏幕上的输出变成了0080efff. 可见SDA也能作为输入使用. 所以应该是7个双向GPIO, 3个只能输出.