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

📄 d12ci.c

📁 USB固件开发源程序,以单片机为核心,转贴的
💻 C
字号:
#include "reg52.h"
#include "absacc.h"				//如果用XBYTE需要包含这个头文件
#include "usb.h"

/*****************************
*******USB数据结构变量声明
*****************************/
xdata EPPFLAGS bEPPflags;
xdata CONTROL_XFER ControlData;

/****************************
******D12硬件通信基本宏
****************************/
#define SendD12Cmd(value)  	XBYTE[D12_COMMAND] = (value)
#define SendD12Data(value)	XBYTE[D12_DATA]    = (value)
#define GetD12Data		XBYTE[D12_DATA]



//////////////////////////////////////////////////////////////
////////段名:		D12初始化函数
////////个数:		4
////////			D12_SetAddressEnable(uchar)		设置地址寄存器
////////			D12_SetEndpointEnable(uchar)	使能普通/同步端点
////////			D12_SetMode(uchar , uchar)		设置D12使用模式
////////			D12_SetDMA(uchar)				....
/////////////////////////////////////////////////////////////
//函数名:D12_SetAddressEnable
//输入参数:uchar Address
//功能:设置地址并使能
//注意事项:Address是从PC分配过来的	
//使用情况:D12基本通信函数
void D12_SetAddressEnable(uchar Address)
{
	if(bEPPflags.bits.in_isr == 0)
		DISABLE;

	SendD12Cmd(0xD0);                     

	Address |= 0x80;              //使能位
	SendD12Data(Address);             //地址位

	if(bEPPflags.bits.in_isr == 0)
		ENABLE;
}

//函数名:D12_SetEndpointEnable
//输入参数:uchar bEnable
//功能:端点使能,置1后就使能普通/同步端点
//注意事项:
//使用情况:D12基本通信函数
void D12_SetEndpointEnable(uchar bEnable)
{
	if(bEPPflags.bits.in_isr == 0)
		DISABLE;

	SendD12Cmd(0xD8);
	if(bEnable)
		SendD12Data(1);
	else
		SendD12Data(0);

	if(bEPPflags.bits.in_isr == 0)
		ENABLE;
}

//函数名:D12_SetMode
//输入:模式,时钟字节
//功能:设置LAZYCLOCK,时钟运行,中断模式,SOFTCONNECT,端点配置
//注意事项: 命令后要写入两个字节,如下
//	7	6	5	4		3		2		1		0		
//	端点配置	留	SoftConnect	中断模式	时钟运行	无LAZYCLOCK	留
//
//	7		6		5	4	3210
//	SOF_ONLY	SET_TO_ONE			时钟分频系数

//使用情况:D12基本通信函数
void D12_SetMode(uchar bConfig, uchar bClkDiv)//设置模式,在usb.c里设置的
{
 	if(bEPPflags.bits.in_isr == 0)
		DISABLE;
 	SendD12Cmd(0xF3);
 	SendD12Data(bConfig);
 	SendD12Data(bClkDiv);
 	if(bEPPflags.bits.in_isr == 0)
 		ENABLE;

}


//函数名:D12_SetDMA
//输入:
//功能:
//注意事项:在命令后跟一个字节数据的写入或读出   (P35)
//	7		6		5		4		3		2		10
//	端点索引5	端点索引4	中断脚模式	自动重装	DMA方向		DMA使能		DAM突发串
//	中断使能	中断使能
//
void D12_SetDMA(uchar bMode)
{

 	if(bEPPflags.bits.in_isr == 0)
 	 	DISABLE;
 	SendD12Cmd(0xFB);
 	SendD12Data(bMode);
	if(bEPPflags.bits.in_isr == 0)
		ENABLE;

}

/*
//功能:得到设置DMA寄存器的数值,不过用途不大。
uchar D12_GetDMA(void)
{
 SendD12Cmd(0xFB);
 return(GetD12Data());
}
*/


///////////////////////////////////////////////////////////////////
///////段名:			端点状态设置函数
///////个数:			5
///////
///////
///////
///////
///////
//////////////////////////////////////////////////////////////////

//函数名:D12_ReadInterruptRegister
//功能:读中断状态寄存器
//注意事项:(P36)  连续读取两个字节
//	7		6		5		4		3		2		1		0
//	挂起改变	总线复位	主输入端点	主输出端点	端点1输入	端点1输出	控制端点输入	控制端点输出
//					D12->PC		PC->D12
//
unsigned short D12_ReadInterruptRegister(void)  //读中断寄存器
{
	uchar b1;
	unsigned int j;
	SendD12Cmd(0xF4);
	b1 = GetD12Data;
	j =  GetD12Data;		
	j <<= 8;
	j += b1;      //第一字节在前,第二字节在后
    //printf("%x..",b1);
	return j;
}

//函数名:D12_SelectEndpoint
//功能:选择端点,选择后可以读出端点缓冲是否已经满
//注意事项:
//输入:端点索引
uchar D12_SelectEndpoint(uchar bEndp)//选择端点
{
	uchar c;

	if(bEPPflags.bits.in_isr == 0)
		DISABLE;

	SendD12Cmd(bEndp);
	c = GetD12Data;
	if(bEPPflags.bits.in_isr == 0)
		ENABLE;

	return c;
}


