📄 usbfunctions.c
字号:
#include <msp430x14x.h>
#include "USBvariables.h"
#include "USBfunctions.h"
typedef unsigned char uchar;
typedef unsigned int uint;
//外部变量声明
extern unsigned char KeyChar; //按键输入数值
extern unsigned char SendFlag; //是否发送数据标志
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)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -