【CH376】使用CH376控制U盘-读写文件

该项目通过STM32芯片的IO口模拟SPI接口操作CH376芯片完成对U盘的读写操作。

CH376芯片内置了文件管理系统,可以通过简洁的命令操作U盘,完成读写文件等各种常规的U盘操作,用户不需要考虑FAT文件系统的底层知识,只需要使用基本的命令就行。官方提供了大量的函数,如果只是对U盘进行基本的操作的话,可以直接使用各种函数,不需要详细解读手册。

目录

一、硬件准备:

二、资料准备:

三、code

四、硬件连接


一、硬件准备:

STM32F103:作为一个主控芯片使用。

CH376:接口芯片,用来控制U盘完成文件读写操作。

CH340:监控鼠标的传输过程。

若干杜邦线,以及U盘等等基本

二、资料准备:

软件参考沁恒提供的例程:http://www.wch.cn/downloads/CH376EVT_ZIP.html

手册参考:http://www.wch.cn/downloads/CH376DS1_PDF.html

                  http://www.wch.cn/downloads/CH376DS2_PDF.html

三、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 <reg52.h>
#include <stdio.h>
#include <string.h>

#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: %02X\n", (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_TEST\r\n");

	while ( 1 ) 
	{
		printf( "Wait Udisk/SD\n" );
		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 out\n" );
		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

 

  • 7
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值