/*
//功能:读端点状态
//返回当前端点的状态
//
uchar D12_ReadEndpointStatus(uchar bEndp)
{
	uchar c;

	if(bEPPflags.bits.in_isr == 0)
		DISABLE;

	SendD12Cmd(0x80 + bEndp);
	c = GetD12Data();

	if(bEPPflags.bits.in_isr == 0)
		ENABLE;

	return c;
}
*/
//函数名:D12_ReadLastTransactionStatus
//功能:读最后处理状态寄存器状态
//注意事项:读一次后会复位中断寄存器中的响应位并将状态清0.读出1个字节,参看(P38),
//输入:40H+端点索引
//
//
uchar D12_ReadLastTransactionStatus(uchar bEndp)//读最后处理状态寄存器     
{
	SendD12Cmd(0x40 + bEndp);		
	return GetD12Data;		
}


//函数名:D12_SetEndpointStatus
//输入:			bEndp		bStalled
//			选择端点	响应的状态,只能是第一位有效,1就为停止			
//功能:设置断点的状态,
//注意事项:(P40)	应该仔细看看书
void D12_SetEndpointStatus(uchar bEndp , uchar bStalled)//设置端点状态
{
	if(bEPPflags.bits.in_isr == 0)
		DISABLE;

	SendD12Cmd(0x40 + bEndp);      //端点索引
	SendD12Data(bStalled);         //1表示停止,写0表示初始化端点

	if(bEPPflags.bits.in_isr == 0)
		ENABLE;
}

//函数名:D12_AcknowledgeEndpoint
//功能:应答SETUP包
//注意事项:P(40),SETUP包到后要有应答才能继续继续允许对IN,OUT端点的缓冲区操作
//		要先选择了端点再应答
//
void D12_AcknowledgeEndpoint(uchar endp)//应答端点
{
	SendD12Cmd( endp);	//选择端点
	SendD12Cmd(0xF1);	//应答设置
	if(endp == 0)
		SendD12Cmd(0xF2);	//缓冲区清零
}



/////////////////////////////////////////////////////////
////////段名:			读写数据函数
////////个数:
/////////////////////////////////////////////////////////




//写端点缓冲			端点索引           长度           所写数据缓冲区
uchar D12_WriteEndpoint(uchar endp, uchar len, uchar * buf)
{
	uchar i;

	if(bEPPflags.bits.in_isr == 0)
		DISABLE;
	//---------------------
	SendD12Cmd(endp);	//选择端点
	i=GetD12Data;		//读入满/空状态	
	SendD12Cmd(0xF0);	//写缓冲区命令
	SendD12Data(0);     //第一个字节必须写0
	SendD12Data(len);

	for(i=0; i<len; i++)
		SendD12Data(*(buf+i));

	SendD12Cmd(0xFA);	//使缓冲区有效
	
	//--------------------------------
	if(bEPPflags.bits.in_isr == 0)
		ENABLE;

	return len;
}

//用途和上面相同,但只写一个字节
void D12_WriteEndpointByte(uchar endp, uchar buf)
{
	uchar i;

	if(bEPPflags.bits.in_isr == 0)
		DISABLE;
	//---------------------
	SendD12Cmd(endp);	//选择端点
	i=GetD12Data;		//读入满/空状态	
	SendD12Cmd(0xF0);	//写缓冲区命令
	SendD12Data(0);     //第一个字节必须写0
	SendD12Data(1);		//长度
	SendD12Data(buf);

	SendD12Cmd(0xFA);	//使缓冲区有效
	
	//--------------------------------
	if(bEPPflags.bits.in_isr == 0)
		ENABLE;

//	return len;
}
//////////////读端点缓冲          端点索引            长度                数据缓冲区
uchar D12_ReadEndpoint(uchar endp, uchar len, uchar * buf)
{
	uchar i, j;

	if(bEPPflags.bits.in_isr == 0)
		DISABLE;
	//--------------------------------
	SendD12Cmd(endp);			//选择端点,可选读一个字节,用于判断缓冲是否满,这里应该用下面的函数比较好
	if((GetD12Data & D12_FULLEMPTY) == 0) {	//如果缓冲区为空,则返回
		if(bEPPflags.bits.in_isr == 0)
			ENABLE;
		return 0;
	}
	
	SendD12Cmd(0xF0);			//读缓冲区命令
	j = GetD12Data;              //第一个字节无效的,
	j = GetD12Data;              //第二个为长度
	
	if(j > len)                 //实际长度大于需要读的长度
		j = len;                //

	for(i=0; i<j; i++)
		*(buf+i) = GetD12Data;
		
	SendD12Cmd(0xF2);				//缓冲区清空
	//-------------------------------
	if(bEPPflags.bits.in_isr == 0)
		ENABLE;

	return j;
}


////////////////////////////////////////////
/////////其他命令
///////////////////////////////////////////
/*
//功能:发送恢复
void D12_SendResume(void)
{
 SendD12Cmd(0xF6);
}
*/

⌨️ 快捷键说明

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