1
完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
该项目通过STM32芯片的IO口模拟SPI接口操作CH376芯片完成对U盘的读写操作。
CH376芯片内置了文件管理系统,可以通过简洁的命令操作U盘,完成读写文件等各种常规的U盘操作,用户不需要考虑FAT文件系统的底层知识,只需要使用基本的命令就行。官方提供了大量的函数,如果只是对U盘进行基本的操作的话,可以直接使用各种函数,不需要详细解读手册。 一、硬件准备: STM32F103:作为一个主控芯片使用。 CH376:接口芯片,用来控制U盘完成文件读写操作。 CH340:监控鼠标的传输过程。 若干杜邦线,以及U盘等等基本 三、code 1.进入官网,下载好EVT压缩包并且解压。 文件从上到下依次是: .EXAM:操作U盘的各种例程。 .CH376DBG.EXE:上位机的串口操作CH376的软件,可以通过串口调试工具,通过该软件读写文件。可以用来检查使用CH376串口接口时的硬件是否完整。 .CH376EVT.PDF:CH376资料的一个说明。包括对EXAM里面资料的一个简要说明。 .CH376SCH.PDF:CH376评估板的一个原理图。 .CH376编程指南.PDF:讲解如何移植代码等等。 2.找一个STM32的基本工程,随便一个都可以。 如下图,这里我们找一个UART的例程。创建好CH376的文件夹,将相应的文件放进去。 为什么是上面这些文件,是因为在后面移植代码时,发现都需要包含这些文件。例如打开一个EXAM7例程的参考文件“CH376HFT.C”。发现这个例程中会包含这些文件。 /* C51 CH376HFT.C */ /* LX51 CH376HFT.OBJ */ /* OHX51 CH376HFT */ #include #include #include #include "..HAL.H" #include "..HAL_BASE.C" #include "..DEBUG.H" #include "..DEBUG.C" #include "..PARA_HW.C" /* 硬件总线并口连接方式 */ //#include "..PARA_SW.C" /* 软件模拟并口连接方式 */ //#include "..SPI_HW.C" /* 硬件SPI连接方式 */ //#include "..SPI_SW.C" /* 软件模拟SPI方式 */ //#include "..UART_HW.C" /* 硬件异步串口连接方式 */ #define EN_DISK_QUERY 1 /* 启用磁盘查询 */ #include "..FILE_SYS.H" #include "..FILE_SYS.C" UINT8 idata buf[64]; main( ) { } 打开工程,将这些文件添加至工程里面,加好文件路径。 然后在主函数里面添加例程例程里面的代码。 主要是移植好接口函数,以及中断函数,所有的函数都是基于“xWriteCH376Cmd” “xWriteCH376Data” “xReadCH376Data” “Query376Interrupt”这几个函数实现的。所以在移植代码时,理论上只需要调通这几个代码即可 /* SPI片选无效,结束CH376命令,仅用于SPI接口方式 */ void xEndCH376Cmd( void ) { CH376T_CS_HIGH; } /************************************************************************************************** ** 函数名称: xWriteCH376Cmd ** 功能描述: 向CH376写命令操作 ** 输 入: mCmd-发送的命令 ** 输 出: 无 *******************************************************************************************************/ void xWriteCH376Cmd( UINT8 mCmd ) /* */ { // CH376T_CS_HIGH; 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 } Spi376OutByte函数是使用SPI输出一个字节的数据。 Spi376InByte函数是使用SPI读取一个字节的数据。 因为是模拟的SPI主机所以就是IO口直接拉的电平。 /************************************************************************************************** ** 函数名称: 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 ++; // delay_us(2); CH376T_SCK_HIGH; //CH376_SPI_SCK = 1; // delay_us(2); } return( d ); } 主函数里面的代码如下,功能是,向U盘创建一个“ABC.TXT”的文件,并写入“hello world!!”。 #include "delay.h" #include "sys.h" #include "usart.h" #include "HAL.H" #include "FILE_SYS.H" UINT8 TEST_BUFF[] = { "hello world!!" }; /************************************************************************************************** ** 函数名称: mStopIfError ** 功能描述: 检查函数是否操作成功,返回值为USB_INT_SUCCESS则操作成功,其他值则操作失败 ** 输 入: iError-需要检查的参数 ** 输 出: 无 *******************************************************************************************************/ void mStopIfError( UINT8 iError ) { if ( iError == USB_INT_SUCCESS ) return; /* 操作成功 */ printf( "Error: %02Xn", (UINT16)iError ); /* 显示错误 */ while ( 1 ) { ; } } int main(void) { UINT8 s; delay_init(); //延时函数初始化 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级 uart_init(115200); //串口初始化为115200 printf("CH376_UDisk_TESTrn"); while ( 1 ) { printf( "Wait Udisk/SDn" ); while ( CH376DiskConnect( ) != USB_INT_SUCCESS ) /* 检查U盘是否连接,等待U盘插入,对于SD卡,可以由单片机直接查询SD卡座的插拔状态引脚 */ { mDelaymS( 100 ); } mDelaymS( 200 ); /* 延时,可选操作,有的USB存储器需要几十毫秒的延时 */ /* 对于检测到USB设备的,最多等待10*50mS */ for ( s = 0; s < 10; s ++ ) { mDelaymS( 50 ); printf( "Ready ?n" ); if ( CH376DiskMount( ) == USB_INT_SUCCESS ) break; /* 初始化磁盘并测试磁盘是否就绪 */ } s = CH376FileCreate("/ABC.TXT"); mStopIfError( s ); CH376ByteWrite( TEST_BUFF, sizeof(TEST_BUFF), NULL ); s = CH376FileClose( TRUE ); mStopIfError( s ); printf( "Take outn" ); while ( CH376DiskConnect( ) == USB_INT_SUCCESS ) { /* 检查U盘是否连接,等待U盘拔出 */ mDelaymS( 100 ); } mDelaymS( 200 ); } } 到此代码部分调试完成,剩下就是连接好硬件部分,进行测试。 四、硬件连接 使用的是SPI接口时需要注意,SPI的MOSI对应的CH376的SDI,MISO对应的SDO。 在芯片主控上面对应是 PB10 INT PB12 SCS PB13 SCK PB14 SDO PB15 SDI |
|
|
|
只有小组成员才能发言,加入小组>>
3323 浏览 9 评论
3000 浏览 16 评论
3498 浏览 1 评论
9073 浏览 16 评论
4093 浏览 18 评论
1198浏览 3评论
614浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
603浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2343浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1902浏览 2评论
小黑屋| 手机版| Archiver| 德赢Vwin官网 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-31 00:45 , Processed in 1.200996 second(s), Total 50, Slave 41 queries .
Powered by 德赢Vwin官网 网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
德赢Vwin官网 观察
版权所有 © 湖南华秋数字科技有限公司
德赢Vwin官网 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号