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

📄 usbfunctions.c

📁 LT-1B msp430 程序原理图集合
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <msp430x14x.h>
#include "USBvariables.h"
#include "USBfunctions.h"
typedef unsigned char uchar;
typedef unsigned int  uint;

void (*StandardDeviceRequest[])(void)=
{
	Get_status,
	Clr_feature,
	Reserved,
	Set_feature,
	Reserved,
	Set_addr,
	Get_descriptor,
	Reserved,
	Get_config,
	Set_config,
	Get_interface,
	Set_interface,
	Reserved,
	Reserved,
	Reserved,
	Reserved
};
/*******************************************
函数名称: Delayus
功    能: 延时指定微秒(8M晶振)
参    数: US--延时的微秒数(大约,不是很精确)
返回值  : 无
********************************************/
void Delayus(uint US)		  
{
    uint i;
    
    US=US*5/4;		 // 5/4是在8MHz晶振下,通过软件仿真反复实验得到的数值
    for( i=0;i<US;i++); 
}
/*******************************************
函数名称: Delayms
功    能: 延时指定毫秒(8M晶振)
参    数: MS--延时的毫秒数
返回值  : 无
********************************************/
void Delayms(uint MS)		  
{
     uint i,j;
     
     for(i=0;i<MS;i++)
     for(j=0;j<1141;j++);	// 1141是在8MHz晶振下,通过软件仿真反复实验得到的数值
}
/*******************************************
函数名称: D12_init
功    能: 初始化D12接口(包括数据接口和控制接口)
参    数: 无
返回值  : 无
********************************************/
void D12_init(void)
{
     USBDAT_DDR|=0xFF;				    //数据端口设置为输出
     USBCTL_DDR|=BIT(WR_N)|BIT(RD_N)|BIT(C_D)|BIT(D12_CS);//控制引脚设置为输出
     USBINT_DDR&=~BIT(D12_INT);	        //中断引脚设置为输入						  //中断引脚设置为输入				  
     USBINT_IES|=BIT(D12_INT);          //选择下降沿中断
     USBINT_SEL&=~BIT(D12_INT);         //选择IO端口
     USBINT_IE|=BIT(D12_INT);           //使能端口中断
     USBCTL_PORT|=BIT(WR_N)|BIT(RD_N)|BIT(D12_CS);		  //控制引脚无效
     
     EN_GINT();                         //使能全局中断    
     USBCTL_PORT&=~BIT(D12_CS);        //给出片选信号
}
/*******************************************
函数名称: OutB
功    能: 向D12写入一个字节数据或者命令
参    数: cmd--命令标识(为CMD是命令,为DAT是数据)
	  	  dat--要写入的字节数据
返回值  : 无
********************************************/
void OutB(uchar cmd,uchar dat)
{
     if(cmd==CMD)
     {
          USBCTL_PORT|=BIT(C_D); 
          Delayus(5);
          USBCTL_PORT&=~BIT(WR_N);
          Delayus(5);
          USBDAT_PORT=dat;  
          Delayus(5);
          USBCTL_PORT|=BIT(WR_N);
     }
     else
     {
          USBCTL_PORT&=~BIT(C_D);
          Delayus(1);
          USBCTL_PORT&=~BIT(WR_N);
          Delayus(1);
          USBDAT_PORT=dat;  
          Delayus(1);
          USBCTL_PORT|=BIT(WR_N);
     }
}
/*******************************************
函数名称: InB
功    能: 从D12读出一个字节数据
参    数: 无
返回值  : dat--读出的字节数据
********************************************/
uchar InB(void)
{ 
      uchar dat;
      
      USBDAT_DDR=0x00;
      USBDAT_PORT=0xFF;
      USBCTL_PORT&=~BIT(C_D);
      Delayus(1);
      USBCTL_PORT&=~BIT(RD_N);
      Delayus(1);
      dat=USBDAT_PIN;
      Delayus(1);
      USBCTL_PORT|=BIT(RD_N);
      USBDAT_DDR=0xFF;
      return dat;
}
/*******************************************
函数名称: Set_addren
功    能: 设置地址/使能
参    数: addr--设置的地址
	  enable--使能标志(为1使能,为0禁止)
返回值  : 无
********************************************/
void Set_addren(uchar addr, uchar enable)
{
	if(USB_FLAG.in_isr == 0)
		UEN_GINT();

	OutB(CMD, 0xD0);	//输出设置地址/使能指令
	Delayus(1);
	if(enable)
	{
		addr|=0x80;		//bit7置1,使能
	}
	Delayus(1);
	OutB(DAT,addr);		//输出设置值

	if(USB_FLAG.in_isr == 0)
		EN_GINT();
}
/*******************************************
函数名称: Set_EPen
功    能: 设置端点使能
参    数: enable--使能标志(为1使能,为0禁止)
返回值  : 无
********************************************/
void Set_EPen(uchar enable)
{
	if(USB_FLAG.in_isr == 0)
		UEN_GINT();

	OutB(CMD,0xD8);	        //输出设置端点使能指令
	Delayus(1);
	if(enable)
		OutB(DAT,1);		//设置端点允许
	else
		OutB(DAT,0);		//设置端点禁止

	if(USB_FLAG.in_isr == 0)
		EN_GINT();
}
/*******************************************
函数名称: Set_mode
功    能: 设置模式
参    数: config--配置字节信息
	  	  clkdiv--分频因子
返回值  : 无
********************************************/
void Set_mode(uchar config,uchar clkdiv)
{
	if(USB_FLAG.in_isr == 0)
		UEN_GINT();

	OutB(CMD,0xF3);		//输出设置模式指令
	Delayus(1);
	OutB(DAT,config);	//输出配置字节信息
	OutB(DAT,clkdiv);	//输出时钟分频因数字节

	if(USB_FLAG.in_isr == 0)
		EN_GINT();	
}
/*******************************************
函数名称: Set_DMA
功    能: 设置DMA工作方式设置
参    数: bMode--设置值
返回值  : 无
********************************************/
void Set_DMA(uchar bMode)
{
	if(USB_FLAG.in_isr == 0)
		UEN_GINT();

	OutB(CMD, 0xFB);	//设置DMA工作方命令
	Delayus(1);
	OutB(DAT, bMode);	//输出设置值

	if(USB_FLAG.in_isr == 0)
		EN_GINT();			
}

/*******************************************
函数名称: Read_IntR
功    能: 读取中断寄存器值
参    数: 无
返回值  : intreg--16位中断寄存器值
********************************************/
uint Read_IntR(void)
{
	uchar regl;
	uint  intreg;

	OutB(CMD,0xF4);	        //读取中断寄存器命令
	Delayus(5);
	regl=InB( );			//读取低8位字节
	intreg=InB( );			//读取高8位字节

	intreg<<=8;
	intreg+=regl;			//组合为16位

	return intreg;
}
/*******************************************
函数名称: Sel_EP
功    能: 端点选择,将内部指针初始化到选择的缓冲区起始位置
参    数: endp--端点索引号,取值0 ~ 5
返回值  : byte--一个字节的返回数据
********************************************/
uchar Sel_EP(uchar endp)
{
	uchar byte;
    
	if(USB_FLAG.in_isr == 0)
		UEN_GINT();

	OutB(CMD,endp);	//端点选择
	Delayus(1);
	byte=InB( );	//读出一个字节

	if(USB_FLAG.in_isr == 0)
		EN_GINT();

	return byte;
}
/*******************************************
函数名称: Sel_EP
功    能: 读取端点状态
参    数: endp--端点索引号,取值0 ~ 5
返回值  : status--端点状态
********************************************/
uchar Read_EPsta(uchar endp)//-----------------
{
	uchar status;

	if(USB_FLAG.in_isr == 0)
		UEN_GINT();

	OutB(CMD,0x80+endp);	//读取端点状态命令
	status=InB( );		    //读取端点状态

	if(USB_FLAG.in_isr == 0)
		EN_GINT();

	return status;
}
/*******************************************
函数名称: Read_LttransSta
功    能: 读取最后处理状态寄存器
参    数: endp--端点索引号,取值0 ~ 5
返回值  : status--端点最后处理的状态
********************************************/
uchar Read_LttransSta(uchar endp)
{
 	uchar status;
    
	OutB(CMD,0x40+endp);	//输出读取最后处理状态寄存器命令
	Delayus(5);
	status=InB( );
	return status;		    //读取状态
}
/*******************************************
函数名称: Set_EPsta
功    能: 设置端点状态
参    数: endp--端点索引号,取值0 ~ 5
	  	  stall--设置状态值
返回值  : 无
********************************************/
void Set_EPsta(uchar endp,uchar stall)
{
	if(USB_FLAG.in_isr == 0)
		UEN_GINT();

	OutB(CMD,0x40+endp);	//发送设置端点状态命令
	Delayus(1);
	OutB(CMD,stall);	    //设置端点状态

	if(USB_FLAG.in_isr == 0)
		EN_GINT();
}
/*******************************************
函数名称: Set_Sresume
功    能: 设置发送恢复
参    数: 无
返回值  : 无
********************************************/
void Set_Sresume(void)
{
	OutB(CMD,0xF6);		//设置发送恢复
}
/*******************************************
函数名称: Read_EP
功    能: 读取端点数据
参    数: endp--端点索引号,取值 0 ~ 5 
	  	  len--要读取的数据长度
		  buf--接收数据指针					   
返回值  : num--实际读到的字节数
********************************************/
uchar Read_EP(uchar endp,uchar len,uchar * buf)
{
	uchar i,num;

	if(USB_FLAG.in_isr == 0)
		UEN_GINT();

	OutB(CMD,endp);				//发送选择端点命令
	Delayus(1);
	if((InB( )&FULLEMPTY)==0)   //如果缓冲区为空 
	{	
		if(USB_FLAG.in_isr == 0)
		EN_GINT();
		return 0;			    //则返回读到0字节
	}

	OutB(CMD,0xF0);			    //发送读缓冲区命令
	Delayus(1);
	num=InB( );				    //读取保留字节
	num=InB( );				    //读取数据字节的数目/长度

	if(num>len)				    //如果大于要求读的字节数目
	{
		num=len;			    //则只读取要求的字节长度
	}
	for(i=0; i<num; i++)
		*(buf+i)=InB( );		//读取要求的字节数目/长度

	OutB(CMD,0xF2);				//清缓冲区,新的信息包才可以重新被接受

	if(USB_FLAG.in_isr == 0)
		EN_GINT();

	return num;				    //返回读到的字节数
}
/*******************************************
函数名称: Write_EP
功    能: 将数据写入端点
参    数: endp--端点索引号,取值 0 ~ 5 
	  	  len--要写入的数据长度
		  buf--发送数据指针					   
返回值  : num--实际写入的字节数
********************************************/
uchar Write_EP(uchar endp,uchar len,uchar * buf)
{
	uchar i;

	if(USB_FLAG.in_isr == 0)
		UEN_GINT();

	OutB(CMD,endp);			//发送选择端点命令
	Delayus(1);
	i=InB( );			    //可选地读取一个字节

	OutB(CMD,0xF0);			//发送写缓冲区命令	
	Delayus(1);
	OutB(DAT,0);			//写入一个保留字节
	Delayus(1);
	OutB(DAT,len);			//写入即将写入的字节数目
	Delayus(1);

	for(i=0; i<len; i++)
	{
		OutB(DAT,*(buf+i));	//写入指定的字节
	}
	Delayus(1);
	OutB(CMD,0xFA);			//使缓冲区有效

	if(USB_FLAG.in_isr == 0)
		EN_GINT();

	return len;				//返回写入的字节数
}
/*******************************************
函数名称: Ack_EP
功    能: 应答Setup
参    数: endp--端点索引号,取值 0 ~ 5 	   
返回值  : 无
********************************************/
void Ack_EP(uchar endp)
{
	OutB(CMD,endp);			//选择端点
	Delayus(1);
	OutB(CMD,0xF1);			//应答Setup指令
	Delayus(1);
	if(endp==0)	
	{	
		OutB(CMD,0xF2);		//清空该端点缓冲区
	}
}
/*******************************************
函数名称: Clear_buf
功    能: 清指定端点的缓冲区(包括双缓冲区)
参    数: endp--端点索引号,取值 0 ~ 5 	   
返回值  : 无
********************************************/
void Clear_buf(uchar endp)
{	
   	OutB(CMD,endp);			//选择端点
	Delayus(1);
	OutB(CMD,0xF2);			//清空第1个缓冲区	
	
	if (endp>=4)
	{
   		OutB(CMD,endp);		//选择端点
		Delayus(1);
		OutB(CMD,0xF2);		//清空第2个缓冲区	
	}
}
/*******************************************
函数名称: Stall_ep0
功    能: 使控制端点处于停止状态
参    数: 无   
返回值  : 无
********************************************/
void Stall_ep0(void)
{
	Set_EPsta(0,1);
	Set_EPsta(1,1);
}
/*******************************************
函数名称: S_trans
功    能: 通过端点索引 1 发送数据(DATA 类型)
参    数: buf--发送数据指针
		  len--发送数据长度   
返回值  : 无
********************************************/
void S_trans(uchar * buf, uchar len)
{
	if(len<=EP0_PACKET_SIZE) //长度小于EP0最大信息包大小才允许发送
	{			
		Write_EP(1,len,buf);
	}
}
/*******************************************
函数名称: Code_trans
功    能: 通过端点索引 1 发送数据(CODE类型)
参    数: buf--发送数据指针
		  len--发送数据长度   
返回值  : 无
********************************************/
void Code_trans(uchar *pRomData, uint len)
{
	ControlData.wCount = 0;								//传输字节数计数器清0
	if(ControlData.wLength > len)
		ControlData.wLength = len;						//传输数据总字节数不得超过len

	ControlData.pData = pRomData;						//传输数据指针指向pRomData
	if( ControlData.wLength >= EP0_PACKET_SIZE)         //传输数据总字节数大于端点0最大信息包大小
	{		
		Write_EP(1, EP0_PACKET_SIZE, ControlData.pData);//发送端点0最大信息包大小个字节
		ControlData.wCount += EP0_PACKET_SIZE;			//统计已发送字节数

		UEN_GINT();
		USB_FLAG.control_state = USB_TRANSMIT;	        //标志数据发送状态			
		EN_GINT();
	}
	else 
	{
		Write_EP(1, ControlData.wLength, pRomData);	    //写入传输数据总字节数
		ControlData.wCount += ControlData.wLength;	    //统计已发送字节数
		UEN_GINT();
		USB_FLAG.control_state = USB_IDLE;		        //标志空闲状态
		EN_GINT();
	}
}
/*******************************************
函数名称: USB_INT1
功    能: D12中断服务函数
参    数: 无   
返回值  : 无
********************************************/
#pragma vector=PORT1_VECTOR 
__interrupt void USB_INT1(void)
{
    uint int_sta;
          
    if((USBINT_IFG & BIT(D12_INT))==BIT(D12_INT))
    {
        USBINT_IFG&=~BIT(D12_INT);  //清除中断标志

        USB_FLAG.in_isr = 1;
        int_sta=Read_IntR();	    //读取PDIUSBD12中断寄存器值
      
        if(int_sta!=0) 
        {
                if(int_sta&INT_BUSRESET)
                        USB_FLAG.bus_reset=1;	//USB总线复位标志	
                if(int_sta&INT_ENDP0IN)
                        Ep0_txdone();		//控制端点发送数据处理
                if(int_sta&INT_ENDP0OUT)
                        Ep0_rxdone();		//控制端点接收数据处理
                if(int_sta&INT_ENDP1IN)
                        Ep1_txdone();		//端点 1发送数据处理
                if(int_sta&INT_ENDP1OUT)
                        Ep1_rxdone();		//端点 1接收数据处理
                if(int_sta&INT_ENDP2IN)
                        Ep2_txdone();		//端点 2发送数据处理
                if(int_sta&INT_ENDP2OUT)

⌨️ 快捷键说明

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