📄 usb6.c
字号:
#include<main.h>#include <stdio.h>
#include <avr/io.h>
#define usb_cmd (*(volatile unsigned char *)0xa001)
#define usb_data (*(volatile unsigned char *)0xa000)
/* 单片机的RAM有限,其中CH375子程序用512字节,剩余RAM部分可以用于文件读写缓冲 */
#define CMD_RET_SUCCESS 0x51 /* 命令操作成功 */
#define FILE_DATA_BUF_LEN 0x0200 /* 外部RAM的文件数据缓冲区,缓冲区长度不小于一次读写的数据长度 */
#define CH375_INT_WIRE ( PINB & 0x10 ) /* PINB.4, CH375的中断线INT#引脚,连接CH375的INT#引脚,用于查询中断状态 */
#define CMD_SET_USB_MODE 0x15 /* 设置USB工作模式 */
#define CMD_CHECK_EXIST 0x06 /* 测试工作状态 */
#define CMD_RESET_ALL 0x05 /* 执行硬件复位 */
#define CMD_GET_DESCR 0x46 /* 主机方式: 控制传输-获取描述符 */
#define CMD_WR_USB_DATA7 0x2B /* 向USB端点2的发送缓冲区写入数据块 */
#define USB_INT_EP2_IN 0x0A /* USB端点2的IN */
#define CMD_GET_STATUS 0x22 /* 获取中断状态并取消中断请求 */
#define CMD_UNLOCK_USB 0x23 /* 设备方式: 释放当前USB缓冲区 */
#define USB_INT_DISCONNECT 0x16 /* 检测到USB设备断开事件 */
#define CMD_DISK_INIT 0x51 /* 主机方式: 初始化USB存储器 */
#define USB_INT_SUCCESS 0x14 /* USB事务或者传输操作成功 */
#define CMD_DISK_SIZE 0x53 /* 主机方式: 获取USB存储器的容量*/
#define CMD_RD_USB_DATA 0x28 /* 从当前USB中断的端点缓冲区读取数据块, 并释放缓冲区 */
#define CMD_DISK_READ 0x54 /* 主机方式: 从USB存储器读数据块(以扇区512字节为单位) */
#define CMD_DISK_RD_GO 0x55 /* 主机方式: 继续执行USB存储器的读操作 */
#define USB_INT_DISK_READ 0x1D /* USB存储器读数据块, 请求数据读出 */
unsigned int WordSwap(unsigned int input);
unsigned int LSwapINT16(unsigned short dData1,unsigned short dData2);
unsigned long LSwapINT32(unsigned long dData1,unsigned long dData2,unsigned long dData3,unsigned long dData4);
unsigned char ch375_init( unsigned char mode);
unsigned char set_usb_mode( unsigned char mode );
void usb_send_data(unsigned char *pbuff,unsigned int len);
unsigned char EnumMassDev(void);
unsigned char InitDisk(void);
unsigned char ReadSector(unsigned long iLbaStart, unsigned char iSectorCount,unsigned char *oDataBuffer);
unsigned char WriteSector(unsigned long iLbaStart, unsigned char iSectorCount,unsigned char *oDataBuffer);
unsigned char usb_rec_buff[64];
unsigned char usb_rec_buflen;
unsigned char diskbuff[512*2];
unsigned char CH375_WR_CMD_PORT( unsigned char type);
unsigned char CH375_WR_DAT_PORT(unsigned char type);
void main(void)
{
void delayms( unsigned char m)
{
unsigned char i,j;
while(m--)
{for ( i = 100; i != 0; i -- )
for ( j=10; j!=0; j-- );}
}
void delay2us(unsigned char m)
{
unsigned char i;
while(m--)
{for ( i = 2; i != 0; i -- );}
}
/* 设置CH375的工作模式 */
unsigned char set_usb_mode( unsigned char mode )
{
unsigned char i;
unsigned char RD_Data;
usb_cmd=CMD_SET_USB_MODE;
delay2us(1);
usb_data=0x06;
delay2us(1);
for ( i = 100; i != 0; i -- ) /* 等待设置模式操作完成,不超过30uS */
{
RD_Data=usb_data;
if( RD_Data == CMD_RET_SUCCESS )
return 1;
} /* 成功 */
return 0;
}
unsigned char ch375_init(unsigned char mode)
{
unsigned char i, k;
EIMSK|=0x10;
/* 测试CH375是否正常工作 */
for( k=100; k!=0; k-- )
{
usb_cmd=CMD_CHECK_EXIST ; /* 测试CH375是否正常工作 */
delay2us(1);
usb_data=0x0f; /* 写入测试数据 */
/* 返回数据应该是测试数据取反 */
delay2us(1);
i=usb_data;
if ( 0xf0!= i) /* CH375不正常 */
{
for ( i=5; i!=0; i-- )
usb_cmd=CMD_RESET_ALL; /* 多次重复发命令,执行硬件复位 */
delayms(50); /* 延时50ms */
}
else
break;
}
/* 设置CH375的工作模式 */
return set_usb_mode(mode); //内部固件模式
}
void CtrlGetDescr( unsigned char type )
{ /* 执行控制传输: 获取USB 描述符 */
char IntStatus = 0; /* 清中断状态 */
CH375_WR_CMD_PORT(CMD_GET_DESCR); /* 控制传输-获取描述符 */
CH375_WR_DAT_PORT( type ); /* 0:设备描述符, 1:配置描述符 */
while ( IntStatus == 0 ); /* 等待操作完成,IntStatus 由中断服务程序更新 */
}
unsigned char get_ver(void)
{ unsigned char ver;
usb_cmd=0x01;
ver=usb_data;
return ver;
}
void _usb_send(unsigned char *pbuff,unsigned char len)
{
unsigned char i,status;
usb_cmd=CMD_WR_USB_DATA7;
delay2us(3);
usb_data=len;
delay2us(1);
for(i=0;i<len;i++)
{
usb_data=pbuff[i];
delay2us(1);
}
while(status!=USB_INT_EP2_IN)
{
usb_cmd=CMD_GET_STATUS;
delay2us(3);
status=usb_data;
delay2us(3);
}
}
void usb_send_data(unsigned char *pbuff,unsigned int len)
{
unsigned char i,r,n;
EIMSK&=~0x10;
r=len/64;
n=len%64;
for(i=0;i<r;i++)
_usb_send((pbuff+i*64),64);
_usb_send((pbuff+i*64),n);
usb_cmd=CMD_UNLOCK_USB;
delay2us(1);
EIMSK|=0x10;
}
unsigned char waitint(void)
{
while(PINE&0x10);
usb_cmd=CMD_GET_STATUS;
delay2us(2);
return usb_data;
}
unsigned char InitDisk(void)
{
unsigned char status;
usb_cmd=CMD_GET_STATUS;
delay2us(10);
status=usb_data;
if (status==USB_INT_DISCONNECT) return status;//usb断开
usb_cmd=CMD_DISK_INIT;
status=waitint();
if (status!=USB_INT_SUCCESS) return status;
usb_cmd=CMD_DISK_SIZE;
status=waitint();
if (status!=USB_INT_SUCCESS)
{
delayms(250);
usb_cmd=CMD_DISK_SIZE;
status=waitint();
}
if (status!=USB_INT_SUCCESS) return status;
return 1;//u盘初始化成功
}
unsigned char ReadSector(unsigned long iLbaStart, unsigned char iSectorCount,unsigned char *oDataBuffer)
{
unsigned int mBlockCount;
unsigned char c;
usb_cmd=CMD_DISK_READ; /* 从USB存储器读数据块 */
delay2us(10);
usb_data=(unsigned char)iLbaStart; /* LBA的最低8位 */
delay2us(2);
usb_data=(unsigned char)(iLbaStart >> 8);
delay2us(2);
usb_data=(unsigned char)(iLbaStart>> 16);
delay2us(2);
usb_data=(unsigned char)(iLbaStart>> 24); /* LBA的最高8位 */
delay2us(2);
usb_data=iSectorCount ; /* 扇区数 */
for ( mBlockCount = iSectorCount * 8; mBlockCount != 0; mBlockCount -- )
{
c = waitint(); /* 等待中断并获取状态 */
if ( c == USB_INT_DISK_READ )
{ /* 等待中断并获取状态,请求数据读出 */
usb_cmd=CMD_RD_USB_DATA; /* 从CH375缓冲区读取数据块 */
delay2us(10);
c =usb_data; /* 后续数据的长度 */
delay2us(2);
while ( c -- )
{
*oDataBuffer++ = usb_data;
delay2us(2);
}
usb_cmd=CMD_DISK_RD_GO; /* 继续执行USB存储器的读操作 */
}
else break; /* 返回错误状态 */
}
if ( mBlockCount == 0 )
{
c = waitint(); /* 等待中断并获取状态 */
if ( c== USB_INT_SUCCESS ) return( 1 ); /* 操作成功 */
}
return( c ); /* 操作失败 */
}
unsigned int WordSwap(unsigned int input)
{
return(((input&0x00FF)<<8)|((input&0xFF00)>>8));
}
unsigned int LSwapINT16(unsigned short dData1,unsigned short dData2)
{
unsigned int dData;
dData = ((dData2<<8)&0xff00)|(dData1&0x00ff);
return dData;
}
unsigned long LSwapINT32(unsigned long dData1,unsigned long dData2,unsigned long dData3,unsigned long dData4)
{
unsigned long dData;
dData = ((dData4<<24)&0xff000000)|((dData3<<16)&0xff0000)|((dData2<<8)&0xff00)|(dData1&0xff);
return dData;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -