完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
一、背景简介:
CH376是一款USB接口芯片,可以使用SPI接口或串口或并口扩展一个通用USB接口出来。 二、芯片特点: 1.该芯片内置了一个文件管理系统,可以方便操作FAT12、FAT16、FAT32文件系统的存储设备、比如大部分的U盘和SD卡。 2.提供了SPI、串口、并口等常用接口,方便大部分情况下的使用。 3.提供了USB接口和SPI主机口,可以操作U盘或者SD卡。 三、电路设计: 在进行电路设计之前需要确定两件事,芯片的供电电压、芯片使用的接口。供电不同、接口不同电路就不同。 1.供电,VCC=5V供电时,V3引脚需要连接一个0.01uF的电容接到GND。 VCC=3.3V供电时,V3引脚要和VCC引脚连接在一起。 2.接口,芯片的接口选择是根据上电时WR#、RD#、PCS#、A0、RXT、TXD的引脚状态决定。 3.USB接口,USB接口部分需要连接一个大点的电容(几十uF)接到GND。 4.晶振部分,在XI引脚内部内置了一个电容,所以只需要在XO引脚添加电容即可。 四、程序设计: 官方有提供很多基于51单片机的例程,包括U盘,做各种常用设备和主机的参考代码,可以在提供的例程基础上做一个移植。参考例程大都是基于这四个函数使用的,xWriteCH376Cmd(),xWriteCH376Data(),xReadCH376Data(),Query376Interrupt( ),所以只要把自己的硬件接口与这些函数对应即可。 1.接口函数调试方法: 接口函数调试的核心思想就是,将输出的波形调成满足手册需求的波形。 测试的方式也很简单,CH376有一个取反命令,可以将输入的数据按位取反再返回,如果返回的数据正确取反,那么就可以确认接口三个接口函数是正确的(无法测试中断函数是否正确)。 2.接口函数举例:使用STM32单片机IO口模拟SPI接口,控制CH376。 /*======CH376T IO定义======*/ #define CH376T_SDI_HIGH GPIO_SetBits(GPIOB, GPIO_Pin_15) //CH376T SDI #define CH376T_SDI_LOW GPIO_ResetBits(GPIOB, GPIO_Pin_15) #define CH376T_SDO_HIGH GPIO_SetBits(GPIOB, GPIO_Pin_14) //CH376T SDO #define CH376T_SDO_LOW GPIO_ResetBits(GPIOB, GPIO_Pin_14) #define CH376T_SCK_HIGH GPIO_SetBits(GPIOB, GPIO_Pin_13) //CH376T 时钟SCK #define CH376T_SCK_LOW GPIO_ResetBits(GPIOB, GPIO_Pin_13) #define CH376T_CS_HIGH GPIO_SetBits(GPIOB, GPIO_Pin_12) //CH376T 片选CS #define CH376T_CS_LOW GPIO_ResetBits(GPIOB, GPIO_Pin_12) #define CH376T_RST_HIGH GPIO_SetBits(GPIOB, GPIO_Pin_11) //CH376T 复位RST #define CH376T_RST_LOW GPIO_ResetBits(GPIOB, GPIO_Pin_11) #define CH376_INT_WIRE GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_10) //中断 INT /************************************************************************************************** ** 函数名称: Spi376OutByte ** 功能描述: 模拟SPI输出8位数据 ** 输 入: d-SPI发送的数据 ** 输 出: 无 *******************************************************************************************************/ void Spi376OutByte( UINT8 d ) { UINT8 i; for ( i = 0; i < 8; i ++ ) { CH376T_SCK_LOW; //CH376_SPI_SCK = 0; if ( d & 0x80 ) { CH376T_SDI_HIGH; //CH376_SPI_SDI = 1; } else CH376T_SDI_LOW; //CH376_SPI_SDI = 0; d <<= 1; /* 数据位是高位在前 */ CH376T_SCK_HIGH; //CH376_SPI_SCK = 1; /* CH376在时钟上升沿采样输入 */ } } /************************************************************************************************** ** 函数名称: Spi376InByte ** 功能描述: 模拟SPI输入8位数据 ** 输 入: 无 ** 输 出: SPI接收的数据 *******************************************************************************************************/ UINT8 Spi376InByte( void ) { UINT8 i, d; d = 0; for ( i = 0; i < 8; i ++ ) { CH376T_SCK_LOW; //CH376_SPI_SCK = 0; /* CH376在时钟下降沿输出 */ d <<= 1; /* 数据位是高位在前 */ if ( GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14) ) d ++; CH376T_SCK_HIGH; //CH376_SPI_SCK = 1; } return( d ); } /* SPI片选无效,结束CH376命令,仅用于SPI接口方式 */ void xEndCH376Cmd( void ) { CH376T_CS_HIGH; } /************************************************************************************************** ** 函数名称: xWriteCH376Cmd ** 功能描述: 向CH376写命令操作 ** 输 入: mCmd-发送的命令 ** 输 出: 无 *******************************************************************************************************/ void xWriteCH376Cmd( UINT8 mCmd ) /* */ { mDelay0_5uS( ); CH376T_CS_LOW; //CH376_SPI_SCS = 0; /* SPI片选有效 */ Spi376OutByte( mCmd ); /* 发出命令码 */ mDelay0_5uS( ); mDelay0_5uS( ); mDelay0_5uS( ); /* 延时1.5uS确保读写周期大于1.5uS,或者用上面一行的状态查询代替 */ } /************************************************************************************************** ** 函数名称: xWriteCH376Data ** 功能描述: 向CH376写数据操作 ** 输 入: mData-发送的数据 ** 输 出: 无 *******************************************************************************************************/ void xWriteCH376Data( UINT8 mData ) /* 向CH376写数据 */ { Spi376OutByte( mData ); mDelay0_5uS( ); /* 确保读写周期大于0.6uS */ } /************************************************************************************************** ** 函数名称: xReadCH376Data ** 功能描述: 读取CH376的数据 ** 输 入: 无 ** 输 出: CH376返回的数据 *******************************************************************************************************/ UINT8 xReadCH376Data( void ) /* 从CH376读数据 */ { UINT8 s; mDelay0_5uS( ); /* 确保读写周期大于0.6uS */ CH376T_CS_LOW; s = Spi376InByte(); mDelay0_5uS(); return( s ); } /* 查询CH376中断(INT#低电平) */ UINT8 Query376Interrupt( void ) { #ifdef CH376_INT_WIRE return( CH376_INT_WIRE ? FALSE : TRUE ); /* 如果连接了CH376的中断引脚则直接查询中断引脚 */ #else return( CH376_SPI_SDO ? FALSE : TRUE ); /* 如果未连接CH376的中断引脚则查询兼做中断输出的SDO引脚状态 */ #endif } |
|
|
|
只有小组成员才能发言,加入小组>>
3334 浏览 9 评论
3013 浏览 16 评论
3506 浏览 1 评论
9092 浏览 16 评论
4105 浏览 18 评论
1214浏览 3评论
628浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
615浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2358浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1920浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-1-8 21:51 , Processed in 1.081338 second(s), Total 47, Slave 38 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号