⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 udisk.c

📁 AVR单片机平台Atmega32+CH375A芯片读写U盘代码
💻 C
📖 第 1 页 / 共 2 页
字号:
//此版本为测试375自带模块函数设计,
//测试读取文件,新建文件,写入文件,修改属性


#include <iom32v.h>
#include "macros.h"
#include <string.h>
#include <stdio.h>
#include "twi.h"
#include "UART.h"
#include "udisk.h"


#define uchar unsigned char
#define UINT8 unsigned char
#define ulong unsigned long
#define uint  unsigned int
//端口的定义,用I/O模拟总线方式
//LED定义
#define LEDPORT PORTD
#define ALLLED  0xF0
#define LEDRD   PD7
#define LEDWR   PD6
#define LEDBUSY PD5
#define LEDERR  PD4
//按键定义
#define KEYPORT PIND
#define S1      PD3
//模拟总线定义
#define DATAOUT PORTA                    //D0~D7在PA口
#define DATAIN  PINA

#define CTRLBUS PORTC
#define CTRLWR  PC7                      //WR信号线在PC7
#define CTRLRD  PC6                      //RD信号线在PC6

#define ADDRBUS PORTB
#define A0      PB0                      //A0地址线在PB0

#define CSPORT PORTB
#define CS      PB1                      //片选线在PB1

//一些总线控制宏定义
#define WRCTRL  CTRLBUS&= ~BIT(CTRLWR)   //写总线置低
#define RDCTRL  CTRLBUS&= ~BIT(CTRLRD)   //读总线置低
#define CLRCTRL CTRLBUS|= (BIT(CTRLWR)|BIT(CTRLRD))  //读写总线均置高
#define MCMD  ADDRBUS|= BIT(A0)                       //指令的读写模式,A0置高
#define MDATA  ADDRBUS&= ~BIT(A0)                       //数据的读写模式,A0置低
#define CSEN    ADDRBUS&= ~BIT(CS)                   //CS使能置低
#define CSDIS   ADDRBUS|= BIT(CS)                    //CS不使能置高
#define DATADIRI      DDRA=0                               //数据输入方式把DDRA置0
#define DATADIRO     DDRA=0xff                            //数据输出方式把DDAR置0xff



//点灯的宏定义

#define LIGHT_WR    LEDPORT&= ~BIT(LEDWR)
#define OFF_WR      LEDPORT|= BIT(LEDWR)
#define LIGHT_RD    LEDPORT&= ~BIT(LEDRD)
#define OFF_RD      LEDPORT|= BIT(LEDRD)
#define LIGHT_BUSY  LEDPORT&= ~BIT(LEDBUSY)
#define OFF_BUSY    LEDPORT|= BIT(LEDBUSY)
#define LIGHT_ERR   LEDPORT&= ~BIT(LEDERR)
#define OFF_ERR     LEDPORT|= BIT(LEDERR)

#define LIGHT_ALL   LEDPORT&= ~ALLLED
#define OFF_ALL LEDPORT|= ALLLED

#define I2C_SEND_READY DataPrepared = 0xff
#define CLR_COMFLAGE I2cComStatus = 0

#define FILE_ATTRI_BYTES 9



#define RETURN_SUCCESS nComBuff.AckData.Ack = A_SUCCESS

//决定是否使能应答
#define OPEN_ACK TWCR|= 1<<TWEA
#define CLOSE_ACK  TWCR&= ~(1<<TWEA)



/* 以下定义的详细说明请看CH375HF9.H文件 */
#define LIB_CFG_FILE_IO			1		/* 文件读写的数据的复制方式,0为"外部子程序",1为"内部复制" */
#define LIB_CFG_INT_EN			0		/* CH375的INT#引脚连接方式,0为"查询方式",1为"中断方式" */

/* 单片机的RAM有限,其中CH375子程序用512字节,剩余RAM部分可以用于文件读写缓冲 */
#define FILE_DATA_BUF_LEN		512	/* 外部RAM的文件数据缓冲区,缓冲区长度不小于一次读写的数据长度 */

#define CH375_INT_WIRE			( PIND & 0x04 )	/* PIND.2, CH375的中断线INT#引脚,连接CH375的INT#引脚,用于查询中断状态 */

#define NO_DEFAULT_CH375_F_ENUM		1		/* 未调用CH375FileEnumer程序故禁止以节约代码 */
//#define NO_DEFAULT_CH375_F_QUERY	1		/* 未调用CH375FileQuery程序故禁止以节约代码 */
#define LIB_CFG_FILE_IO_DEFAULT
#define NO_DEFAULT_DELAY_100US                 //用自己定义的延时100us函数实现延时
#define NO_DEFAULT_DELAY_WRITE                 //用自己定义的延时函数实现写入后的延时
#include "CH375HFB.h"



void init_devices(void );
void mDelaymS( UINT8 ms );
void xDelay100uS( void );
void xDelayAfterWrite( void );

void twi_process(void);
void transmit_process(void);
void receive_process(void);
void twisentbyte(unsigned char SentData);
void delay_us(void);
void xWriteCH375Cmd( UINT8 mCmd );
void xWriteCH375Data( UINT8 mData );
UINT8 xReadCH375Data( void );
void timer0_ovf_isr(void);
void timer0_init(void);
void twi_isr(void);
void variable(void);
void RecieveFrameProcess( void );
void ModuleSetOffset(uchar ModeLocate);

COM_BUFF nComBuff;
uchar  ys20ms;

uchar B_status;    //模块大状态变量
uchar temp[10];

uchar OperReturn;
uchar DataPrepared;       //数据是否准备好变量
uchar rdcount;

extern uint *SlaveSendLength;
extern uchar I2cComStatus;     //通信状态变量

/*Bit7        Bit6        Bit5    Bit4 Bit3 Bit2 Bit1 Bit0
  I2CRecCom   I2C_sendCom  
  I2C_RecCom--Recieve complete
  I2C_SendCom--Transmmit complete
 **********************************************************/
extern unsigned char *I2cReceiveData;    //I2c数据接收缓冲地址 
extern unsigned char *I2cSendData;      //I2c数据发送缓冲地址
			
extern unsigned char *UartRx;          //存放接收数据的指针
extern unsigned int *RxLength;         //数据接收长度地址指针
extern unsigned char UartState; 	  //UART状态变量		
			
				
			

void main(void)
{
	UINT8 i;
	uint j=200;
begin: variable( );              //变量的初始化
    i2cSetBitrate(100);
    i2cInit();
    i2cSetLocalDeviceAddr(0x60,1);
	init_USART(0);
    init_devices( );
    /*测试延时时间是否充足*/
	xDelay100uS( );
	delay_us( );
    put_s("Start\n");
    for(i=0;i<3;i++)           //闪烁三次
	{
		LIGHT_ALL;
        ys20ms=20;
		while(ys20ms);
		OFF_ALL;
		ys20ms=20;
		while(ys20ms);
		
	}

	OperReturn = CH375LibInit( );  // 初始化CH375程序库和CH375芯片,操作成功返回0 
	if(OperReturn)
	{
		goto begin;                 //重新启动程序
	}

	while( CH375DiskStatus != DISK_CONNECT ) xQueryInterrupt( );  // 查询CH375中断并更新中断状态,等待U盘插入 
	
	mDelaymS( 200 );  //延时,可选操作,有的USB存储器需要几十毫秒的延时 

/* 检查U盘是否准备好,有些U盘不需要这一步,但是某些U盘必须要执行这一步才能工作 */
	for ( i = 0; i < 10; i ++ ) 
	{                                       /* 有的U盘总是返回未准备好,不过可以被忽略 */
		mDelaymS( 100 );
		if ( CH375DiskReady( ) == ERR_SUCCESS ) 
        {
            B_status = S_READY;
            break;  /* 查询磁盘是否准备好 */
        }
        else
        {
            B_status = S_NOTREADY;
        }
	}
    put_s("Prepared\n");

	while(1)
	{

		if(I2cComStatus & BIT(I2C_RECCOM))
		{
            CLOSE_ACK;                //停止应答
            LIGHT_BUSY;
            puts("Command received\n");
            put_bytes(&nComBuff.ReqData.Com,1);
			I2cComStatus&= ~BIT(I2C_RECCOM);
            if(nComBuff.ReqData.Com == R_RESET)
            {
                nComBuff.ReqData.Com = 0;
                goto begin;
            }
			RecieveFrameProcess( );
            DataPrepared = 0xff;
		}
		if(DataPrepared)
		{
            DataPrepared = 0;
            put_bytes((char* )&nComBuff,MAX_BYTE_TRANS+5);
            OPEN_ACK;                 //进行应答
            OFF_BUSY;
		}
        
	}
     	
}
	


/* 延时指定毫秒时间,根据单片机主频调整,不精确 */
void	mDelaymS( UINT8 ms )
{
	UINT16	i;
	while ( ms -- ) for ( i = 1325; i != 0; i -- );
}


/******************************************************************************
延时1uS
*******************************************************************************/
	
void delay_us(void)
    {
	   uchar j;
	   j++;
	}
/*****************************************************************************
/函数库要调用的100us延时
*****************************************************************************/
void xDelay100uS( void )				/* 延时100uS */
{
	UINT16	count;
	for ( count = 150; count != 0; count -- ); 
}
/****************************************************************************
/函数库要调用的写入后延时
****************************************************************************/
void xDelayAfterWrite( void )			/* 写操作后延时 */
{
	UINT16	count;
	for ( count = 300; count != 0; count -- );  /* 延时200uS左右 */
}
/**************************************************************************
外部定义的被CH375程序库调用的子程序,向CH375写命令,最小周期为4uS,
否则之前之后各延时2uS 
***************************************************************************/
void xWriteCH375Cmd( UINT8 mCmd )	
{
	delay_us();
	delay_us();
	MCMD;                               //A0置高
	DATADIRO;                            //数据方向为输出
	DATAOUT=mCmd;                        //数据输出
	CSEN;                                //使能
	WRCTRL;                              //写信号
	WRCTRL;                              //延时
	CLRCTRL;                            //关写信号
	CSDIS;                              //使能禁止
	delay_us();
	delay_us();
}

/**************************************************************************
外部定义的被CH375程序库调用的子程序,向CH375写数据,最小周期为1.5uS,
否则之后延时1.5uS
***************************************************************************/
void xWriteCH375Data( UINT8 mData )
{
	MDATA;                               //A0置高
	DATADIRO;                            //数据方向为输出
	DATAOUT=mData;                        //数据输出
	CSEN;                                //使能
	WRCTRL;                              //写信号
	WRCTRL;                               //延时
	CLRCTRL;                            //关写信号
	CSDIS;                              //使能禁止
	delay_us();
	delay_us();	 

}
/**************************************************************************
外部定义的被CH375程序库调用的子程序,从CH375读数据,最小周期为1.5uS,
否则之前延时1.5uS
***************************************************************************/
UINT8 xReadCH375Data( void )
{
	UINT8 inData;
	delay_us();
	MDATA;
	DATADIRI;
	CSEN;
	RDCTRL;
	RDCTRL;
	inData=DATAIN;
	CLRCTRL;
	CSDIS;
	return(inData);
}

/****************************************************************************
/动作执行完,返回结果,OperReturn为0则返回A_SUCCESS,非零则返回OperReturn值
****************************************************************************/
void ReturnProResult( void )
{
	if(OperReturn)
	{
		nComBuff.AckData.Ack = OperReturn;
	}
	else
	{
		nComBuff.AckData.Ack = A_SUCCESS;
	}
}

/************************************************************************/
/* 发送错误码。自动组帧。
入口参数:ErrorCode                                                     */
/************************************************************************/
void ReturnErrorCode(uchar ErrorCode)
{
	I2C_SEND_READY;
    nComBuff.AckData.Ack = ErrorCode;
	nComBuff.AckData.FrameLen = 3;
}
/************************************************************************/
/* 复制数据
入口参数:
uchar destination *:目的地址
uchar source *:源地址
uint number:  字节数                                                     */
/************************************************************************/
void CopyBytes(uchar* destination,uchar* source,uint number)
{
	uint i;
	for(i=0;i<number;i++)
	{
		*(destination+i) = *(source+i);
	}
}

/************************************************************************/
/* 新建文件(文件夹)函数
入口参数:directory,0=新建文件,!0=新建文件夹                          */
/************************************************************************/
void ModuleNewFile(uchar directory)
{
	nComBuff.ReqData.VeryData.FileName[MAX_PATH_LEN-1]=0;  //确保最后一个是“0”,作为字符串的尾部
	strcpy((char *)mCmdParam.Create.mPathName,(char *)nComBuff.ReqData.VeryData.FileName);
	OperReturn = CH375FileCreate( );    //新建文件
	
	if(OperReturn)
	{
		ReturnErrorCode(OperReturn);
		B_status = S_READY;
	}
	else if(directory)
	{
		mCmdParam.Modify.mFileAttr = ATTR_DIRECTORY;
		mCmdParam.Modify.mFileDate = 0xffff;
		mCmdParam.Modify.mFileSize = 0xffffffff;
		mCmdParam.Modify.mFileTime = 0xffff;
		OperReturn = CH375FileModify();
		directory = 0;                         //把此值清零防止再进入此分支
		if(OperReturn)
		{
			ReturnErrorCode(OperReturn);
			B_status = S_READY;
		}
		else
		{
			mCmdParam.Close.mUpdateLen = 1;                    //自动更新文件长度
			OperReturn = CH375FileClose( );
			if(OperReturn)
			{
				ReturnErrorCode(OperReturn);
                B_status = S_READY;
			}
			else
			{
				ReturnErrorCode(A_SUCCESS);
				B_status = S_READY;
			}
					
		}
	}
	else
	{

		ReturnErrorCode(A_SUCCESS);
		B_status=S_OPEN;
	}

}

/************************************************************************/
/* 如果优盘的状态是准备好,但未读写,进入的分支                         */
/************************************************************************/
void StatusReady(void)
{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -