📄 success6.c
字号:
#include <reg52.h>
#include <absacc.h>
#include <intrins.h>
#include <D12.h>
unsigned char xdata GenEpBuf[EP1_PACKET_SIZE];
unsigned char EpBufL[8]={11,22,33,44,55,66,77,88};
// 能设置地址了
void outportb(unsigned int Addr, unsigned char Data) // 输出数据
{
*((unsigned char xdata *) Addr) = Data;
}
unsigned char inportb(unsigned int Addr) // 输入数据
{
return *((unsigned char xdata *) Addr);
}
void delay(unsigned int cnt) // 延时函数,11.0592的晶振,产生13*cnt+20us 的延时
{
unsigned int i;
for(i=0;i<cnt;i++);
}
void serial_output(unsigned char temp) // 串口输出程序
{
SBUF=temp;
while(TI==0);
TI=0;
}
void D12_SetMode(unsigned char bConfig, unsigned char bClkDiv) //模式设置
{
outportb(D12_COMMAND, 0xF3); // 设置模式,后面跟2字节数据
outportb(D12_DATA, bConfig); // 第一个字节包含配置字节信息
outportb(D12_DATA, bClkDiv); // 第二个字节包含时钟分频因子信息
}
void D12_SetEndpointStatus(unsigned char bEndp, unsigned char bStalled)
{
outportb(D12_COMMAND, 0x40 + bEndp);//设置端点状态
outportb(D12_DATA, bStalled);
}
void D12_AcknowledgeEndpoint(unsigned char endp) // 设置端点应答
{
outportb(D12_COMMAND, endp); // 选择端点
outportb(D12_COMMAND, 0xF1); // 设置应答
if(endp == 0)
outportb(D12_COMMAND, 0xF2);
}
unsigned short D12_ReadInterruptRegister(void) // 读取中断寄存器
{
unsigned char b1;
unsigned int j;
outportb(D12_COMMAND, 0xF4); // 读取中断寄存器命令
b1 = inportb(D12_DATA);
j = inportb(D12_DATA);
j <<= 8;
j += b1;
return j;
}
void D12_SetAddressEnable(unsigned char bAddress, unsigned char bEnable) // 设置地址/使能
{ // 地址 使能该功能
outportb(D12_COMMAND, 0xD0); // 输出指令
if(bEnable)
bAddress |= 0x80;
outportb(D12_DATA, bAddress); // 设置地址
}
void D12_SetEndpointEnable(unsigned char bEnable) // 设置端点使能
{
outportb(D12_COMMAND, 0xD8); // 输出指令
if(bEnable)
outportb(D12_DATA, 1); // 设置端点允许
else
outportb(D12_DATA, 0); // 设置端点禁止
}
unsigned short D12_ReadChipID(void) // 读芯片ID
{
unsigned short i,j;
outportb(D12_COMMAND, 0xFD);
i=inportb(D12_DATA);
j=inportb(D12_DATA);
i += (j<<8);
return i;
}
unsigned char D12_ReadLastTransactionStatus(unsigned char bEndp) // 读取最后处理状态
{
outportb(D12_COMMAND, 0x40 + bEndp);//返回最后传输状态
return inportb(D12_DATA);
}
unsigned char D12_ReadEndpoint(unsigned char endp, unsigned char len, unsigned char * buf) // 读取端点数据
{ // 返回数据的长度
unsigned char i, j;
outportb(D12_COMMAND, endp); // 选择管道
if((inportb(D12_DATA) & D12_FULLEMPTY) == 0) // 缓冲区空
{
return 0;
}
// 缓冲区有内容
outportb(D12_COMMAND, 0xF0); // 读缓冲区
j = inportb(D12_DATA); // 第一字节无意义
j = inportb(D12_DATA); // 第二字节是数据字节的长度
if(j > len)
j = len;
for(i=0; i<j; i++)
*(buf+i) = inportb(D12_DATA);
outportb(D12_COMMAND, 0xF2); // 缓冲区清零
return j;
}
unsigned char D12_WriteEndpoint(unsigned char endp, unsigned char len, unsigned char * buf) // 写端点
{ // 返回数据的长度
unsigned char i;
outportb(D12_COMMAND, endp); // 选管道
i = inportb(D12_DATA);
outportb(D12_COMMAND, 0xF0); // 写缓冲区
outportb(D12_DATA, 0); // 第一字节保留,为0
outportb(D12_DATA, len); // 第二字节为数据字节长度
for(i=0; i<len; i++)
outportb(D12_DATA, *(buf+i)); // 写入数据
outportb(D12_COMMAND, 0xFA); // 使缓冲区有效
return len;
}
/*unsigned char D12_ReadEndpointStatus(unsigned char bEndp) // 读取端点状态
{
unsigned char xdata c;
outportb(D12_COMMAND, 0x80 + bEndp); // 读取端点状态
c = inportb(D12_DATA);
return c;
}*/
void stall_ep0(void)
{
D12_SetEndpointStatus(0, 1);
D12_SetEndpointStatus(1, 1);
}
/*******************************************************************************************************/
void disconnect_USB(void) // 断开USB总线
{
// Initialize D12 configuration
D12_SetMode(D12_NOLAZYCLOCK,D12_CLOCK_12M);
}
void connect_USB(void) // 连接USB总线
{
// Initialize D12 configuration
D12_SetMode(D12_NOLAZYCLOCK|D12_SOFTCONNECT, D12_CLOCK_12M);
}
void reconnect_USB(void) //重新连接到USB总线
{
// SUSPEND = 0;
disconnect_USB();
delay(191); // 2.5ms
delay(191); // 2.5ms
delay(191); // 2.5ms
delay(191); // 2.5ms
D12_SetAddressEnable(0,1); // 设置地址0使能
D12_SetEndpointEnable(1); // 设置端点使能
connect_USB();
}
void init_MCS51(void) // I/O口初始化程序
{
P1 = 0xFF;
P3 = 0xFF;
D12SUSPD = 0; // 挂起为低电平
SCON = 0x40; // 串口工作方式1,8位UART
PCON = 0x00; // 波特率不加倍
TMOD = 0x20; // T1工作方式2,8位可自动重载
TH1 = 0xfd; // 11.0592M晶振下波特率9600
TL1 = 0xfd;
IT1 = 0; // 外部中断1为电平触发方式,低电平有效
EX1 = 1; // 允许外部中断1
}
void init_unconfig(void) // 恢复到未配置状态
{
D12_SetEndpointEnable(0); /* Disable all endpoints but EPP0. */
}
void init_config(void) // 设置配置状态
{
D12_SetEndpointEnable(1); /* Enable generic/iso endpoints. */
}
void single_transmit(unsigned char * buf, unsigned char len) // 从端点号1发送数据
{
if( len <= EP0_PACKET_SIZE)
{
D12_WriteEndpoint(1, len, buf);
}
}
void code_transmit(unsigned char code * pRomData, unsigned short len) // 发送端点号1建立代码
{
ControlData.wCount = 0;
if(ControlData.wLength > len)
ControlData.wLength = len;
ControlData.pData = pRomData;
if( ControlData.wLength >= EP0_PACKET_SIZE)
{
D12_WriteEndpoint(1, EP0_PACKET_SIZE, ControlData.pData); // 发送16字节数据
ControlData.wCount += EP0_PACKET_SIZE;
// DISABLE;
bEPPflags.bits.control_state = USB_TRANSMIT;
// ENABLE;
}
else
{
D12_WriteEndpoint(1, ControlData.wLength, pRomData); // 发送16字节内数据
ControlData.wCount += ControlData.wLength;
// DISABLE;
bEPPflags.bits.control_state = USB_IDLE;
// ENABLE;
}
}
void set_address(void) // 为设备设置一个唯一的地址
{
D12_SetAddressEnable((unsigned char)(ControlData.DeviceRequest.wValue & 0x7F), 1);
single_transmit(0, 0);
}
void get_descriptor(void) // 获得设备的某种描述符
{
unsigned char bDescriptor = MSB(ControlData.DeviceRequest.wValue); // 取wValue的高8位
switch(bDescriptor)
{
case DEVICE_DESCRIPTOR_TYPE : // 获取设备描述符
code_transmit((unsigned char code *)&DeviceDescr, DEVICE_DESCRIPTOR_SIZE);
break;
case CONFIGURATION_DESCRIPTOR_TYPE : // 获取配置描述符
code_transmit((unsigned char code *)&ConfigDescr, TOTAL_CONFIG_SIZE);break;
default :stall_ep0();
}
}
void get_configuration(void) // 获得指定设备的当前配置的值
{
unsigned char xdata c = bEPPflags.bits.configuration;
single_transmit(&c, 1);
}
void set_configuration(void) // 激活设备的某个配置
{
if (ControlData.DeviceRequest.wValue == 0)
{
//设备进入未配置状态
single_transmit(0, 0);
bEPPflags.bits.configuration = 0;
init_unconfig();
}
else if (ControlData.DeviceRequest.wValue == 1)
{
//配置设备
single_transmit(0, 0);
init_unconfig();
init_config();
bEPPflags.bits.configuration = 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -