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

📄 main.lss

📁 CH375官方有了51单片机控制打印机的代码
💻 LSS
📖 第 1 页 / 共 5 页
字号:
{
	__asm__ volatile (
 180:	87 e0       	ldi	r24, 0x07	; 7
 182:	8a 95       	dec	r24
 184:	f1 f7       	brne	.-4      	; 0x182 <toggle_recv+0x1a>
 186:	1f 91       	pop	r17
 188:	08 95       	ret

0000018a <toggle_send>:
	delay2us();
}

void toggle_send( BOOL1 tog ) {  // 主机发送同步控制:0=DATA0,1=DATA1 
 18a:	1f 93       	push	r17
 18c:	18 2f       	mov	r17, r24
	xWriteCH375Cmd( CMD_SET_ENDP7 );
 18e:	8d e1       	ldi	r24, 0x1D	; 29
 190:	0e 94 65 00 	call	0xca	; 0xca <xWriteCH375Cmd>
	xWriteCH375Data( tog ? 0xC0 : 0x80 );
 194:	11 23       	and	r17, r17
 196:	11 f0       	breq	.+4      	; 0x19c <toggle_send+0x12>
 198:	80 ec       	ldi	r24, 0xC0	; 192
 19a:	01 c0       	rjmp	.+2      	; 0x19e <toggle_send+0x14>
 19c:	80 e8       	ldi	r24, 0x80	; 128
 19e:	0e 94 74 00 	call	0xe8	; 0xe8 <xWriteCH375Data>
*/
void
_delay_loop_1(uint8_t __count)
{
	__asm__ volatile (
 1a2:	87 e0       	ldi	r24, 0x07	; 7
 1a4:	8a 95       	dec	r24
 1a6:	f1 f7       	brne	.-4      	; 0x1a4 <toggle_send+0x1a>
 1a8:	1f 91       	pop	r17
 1aa:	08 95       	ret

000001ac <clr_stall>:
	delay2us();
}

unsigned char clr_stall( unsigned char endp_addr ) {  // USB通讯失败后,复位设备端的指定端点到DATA0
 1ac:	1f 93       	push	r17
 1ae:	18 2f       	mov	r17, r24
	xWriteCH375Cmd( CMD_CLR_STALL );
 1b0:	81 e4       	ldi	r24, 0x41	; 65
 1b2:	0e 94 65 00 	call	0xca	; 0xca <xWriteCH375Cmd>
	xWriteCH375Data( endp_addr );
 1b6:	81 2f       	mov	r24, r17
 1b8:	0e 94 74 00 	call	0xe8	; 0xe8 <xWriteCH375Data>
	return( wait_interrupt() );
 1bc:	0e 94 90 00 	call	0x120	; 0x120 <wait_interrupt>
}
 1c0:	99 27       	eor	r25, r25
 1c2:	1f 91       	pop	r17
 1c4:	08 95       	ret

000001c6 <rd_usb_data>:

// 数据读写, 单片机读写CH375芯片中的数据缓冲区

unsigned char rd_usb_data( unsigned char *buf ) {  // 从CH37X读出数据块 
 1c6:	0f 93       	push	r16
 1c8:	1f 93       	push	r17
 1ca:	cf 93       	push	r28
 1cc:	df 93       	push	r29
 1ce:	ec 01       	movw	r28, r24
	unsigned char i, len;
	xWriteCH375Cmd( CMD_RD_USB_DATA );  // 从CH375的端点缓冲区读取接收到的数据 
 1d0:	88 e2       	ldi	r24, 0x28	; 40
 1d2:	0e 94 65 00 	call	0xca	; 0xca <xWriteCH375Cmd>
	len=xReadCH375Data();  // 后续数据长度 
 1d6:	0e 94 83 00 	call	0x106	; 0x106 <xReadCH375Data>
 1da:	08 2f       	mov	r16, r24
	for ( i=0; i!=len; i++ ) *buf++=xReadCH375Data();
 1dc:	88 23       	and	r24, r24
 1de:	39 f0       	breq	.+14     	; 0x1ee <rd_usb_data+0x28>
 1e0:	10 e0       	ldi	r17, 0x00	; 0
 1e2:	0e 94 83 00 	call	0x106	; 0x106 <xReadCH375Data>
 1e6:	89 93       	st	Y+, r24
 1e8:	1f 5f       	subi	r17, 0xFF	; 255
 1ea:	01 17       	cp	r16, r17
 1ec:	d1 f7       	brne	.-12     	; 0x1e2 <rd_usb_data+0x1c>
	return( len );
}
 1ee:	80 2f       	mov	r24, r16
 1f0:	99 27       	eor	r25, r25
 1f2:	df 91       	pop	r29
 1f4:	cf 91       	pop	r28
 1f6:	1f 91       	pop	r17
 1f8:	0f 91       	pop	r16
 1fa:	08 95       	ret

000001fc <wr_usb_data>:

void wr_usb_data( unsigned char len, unsigned char *buf ) {  // 向CH37X写入数据块
 1fc:	1f 93       	push	r17
 1fe:	cf 93       	push	r28
 200:	df 93       	push	r29
 202:	18 2f       	mov	r17, r24
 204:	eb 01       	movw	r28, r22
	xWriteCH375Cmd( CMD_WR_USB_DATA7 );  // 向CH375的端点缓冲区写入准备发送的数据
 206:	8b e2       	ldi	r24, 0x2B	; 43
 208:	0e 94 65 00 	call	0xca	; 0xca <xWriteCH375Cmd>
	xWriteCH375Data( len );  // 后续数据长度, len不能大于64
 20c:	81 2f       	mov	r24, r17
 20e:	0e 94 74 00 	call	0xe8	; 0xe8 <xWriteCH375Data>
	while( len-- ) xWriteCH375Data( *buf++ );
 212:	11 50       	subi	r17, 0x01	; 1
 214:	1f 3f       	cpi	r17, 0xFF	; 255
 216:	29 f0       	breq	.+10     	; 0x222 <wr_usb_data+0x26>
 218:	89 91       	ld	r24, Y+
 21a:	0e 94 74 00 	call	0xe8	; 0xe8 <xWriteCH375Data>
 21e:	11 50       	subi	r17, 0x01	; 1
 220:	d8 f7       	brcc	.-10     	; 0x218 <wr_usb_data+0x1c>
 222:	df 91       	pop	r29
 224:	cf 91       	pop	r28
 226:	1f 91       	pop	r17
 228:	08 95       	ret

0000022a <issue_token>:
}

// 主机操作
unsigned char endp_out_addr;	// 打印机数据接收端点的端点地址
unsigned char endp_out_size;	// 打印机数据接收端点的端点尺寸
BOOL1	tog_send;				// 打印机数据接收端点的同步标志
unsigned char endp_in_addr;	// 双向打印机发送端点的端点地址,一般不用
BOOL1	tog_recv;				// 双向打印机发送端点的同步标志,一般不用

unsigned char issue_token( unsigned char endp_and_pid ) {  // 执行USB事务 
 22a:	1f 93       	push	r17
 22c:	18 2f       	mov	r17, r24
// 执行完成后, 将产生中断通知单片机, 如果是USB_INT_SUCCESS就说明操作成功 
	xWriteCH375Cmd( CMD_ISSUE_TOKEN );
 22e:	8f e4       	ldi	r24, 0x4F	; 79
 230:	0e 94 65 00 	call	0xca	; 0xca <xWriteCH375Cmd>
	xWriteCH375Data( endp_and_pid );  // 高4位目的端点号, 低4位令牌PID
 234:	81 2f       	mov	r24, r17
 236:	0e 94 74 00 	call	0xe8	; 0xe8 <xWriteCH375Data>
	return( wait_interrupt() );  // 等待CH375操作完成
 23a:	0e 94 90 00 	call	0x120	; 0x120 <wait_interrupt>
}
 23e:	99 27       	eor	r25, r25
 240:	1f 91       	pop	r17
 242:	08 95       	ret

00000244 <issue_token_X>:

unsigned char issue_token_X( unsigned char endp_and_pid, unsigned char tog ) {  // 执行USB事务,适用于CH375A 
 244:	0f 93       	push	r16
 246:	1f 93       	push	r17
 248:	08 2f       	mov	r16, r24
 24a:	16 2f       	mov	r17, r22
// 执行完成后, 将产生中断通知单片机, 如果是USB_INT_SUCCESS就说明操作成功 
	xWriteCH375Cmd( CMD_ISSUE_TKN_X );
 24c:	8e e4       	ldi	r24, 0x4E	; 78
 24e:	0e 94 65 00 	call	0xca	; 0xca <xWriteCH375Cmd>
	xWriteCH375Data( tog );  // 同步标志的位7为主机端点IN的同步触发位, 位6为主机端点OUT的同步触发位, 位5~位0必须为0 
 252:	81 2f       	mov	r24, r17
 254:	0e 94 74 00 	call	0xe8	; 0xe8 <xWriteCH375Data>
	xWriteCH375Data( endp_and_pid );  // 高4位目的端点号, 低4位令牌PID 
 258:	80 2f       	mov	r24, r16
 25a:	0e 94 74 00 	call	0xe8	; 0xe8 <xWriteCH375Data>
	return( wait_interrupt() );  // 等待CH375操作完成 
 25e:	0e 94 90 00 	call	0x120	; 0x120 <wait_interrupt>
}
 262:	99 27       	eor	r25, r25
 264:	1f 91       	pop	r17
 266:	0f 91       	pop	r16
 268:	08 95       	ret

0000026a <soft_reset_print>:

void soft_reset_print( void ) {  // 控制传输:软复位打印机 
 26a:	10 92 76 01 	sts	0x0176, r1
 26e:	10 92 b9 01 	sts	0x01B9, r1
	tog_send=tog_recv=0;  // 复位USB数据同步标志 
	toggle_send( 0 );  // SETUP阶段为DATA0 
 272:	80 e0       	ldi	r24, 0x00	; 0
 274:	0e 94 c5 00 	call	0x18a	; 0x18a <toggle_send>
	buffer[0]=0x21; buffer[1]=2; buffer[2]=buffer[3]=buffer[4]=buffer[5]=buffer[6]=buffer[7]=0;  // SETUP数据,SOFT_RESET 
 278:	81 e2       	ldi	r24, 0x21	; 33
 27a:	80 93 78 01 	sts	0x0178, r24
 27e:	82 e0       	ldi	r24, 0x02	; 2
 280:	80 93 79 01 	sts	0x0179, r24
 284:	10 92 7f 01 	sts	0x017F, r1
 288:	10 92 7e 01 	sts	0x017E, r1
 28c:	10 92 7d 01 	sts	0x017D, r1
 290:	10 92 7c 01 	sts	0x017C, r1
 294:	10 92 7b 01 	sts	0x017B, r1
 298:	10 92 7a 01 	sts	0x017A, r1
	wr_usb_data( 8, buffer );  // SETUP数据总是8字节 
 29c:	68 e7       	ldi	r22, 0x78	; 120
 29e:	71 e0       	ldi	r23, 0x01	; 1
 2a0:	88 e0       	ldi	r24, 0x08	; 8
 2a2:	0e 94 fe 00 	call	0x1fc	; 0x1fc <wr_usb_data>
	if ( issue_token( ( 0 << 4 ) | DEF_USB_PID_SETUP )==USB_INT_SUCCESS ) {  // SETUP阶段操作成功 
 2a6:	8d e0       	ldi	r24, 0x0D	; 13
 2a8:	0e 94 15 01 	call	0x22a	; 0x22a <issue_token>
 2ac:	84 31       	cpi	r24, 0x14	; 20
 2ae:	09 f0       	breq	.+2      	; 0x2b2 <soft_reset_print+0x48>
 2b0:	08 95       	ret
		toggle_recv( 1 );  // STATUS阶段,准备接收DATA1 
 2b2:	81 e0       	ldi	r24, 0x01	; 1
 2b4:	0e 94 b4 00 	call	0x168	; 0x168 <toggle_recv>
		if ( issue_token( ( 0 << 4 ) | DEF_USB_PID_IN )==USB_INT_SUCCESS ) return;  // STATUS阶段操作成功,操作成功返回 
 2b8:	89 e0       	ldi	r24, 0x09	; 9
 2ba:	0e 94 15 01 	call	0x22a	; 0x22a <issue_token>
 2be:	08 95       	ret

000002c0 <send_data>:
	}
}

#define	USB_INT_RET_NAK		0x2A		// 00101010B,返回NAK 
void send_data( unsigned short len, unsigned char *buf ) {  // 主机发送数据块,一次最多64KB 
 2c0:	ff 92       	push	r15
 2c2:	0f 93       	push	r16
 2c4:	1f 93       	push	r17
 2c6:	cf 93       	push	r28
 2c8:	df 93       	push	r29
 2ca:	ec 01       	movw	r28, r24
 2cc:	8b 01       	movw	r16, r22
	unsigned char l, s;
	while( len ) {  // 连续输出数据块给USB打印机 
 2ce:	89 2b       	or	r24, r25
 2d0:	59 f4       	brne	.+22     	; 0x2e8 <send_data+0x28>
 2d2:	2f c0       	rjmp	.+94     	; 0x332 <send_data+0x72>
		toggle_send( tog_send );  // 数据同步 
		l = len>endp_out_size?endp_out_size:len;  // 单次发送不能超过端点尺寸 
		wr_usb_data( l, buf );  // 将数据先复制到CH375芯片中 
		s = issue_token( ( endp_out_addr << 4 ) | DEF_USB_PID_OUT );  // 请求CH375输出数据 
		if ( s==USB_INT_SUCCESS ) {  // CH375成功发出数据 
			tog_send = ~ tog_send;  // 切换DATA0和DATA1进行数据同步 
			len-=l;  // 计数 
			buf+=l;  // 操作成功 
		}
		else if ( s==USB_INT_RET_NAK ) {  // USB打印机正忙,如果未执行SET_RETRY命令则CH375自动重试,所以不会返回USB_INT_RET_NAK状态 
 2d4:	8a 32       	cpi	r24, 0x2A	; 42
 2d6:	31 f0       	breq	.+12     	; 0x2e4 <send_data+0x24>
			// USB打印机正忙,正常情况下应该稍后重试 
			// s=get_port_status( );  如果有必要,可以检查是什么原因导致打印机忙 
		}
		else {  // 操作失败,正常情况下不会失败 
			clr_stall( endp_out_addr );  // 清除打印机的数据接收端点,或者 soft_reset_print() 
 2d8:	80 91 77 01 	lds	r24, 0x0177
 2dc:	0e 94 d6 00 	call	0x1ac	; 0x1ac <clr_stall>
//			soft_reset_print();  打印机出现意外错误,软复位 
			tog_send = 0;  // 操作失败 
 2e0:	10 92 b9 01 	sts	0x01B9, r1
 2e4:	20 97       	sbiw	r28, 0x00	; 0
 2e6:	29 f1       	breq	.+74     	; 0x332 <send_data+0x72>
 2e8:	80 91 b9 01 	lds	r24, 0x01B9
 2ec:	0e 94 c5 00 	call	0x18a	; 0x18a <toggle_send>
 2f0:	80 91 ba 01 	lds	r24, 0x01BA
 2f4:	99 27       	eor	r25, r25
 2f6:	c8 17       	cp	r28, r24
 2f8:	d9 07       	cpc	r29, r25
 2fa:	08 f4       	brcc	.+2      	; 0x2fe <send_data+0x3e>
 2fc:	ce 01       	movw	r24, r28
 2fe:	f8 2e       	mov	r15, r24
 300:	b8 01       	movw	r22, r16
 302:	0e 94 fe 00 	call	0x1fc	; 0x1fc <wr_usb_data>
 306:	80 91 77 01 	lds	r24, 0x0177
 30a:	82 95       	swap	r24
 30c:	80 7f       	andi	r24, 0xF0	; 240
 30e:	81 60       	ori	r24, 0x01	; 1
 310:	0e 94 15 01 	call	0x22a	; 0x22a <issue_token>
 314:	84 31       	cpi	r24, 0x14	; 20
 316:	f1 f6       	brne	.-68     	; 0x2d4 <send_data+0x14>
 318:	80 91 b9 01 	lds	r24, 0x01B9
 31c:	80 95       	com	r24
 31e:	80 93 b9 01 	sts	0x01B9, r24
 322:	8f 2d       	mov	r24, r15
 324:	99 27       	eor	r25, r25
 326:	c8 1b       	sub	r28, r24
 328:	d9 0b       	sbc	r29, r25
 32a:	08 0f       	add	r16, r24
 32c:	19 1f       	adc	r17, r25
 32e:	20 97       	sbiw	r28, 0x00	; 0
 330:	d9 f6       	brne	.-74     	; 0x2e8 <send_data+0x28>
 332:	df 91       	pop	r29
 334:	cf 91       	pop	r28
 336:	1f 91       	pop	r17
 338:	0f 91       	pop	r16
 33a:	ff 90       	pop	r15
 33c:	08 95       	ret

0000033e <get_port_status>:
		}
// 如果数据量较大,可以定期调用get_port_status()检查打印机状态 
	}
}

unsigned char get_port_status( void ) {  // 查询打印机端口状态,返回状态码,如果为0FFH则说明操作失败 
 33e:	80 e0       	ldi	r24, 0x00	; 0
 340:	0e 94 c5 00 	call	0x18a	; 0x18a <toggle_send>
// 返回状态码中: 位5(Paper Empty)为1说明无纸, 位4(Select)为1说明打印机联机, 位3(Not Error)为0说明打印机出错 
	toggle_send( 0 );  // 下面通过控制传输获取打印机的状态, SETUP阶段为DATA0 
	buffer[0]=0xA1; buffer[1]=1; buffer[2]=buffer[3]=buffer[4]=buffer[5]=0; buffer[6]=1; buffer[7]=0;  // SETUP数据,GET_PORT_STATUS 
 344:	81 ea       	ldi	r24, 0xA1	; 161
 346:	80 93 78 01 	sts	0x0178, r24
 34a:	81 e0       	ldi	r24, 0x01	; 1
 34c:	80 93 79 01 	sts	0x0179, r24
 350:	10 92 7d 01 	sts	0x017D, r1
 354:	10 92 7c 01 	sts	0x017C, r1
 358:	10 92 7b 01 	sts	0x017B, r1
 35c:	10 92 7a 01 	sts	0x017A, r1
 360:	80 93 7e 01 	sts	0x017E, r24
 364:	10 92 7f 01 	sts	0x017F, r1
	wr_usb_data( 8, buffer );  // SETUP数据总是8字节 
 368:	68 e7       	ldi	r22, 0x78	; 120
 36a:	71 e0       	ldi	r23, 0x01	; 1
 36c:	88 e0       	ldi	r24, 0x08	; 8
 36e:	0e 94 fe 00 	call	0x1fc	; 0x1fc <wr_usb_data>
	if ( issue_token( ( 0 << 4 ) | DEF_USB_PID_SETUP )==USB_INT_SUCCESS ) {  // SETUP阶段操作成功 
 372:	8d e0       	ldi	r24, 0x0D	; 13
 374:	0e 94 15 01 	call	0x22a	; 0x22a <issue_token>
 378:	84 31       	cpi	r24, 0x14	; 20
 37a:	c9 f4       	brne	.+50     	; 0x3ae <get_port_status+0x70>
		toggle_recv( 1 );  // DATA阶段,准备接收DATA1 

⌨️ 快捷键说明

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