Arduino 上使用 CH376-Arduino中文社区 - Powered by Discuz!

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 2592|回复: 0

Arduino 上使用 CH376

[复制链接]
发表于 2020-4-14 19:53 | 显示全部楼层 |阅读模式
本帖最后由 Zoologist 于 2020-4-17 21:03 编辑

CH37X 系列是南京沁恒出品的一系列USB控制类的芯片,主要用途是用作 USBHost 实现 USB 设备的控制。具体列表如下【参考1】:                              
image001.png

上面不同型号主要差别在于提供的接口,目前支持三种对单片机的接口,分别是并口 SPI和串口。此外就是是否硬件集成文件系统。如果集成了,那么可以通过简单的命令来实现文件系统级别的操作,否则需要主控芯片自己来实现,这对于主控的内存要求比较高,整体程序也会复杂得多。
从上面可以看到,CH378是当前最强的,但是因为封装更加负责以及比较新的原因(缺少资料),所以市面上最常见的还是 CH376,淘宝上的价格在20以内,应该也是比较容易接受的。这次试验就是基于 CH376 模块,特别注意是下面这种带有一个2X3跳线的:
image002.png


这款电路图如下:
image003.png


这个模块默认情况下使用串口通讯,跳线顺序如下:
P_S GNDTXD(CH376) TXD
    S RXD  GND  TXD
这个跳线决定初始时串口通讯速度,意思是如果能够通讯,那么可以通过修改寄存器的方式修改波特率从而实现更高的速度。
image004.png

  跳线指南【参考2】
这次试验就是如何进行串口通讯 P_S 位置跳线是 TXD(CH376) TXD 短路。试验使用的是Arduino Leonardo,因为他带有一个额外的硬件串口(软件串口通常在 115200波特率下接收会有问题)。接线如下:
  
Arduino Leonardo
  
CH376模块
5V
VCC
GND
GND
Pin0 RX
TXD
Pin1 TX
RXD

测试代码是 basicUsageHwSerial
[mw_shl_code=arduino,true]/*------------------------------------------------------------------------------------------------------------------

*    Author: György Kovács                                                                                         |

*    Created: 28 Mar 2019                                                                                          |

*    Description: Basic usage of CH376 with hardware serial                                                        |

*    Thanks for the idea to Scott C , https://arduinobasics.blogspot.c ... adwrite-module.html  |

*------------------------------------------------------------------------------------------------------------------

*/





#include <Ch376msc.h>



//..............................................................................................................................

// Leave the default jumper settings for the baud rate (9600) on the CH376, the library will set it up the chosen speed(HW serial only)

Ch376msc flashDrive(Serial1, 115200); // Ch376 object with hardware Serial1 on arduino mega baudrate: 9600, 19200, 57600, 115200

//..............................................................................................................................

// buffer for reading

char adatBuffer[255];// max length 255 = 254 char + 1 NULL character

//..............................................................................................................................

// strings for writing to file

char adat[]="Vivamus nec nisl molestie, blandit diam vel, varius mi. Fusce luctus cursus sapien in vulputate.\n";

char adat2[] = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis efficitur ac est eu pharetra. \n";

//..............................................................................................................................

unsigned long totSect = 0;

unsigned long freeSect = 0;

byte percentg = 0;

byte tmpCommand; //used to store data coming from serial port

boolean readMore;

static char helpString[]= {"hrint this help\n\n1:Create\n2:Append\n3:Read\n4:Read date/time\n"

            "5:Modify date/time\n6elete\n7ist dir\n8rint free space"

            "\n9:Open/Create folder(s)/subfolder(s)"};



void setup() {

  Serial.begin(115200);

  flashDrive.init();

  printInfo(helpString);

}



void loop() {

               if(flashDrive.checkIntMessage()){

                              if(flashDrive.getDeviceStatus()){

                                             Serial.println(F("Flash drive attached!"));

                              } else {

                                             Serial.println(F("Flash drive detached!"));

                              }

               }

  if(Serial.available()){

    tmpCommand = Serial.read();                      //read incoming bytes from the serial monitor

    if(((tmpCommand > 48)&&(tmpCommand < 58)) && !flashDrive.driveReady()){ // if the data is ASCII 1 - 9 and no flash drive are attached

       printInfo("Attach flash drive first!");

      tmpCommand = 10; // change the command byte

    }

     switch (tmpCommand) {



      case 49: //1

        printInfo("COMMAND1: Create and write data to file : TEST1.TXT");    // Create a file called TEST1.TXT

          flashDrive.setFileName("TEST1.TXT");  //set the file name

          flashDrive.openFile();                //open the file



          for(int a = 0; a < 20; a++){          //write text from string(adat) to flash drive 20 times

            flashDrive.writeFile(adat, strlen(adat)); //string, string length

          }

          flashDrive.closeFile();               //at the end, close the file

        printInfo("Done!");

        break;

//*****************************************************************************************************************************************************

      case 50: //2

        printInfo("COMMAND2: Append data to file: TEST1.TXT");               // Append data to the end of the file.

        flashDrive.setFileName("TEST1.TXT");  //set the file name

        if(flashDrive.openFile() == ANSW_USB_INT_SUCCESS){               //open the file

               flashDrive.moveCursor(CURSOREND);     //if the file exist, move the "virtual" cursor at end of the file, with CURSORBEGIN we actually rewrite our old file

               //flashDrive.moveCursor(flashDrive.getFileSize()); // is almost the same as CURSOREND, because we put our cursor at end of the file

        }

        for(int a = 0; a < 20; a++){          //write text from string(adat) to flash drive 20 times

               if(flashDrive.getFreeSectors()){ //check the free space on the drive

                              flashDrive.writeFile(adat2, strlen(adat2)); //string, string length

               } else {

                              printInfo("Disk full");

               }

        }

        flashDrive.closeFile();               //at the end, close the file

        printInfo("Done!");

        break;

//*****************************************************************************************************************************************************

      case 51: //3

        printInfo("COMMAND3: Read File: TEST1.TXT");                         // Read the contents of this file on the USB disk, and display contents in the Serial Monitor

        flashDrive.setFileName("TEST1.TXT");  //set the file name

        flashDrive.openFile();                //open the file

        readMore = true;

                //read data from flash drive until we reach EOF

        while(readMore){ // our temporary buffer where we read data from flash drive and the size of that buffer

               readMore = flashDrive.readFile(adatBuffer, sizeof(adatBuffer));

               Serial.print(adatBuffer);          //print the contents of the temporary buffer

        }

        flashDrive.closeFile();               //at the end, close the file

        printInfo("Done!");

        break;

//*****************************************************************************************************************************************************

      case 52: //4

        printInfo("COMMAND4: Read File date/time: TEST1.TXT");      // Read the date and time of file, default 2004.01.01 - 00:00:00

        flashDrive.setFileName("TEST1.TXT");            //set the file name

        flashDrive.openFile();                          //open the file

                //print informations about the file

          Serial.println(flashDrive.getFileName());

          Serial.print(flashDrive.getYear());

          Serial.print("y\t");

          Serial.print(flashDrive.getMonth());

          Serial.print("m\t");

          Serial.print(flashDrive.getDay());

          Serial.print("d\t");

          Serial.print(flashDrive.getHour());

          Serial.print("h\t");

          Serial.print(flashDrive.getMinute());

          Serial.print("m\t");

          Serial.print(flashDrive.getSecond());

          Serial.println('s');

        flashDrive.closeFile();                         //at the end, close the file

        printInfo("Done!");

        break;

//*****************************************************************************************************************************************************

      case 53: //5

        printInfo("COMMAND5: Modify File date/time: TEST1.TXT");    // Modify the file date/time and save

        flashDrive.setFileName("TEST1.TXT");  //set the file name

        flashDrive.openFile();                //open the file



          flashDrive.setYear(2019);

          flashDrive.setMonth(12);

          flashDrive.setDay(19);

          flashDrive.setHour(03);

          flashDrive.setMinute(38);

          flashDrive.setSecond(42);



          flashDrive.saveFileAttrb();           //save the changed data

        flashDrive.closeFile();               //and yes again, close the file after when you don`t use it

        printInfo("Done!");

        break;

//*****************************************************************************************************************************************************

      case 54: //6

        printInfo("COMMAND6: Delete File: TEST1.TXT");                       // Delete the file named TEST1.TXT

        flashDrive.setFileName("TEST1.TXT");  //set the file name

        flashDrive.deleteFile();              //delete file

        printInfo("Done!");

        break;

//*****************************************************************************************************************************************************

      case 55: //7

        printInfo("COMMAND7: List directory");                          //Print all file names in the current directory

          while(flashDrive.listDir()){ // reading next file

            if(flashDrive.getFileAttrb() == ATTR_DIRECTORY){//directory

              Serial.print('/');

              Serial.println(flashDrive.getFileName()); // get the actual file name

            } else {

              Serial.print(flashDrive.getFileName()); // get the actual file name

              Serial.print(" : ");

              Serial.print(flashDrive.getFileSize()); // get the actual file size in bytes

              Serial.print(" >>>\t");

              Serial.println(flashDrive.getFileSizeStr()); // get the actual file size in formatted string

            }

          }

          printInfo("Done!");

        break;

//*****************************************************************************************************************************************************

      case 56: //8

                 totSect = flashDrive.getTotalSectors(); // get the total sector number

                 freeSect = flashDrive.getFreeSectors(); // get the available sector number

                 percentg = map(freeSect,totSect,0,0,100);                         // convert it to percentage (0-100)

                 Serial.print("Disk size in bytes: ");

                 /*if the sector number is more than 8388607 (8388607 * 512 = 4294966784 byte = 4Gb (fits in a 32bit variable) )

                                                                                                                         e.g. 8388608 * 512 = 4294967296 byte (32bit variable overflows) */

                 if(totSect > 8388607){

                                Serial.print(">4Gb");

                 } else {

                 Serial.print(totSect * SECTORSIZE);

                 }

                 Serial.print("\tFree space in bytes: ");

                 if(freeSect > 8388607){

                                Serial.print(">4Gb");

                 } else {

                 Serial.print(freeSect * SECTORSIZE);

                 }

                 Serial.print(F("\tDisk usage :"));

                 Serial.print(percentg);

                 Serial.print(F("%"));

                 switch (flashDrive.getFileSystem()) { //1-FAT12, 2-FAT16, 3-FAT32

                                             case 1:

                                                            Serial.println(F("\tFAT12 partition"));

                                                            break;

                                             case 2:

                                                            Serial.println(F("\tFAT16 partition"));

                                                            break;

                                             case 3:

                                                            Serial.println(F("\tFAT32 partition"));

                                                            break;

                                             default:

                                                            Serial.println(F("\tNo valid partition"));

                                                            break;

                              }

                break;

//*****************************************************************************************************************************************************

      case 57: //9

        switch(flashDrive.cd("/DIR1/DIR2/DIR3",1)){

          case ERR_LONGFILENAME: //0x01

            Serial.println(F("Directory name is too long"));

          break;



          case ANSW_USB_INT_SUCCESS: //0x14

          Serial.println(F("Directory created successfully"));

          break;



          case ANSW_ERR_OPEN_DIR: //0x41

          Serial.println(F("Directory opened successfully"));

          break;



          case ANSW_ERR_MISS_FILE: //0x42

          Serial.println(F("Directory doesn't exist"));

          break;



          case ANSW_ERR_FOUND_NAME: //0x43

          Serial.println(F("File exist with the given name"));

          break;



          default:



          break;

        }

      break;

//*****************************************************************************************************************************************************

      case 104: //h

                 printInfo(helpString);

        break;

      default:

        break;

    }//end switch



  }//endif serial available



}//end loop



//Print information

void printInfo(char info[]){

  char * infoPtr = info;

  int infoLength = 0;

    while(*infoPtr){

      infoPtr++;

      infoLength++;

      if(infoLength > 40) break;

    }

    Serial.print(F("\n\n"));

    for(int a = 0; a < infoLength; a++){

      Serial.print('*');

    }

   Serial.println();

   Serial.println(info);

   for(int a = 0; a < infoLength; a++){

      Serial.print('*');

    }

   Serial.print(F("\n\n"));

}[/mw_shl_code]
运行结果:

插拔U盘有提示,输入 h 显示菜单,可以进行一些功能测试

image005.png


最后吐槽一下:CH37X  系列推出十多年了,很多年前我也入手过,但是不得不说这货太难用了,官网提供的资料看起来很全,但上手之后会发现缺少核心部分。现在能用是因为南京沁恒后来公布了一些具体COMMAND (之前应该只有大客户才能拿到),这样玩家才有机会应用在 Arduino 上。相比之下,国外的芯片资料一直都很全。这也是为什么很多产品在第一版设计时不会考虑国产方案的原因。希望未来国产芯片在这方面能有所改观。

参考:

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2024-11-28 11:49 , Processed in 0.076964 second(s), 18 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表