📄 d12ci.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 + -