📄 usbd12.lst
字号:
(0087) All_led(FALSE); //熄灭所有的LED
013E 2700 CLR R16
013F DFC8 RCALL _All_led
(0088) Delayms(MS); //延时指定的时间
0140 2F06 MOV R16,R22
0141 2711 CLR R17
0142 DF65 RCALL _Delayms
(0089) One_led(number,FALSE); //熄灭指定的LED
0143 2722 CLR R18
0144 2F04 MOV R16,R20
0145 DF9E RCALL _One_led
(0090) } 0146 940E0760 CALL pop_gset2
0148 9508 RET
FILE: C:\icc\examples.avr\AVR_PQ1A_DEMO\20_USB\SKEY.C
(0001) /*******************************************
(0002) 文件:SKEY.C
(0003) 环境:编译为ICC AVR6.25A,仿真为AVR Studio4.10
(0004) 硬件:ATMEGA16芯片
(0005) 日期:2006年12月10日
(0006) 功能:驱动开发板上的独立按键,按下不同的键,数码管显示0-3四个数字
(0007) 备注:参考《AVR系列单片机C语言编程与应用实例》(清华大学出版社)
(0008) /******************************************/
(0009) #include <iom16v.h> //包含型号头文件
(0010) #include <macros.h> //包含"位"操作头文件
(0011) #include <stdio.h> //标准输入输出头文件
(0012)
(0013) /*******************************************
(0014) 函数名称: Skey_press
(0015) 功 能: 检测是否有键按下
(0016) 参 数: 无
(0017) 返回值 : pressed--有键按下时为TRUE,否则为FALSE
(0018) /********************************************/
(0019) uchar Skey_press(void)
(0020) {
(0021) uchar pressed;
(0022) KEY_DDR=OUT; //定义数据端口为输出
_Skey_press:
pressed --> R16
0149 EF8F LDI R24,0xFF
014A BB81 OUT P11,R24
(0023) KEY_PORTO|=0x0F; //输出数据(输出检测码)
014B B382 IN R24,P12
014C 608F ORI R24,0xF
014D BB82 OUT P12,R24
(0024) KEY_DDR=IN; //定义数据端口为输入
014E EF80 LDI R24,0xF0
014F BB81 OUT P11,R24
(0025) if((KEY_PORTI&0x0F)!=0x0F) //检测是否有键按下
0150 B380 IN R24,P10
0151 708F ANDI R24,0xF
0152 308F CPI R24,0xF
0153 F011 BEQ 0x0156
(0026) pressed=TRUE; //有键按下则返回TRUE
0154 E001 LDI R16,1
0155 C001 RJMP 0x0157
(0027) else
(0028) pressed=FALSE; //无键按下则返回FALSE
0156 2700 CLR R16
(0029) KEY_DDR=OUT; //数据端口还原为输出
0157 EF8F LDI R24,0xFF
0158 BB81 OUT P11,R24
(0030) return pressed;
0159 9508 RET
_Skey_scan:
keycode --> R20
015A 940E0758 CALL push_gset2
(0031) }
(0032) /*******************************************
(0033) 函数名称: Skey_scan
(0034) 功 能: 扫描所按的键并返回键值
(0035) 参 数: 无
(0036) 返回值 : keycode--被按下键值
(0037) /********************************************/
(0038) uchar Skey_scan(void)
(0039) {
(0040) uchar keycode=0xFF;
015C EF4F LDI R20,0xFF
(0041) Delayms(15); //延时消抖
015D E00F LDI R16,0xF
015E E010 LDI R17,0
015F DF48 RCALL _Delayms
(0042) if(Skey_press()==TRUE) //如果有键按下
0160 DFE8 RCALL _Skey_press
0161 3001 CPI R16,1
0162 F519 BNE 0x0186
(0043) {
(0044) KEY_DDR=IN; //定义数据端口为输入
0163 EF80 LDI R24,0xF0
0164 BB81 OUT P11,R24
(0045) keycode=KEY_PORTI; //读入原始键码
0165 B340 IN R20,P10
(0046) keycode&=0x0F; //屏蔽高4位
0166 704F ANDI R20,0xF
(0047) switch(keycode) //翻译原始键码为0~3
0167 2F64 MOV R22,R20
0168 2777 CLR R23
0169 3067 CPI R22,7
016A E0E0 LDI R30,0
016B 077E CPC R23,R30
016C F099 BEQ 0x0180
016D 306B CPI R22,0xB
016E E0E0 LDI R30,0
016F 077E CPC R23,R30
0170 F069 BEQ 0x017E
0171 306D CPI R22,0xD
0172 E0E0 LDI R30,0
0173 077E CPC R23,R30
0174 F039 BEQ 0x017C
0175 306E CPI R22,0xE
0176 E0E0 LDI R30,0
0177 077E CPC R23,R30
0178 F009 BEQ 0x017A
0179 C008 RJMP 0x0182
(0048) {
(0049) case 0x0E:
(0050) keycode=0;
017A 2744 CLR R20
(0051) break;
017B C007 RJMP 0x0183
(0052) case 0x0D:
(0053) keycode=1;
017C E041 LDI R20,1
(0054) break;
017D C005 RJMP 0x0183
(0055) case 0x0B:
(0056) keycode=2;
017E E042 LDI R20,2
(0057) break;
017F C003 RJMP 0x0183
(0058) case 0x07:
(0059) keycode=3;
0180 E043 LDI R20,3
(0060) break;
0181 C001 RJMP 0x0183
(0061) default:
(0062) keycode=0x00;
0182 2744 CLR R20
(0063) }
(0064) do
(0065) {
(0066) }while(Skey_press()==TRUE); //等待按键释放(为了防止按一次,执行多次的现象)
0183 DFC5 RCALL _Skey_press
0184 3001 CPI R16,1
0185 F3E9 BEQ 0x0183
(0067) }
(0068) return keycode;
0186 2F04 MOV R16,R20
0187 940E0760 CALL pop_gset2
0189 9508 RET
FILE: C:\icc\examples.avr\AVR_PQ1A_DEMO\20_USB\USBD12.C
(0001) /*******************************************
(0002) 文件:USBD12.C
(0003) 环境:编译为ICC AVR6.25A,仿真为AVR Studio4.10
(0004) 硬件:ATMEGA16芯片
(0005) 日期:2006年12月10日
(0006) 功能:驱动开发板上的USBD12
(0007) 备注:参考《PDIUSBD12USB固件编程与驱动开发》(北航出版社)
(0008) /******************************************/
(0009) #include <iom16v.h> //包含型号头文件
(0010) #include <macros.h> //包含"位"操作头文件
(0011) #include <stdio.h> //标准输入输出头文件
(0012) #include <AVR_PQ1A.h> //包含自定义常量头文件
(0013) #include "LED.C"
(0014) #include "SKEY.C"
(0015)
(0016) #pragma interrupt_handler USB_INT1:3//外部中断1中断服务函数声明
(0017) struct flags
(0018) {
(0019) uchar bus_reset ; //总线复位标志
(0020) uchar suspend ; //挂起改变标志
(0021) uchar setup_packet ; //收到SETUP包
(0022) uchar remote_wakeup ;
(0023) uchar in_isr ; //USB中断服务标志
(0024) uchar control_state ; //控制端点处理标志
(0025) //0: IDLE 空闲状态
(0026) //1: TRANSMIT 数据发送状态
(0027) //2: RECEIVE 数据接收状态
(0028) uchar configuration ; //配置标志(0: 未配置; 1: 已经配置)
(0029) uchar ep1_rxdone ; //端点 1 收到数据标志
(0030) uchar ep2_rxdone ; //端点 2 收到数据标志
(0031) uchar ep2buf_full ; //端点 2 接收双缓冲区满标志
(0032) }USB_FLAG={0,0,0,0,0,0,0,0,0,0};
(0033) typedef struct request
(0034) {
(0035) uchar bmRequestType;
(0036) uchar bRequest;
(0037) uint wValue;
(0038) uint wIndex;
(0039) uint wLength;
(0040) }DEVICE_REQUEST;
(0041) typedef struct xfer
(0042) {
(0043) DEVICE_REQUEST DeviceRequest;
(0044) uint wLength;
(0045) uint wCount;
(0046) uchar * pData;
(0047) uchar dataBuffer[MAX_CTLDAT_SIZE];
(0048) }CONTROL_XFER;
(0049) typedef struct _USB_DEVICE_DESCRIPTOR
(0050) {
(0051) uchar bLength;
(0052) uchar bDescriptorType;
(0053) uchar bcdUSB0;
(0054) uchar bcdUSB1;
(0055) uchar bDeviceClass;
(0056) uchar bDeviceSubClass;
(0057) uchar bDeviceProtocol;
(0058) uchar bMaxPacketSize0;
(0059) uchar idVendor0;
(0060) uchar idVendor1;
(0061) uchar idProduct0;
(0062) uchar idProduct1;
(0063) uchar bcdDevice0;
(0064) uchar bcdDevice1;
(0065) uchar iManufacturer;
(0066) uchar iProduct;
(0067) uchar iSerialNumber;
(0068) uchar bNumConfigurations;
(0069) } USB_DEVICE_DESCRIPTOR;
(0070) /*********** USB 接口描述符结构体 ****************/
(0071) typedef struct _USB_INTERFACE_DESCRIPTOR
(0072) {
(0073) uchar bLength;
(0074) uchar bDescriptorType;
(0075) uchar bInterfaceNumber;
(0076) uchar bAlternateSetting;
(0077) uchar bNumEndpoints;
(0078) uchar bInterfaceClass;
(0079) uchar bInterfaceSubClass;
(0080) uchar bInterfaceProtocol;
(0081) uchar iInterface;
(0082) } USB_INTERFACE_DESCRIPTOR;
(0083) /*********** USB 配置描述符结构体 ****************/
(0084) typedef struct _USB_CONFIGURATION_DESCRIPTOR
(0085) {
(0086) uchar bLength;
(0087) uchar bDescriptorType;
(0088) uchar wTotalLength0;
(0089) uchar wTotalLength1;
(0090) uchar bNumInterfaces;
(0091) uchar bConfigurationValue;
(0092) uchar iConfiguration;
(0093) uchar bmAttributes;
(0094) uchar MaxPower;
(0095) } USB_CONFIGURATION_DESCRIPTOR;
(0096) /*********** USB 端点描述符结构体 ****************/
(0097) typedef struct _USB_ENDPOINT_DESCRIPTOR
(0098) {
(0099) uchar bLength;
(0100) uchar bDescriptorType;
(0101) uchar bEndpointAddress;
(0102) uchar bmAttributes;
(0103) uchar wMaxPacketSize0;
(0104) uchar wMaxPacketSize1;
(0105) uchar bInterval;
(0106) } USB_ENDPOINT_DESCRIPTOR;
(0107) /*********** D12 USB 各种描述符结构体 *********************/
(0108) typedef struct _USB_DESCRIPTOR
(0109) {
(0110) USB_CONFIGURATION_DESCRIPTOR ConfigDescr; //配置描述符
(0111) USB_INTERFACE_DESCRIPTOR InterfaceDescr; //接口描述符
(0112) USB_ENDPOINT_DESCRIPTOR EP1_TXDescr; //端点1输入描述符
(0113) USB_ENDPOINT_DESCRIPTOR EP1_RXDescr; //端点1输出描述符
(0114) USB_ENDPOINT_DESCRIPTOR EP2_TXDescr; //端点2输入描述符
(0115) USB_ENDPOINT_DESCRIPTOR EP2_RXDescr; //端点2输出描述符
(0116) } USB_DESCRIPTOR;
(0117) CONTROL_XFER ControlData;
(0118) uchar GenEpBuf[EP1_PACKET_SIZE]; //端点1接收缓冲区
(0119) uchar EpBuf[EP2_PACKET_SIZE]; //端点2接收缓冲区
(0120) //#pragma data:code
(0121) //设备描述符
(0122) USB_DEVICE_DESCRIPTOR DeviceDescr =
(0123) {
(0124) sizeof(USB_DEVICE_DESCRIPTOR), //设备描述符长度,= 12H
(0125) USB_DEVICE_DESCRIPTOR_TYPE, //设备描述符类型,= 01H
(0126) 0x00,0x10, //协议版本,= 1.10
(0127) USB_CLASS_CODE_TEST_CLASS_DEVICE, //测试设备类型, = 0DCH
(0128) 0, 0, //设备子类,设备协议
(0129) EP0_PACKET_SIZE, //端点0最大数据包大小,= 10H
(0130) 0x71,0x04, //PHILIPS公司的设备ID
(0131) 0x66,0x06, //设备制造商定的产品ID
(0132) 0x00,0x01, //设备系列号
(0133) 0, 0, 0, //索引
(0134) 1 //可能的配置数
(0135) };
(0136) USB_DESCRIPTOR usb_descr =
(0137) {
(0138) //配置描述符
(0139) {
(0140) sizeof(USB_CONFIGURATION_DESCRIPTOR), //配置描述符长度,= 09H
(0141) USB_CONFIGURATION_DESCRIPTOR_TYPE, //配置描述符类型,= 02H
(0142) CONFIG_DESCRIPTOR_LENGTH,0x00, //描述符总长度, = 002EH
(0143) 1, //只支持1个接口
(0144) 1, //配置值
(0145) 0, //字符串描述符指针(无)
(0146) 0xa0, //自供电,支持远程唤醒
(0147) 0x32 //最大功耗(100mA)
(0148) },
(0149) //接口描述符
(0150) {
(0151) sizeof(USB_INTERFACE_DESCRIPTOR), //接口描述符长度,= 09H
(0152) USB_INTERFACE_DESCRIPTOR_TYPE, //接口描述符类型,= 04H
(0153) 0, //接口数,只有1个
(0154) 0, //可选配置,只有1个
(0155) NUM_ENDPOINTS, //除端点0的端点索引数目,= 04H
(0156) USB_CLASS_CODE_TEST_CLASS_DEVICE, //测试设备类型,= 0DCH
(0157) USB_SUBCLASS_CODE_TEST_CLASS_D12, //子类代码,= 0A0H
(0158) USB_PROTOCOL_CODE_TEST_CLASS_D12, //协议代码,= 0B0H
(0159) 0 //字符串描述符索引
(0160) },
(0161) //端点描述符,端点1输入
(0162) {
(0163) sizeof(USB_ENDPOINT_DESCRIPTOR), //端点描述符长度,= 07H
(0164) USB_ENDPOINT_DESCRIPTOR_TYPE, //端点描述符类型,= 05H
(0165) 0x81, //端点1 IN
(0166) USB_ENDPOINT_TYPE_INTERRUPT, //中断传输, = 03H
(0167) EP1_PACKET_SIZE,0x00, //端点最大包的大小,= 0010H
(0168) 10 //传输间隔时间,= 10ms
(0169) },
(0170) //端点描述符,端点1输出
(0171) {
(0172) sizeof(USB_ENDPOINT_DESCRIPTOR), //端点描述符长度,= 07H
(0173) USB_ENDPOINT_DESCRIPTOR_TYPE, //端点描述符类型,= 05H
(0174) 0x1, //端点1 OUT
(0175) USB_ENDPOINT_TYPE_INTERRUPT, //中断传输,= 03H
(0176) EP1_PACKET_SIZE,0x00, //端点最大包的大小,= 0010H
(0177) 10 //传输间隔时间,= 10ms
(0178) },
(0179) //端点2输入
(0180) {
(0181) sizeof(USB_ENDPOINT_DESCRIPTOR), //端点描述符长度,= 07H
(0182) USB_ENDPOINT_DESCRIPTOR_TYPE, //端点描述符类型,= 05H
(0183) 0x82, //端点2 OUT
(0184) USB_ENDPOINT_TYPE_BULK, //批量传输,= 02H
(0185) EP2_PACKET_SIZE,0x00, //端点最大包的大小,= 0040H
(0186) 10 //批量传输时该设备无效
(0187) },
(0188) //端点2输出
(0189) {
(0190) sizeof(USB_ENDPOINT_DESCRIPTOR), //端点描述符长度,= 07H
(0191) USB_ENDPOINT_DESCRIPTOR_TYPE, //端点描述符类型,= 05H
(0192) 0x2, //端点2 IN
(0193) USB_ENDPOINT_TYPE_BULK, //批量传输,= 02H
(0194) EP2_PACKET_SIZE,0x00, //端点最大包的大小,= 0040H
(0195) 10 //批量传输时该设备无效
(0196) }
(0197) };
(0198) //#pragma data:data
(0199) //#pragma data:code
(0200) void (*StandardDeviceRequest[])(void)=
(0201) {
(0202) Get_status,
(0203) Clr_feature,
(0204) Reserved,
(0205) Set_feature,
(0206) Reserved,
(0207) Set_addr,
(0208) Get_descriptor,
(0209) Reserved,
(0210) Get_config,
(0211) Set_config,
(0212) Get_interface,
(0213) Set_interface,
(0214) Reserved,
(0215) Reserved,
(0216) Reserved,
(0217) Reserved
(0218) };
(0219) //#pragma data:data
(0220) /*******************************************
(0221) 函数名称: D12_init
(0222) 功 能: 初始化D12接口(包括数据接口和控制接口)
(0223) 参 数: 无
(0224) 返回值 : 无
(0225) /********************************************/
(0226) void D12_init(void)
(0227) {
(0228) DDRA|=BIT(CSUSB); //USB的573锁存端设置为输出
_D12_init:
018A 9AD7 SBI P1A,7
(0229) PORTA&=~BIT(CSUSB); //573锁存端关闭
018B 98DF CBI P1B,7
(0230) USBDAT_DDR|=0xFF; //数据端口设置为输出
018C B387 IN R24,P17
018D 6F8F ORI R24,0xFF
018E BB87 OUT P17,R24
(0231) USBCTL_DDR|=BIT(WR_N)|BIT(RD_N)|BIT(C_D)|BIT(D12_CS);//控制引脚设置为输出
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -