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

📄 enc28j60.s

📁 网卡控制器ENC28J60的AVR单片机ATmega16程序源代码(c),实现232toUDP功能,有非常详细的注释.
💻 S
📖 第 1 页 / 共 2 页
字号:
	.module ENC28j60.c
	.area data(ram, con, rel)
_PHY_H::
	.blkb 1
	.area idata
	.byte 0
	.area data(ram, con, rel)
	.dbfile H:\小玩意制作\232转UDP\程序\ENC28j60.c
	.dbsym e PHY_H _PHY_H c
_PHY_L::
	.blkb 1
	.area idata
	.byte 0
	.area data(ram, con, rel)
	.dbfile H:\小玩意制作\232转UDP\程序\ENC28j60.c
	.dbsym e PHY_L _PHY_L c
	.area text(rom, con, rel)
	.dbfile H:\小玩意制作\232转UDP\程序\ENC28j60.c
	.dbfunc e delay _delay fV
;              i -> R20,R21
;              k -> R16
	.even
_delay::
	xcall push_gset1
	.dbline -1
	.dbline 6
; #include "ENC28j60.h"	
; uchar PHY_H=0;
; uchar PHY_L=0;
; //################################延时程序################################//
; void delay(uchar k)//
; {uint i=0;
	.dbline 6
	clr R20
	clr R21
	xjmp L3
L2:
	.dbline 7
	.dbline 7
	clr R20
	clr R21
	xjmp L8
L5:
	.dbline 7
L6:
	.dbline 7
	subi R20,255  ; offset = 1
	sbci R21,255
L8:
	.dbline 7
	cpi R20,64
	ldi R30,31
	cpc R21,R30
	brlo L5
	.dbline 7
L3:
	.dbline 7
;  while(k--){for(i=0;i<8000;i++);}
	mov R2,R16
	clr R3
	subi R16,1
	tst R2
	brne L2
	.dbline -2
	.dbline 8
;  }
L1:
	xcall pop_gset1
	.dbline 0 ; func end
	ret
	.dbsym r i 20 i
	.dbsym r k 16 c
	.dbend
	.dbfunc e putchar _putchar fV
;              c -> R16
	.even
_putchar::
	.dbline -1
	.dbline 11
L10:
	.dbline 11
L11:
	.dbline 11
; //##########################串行通信##########################//
; void putchar(uchar c)
; {while(!(UCSRA&(1<<UDRE)));//判断上次发送有没有完成
	sbis 0xb,5
	rjmp L10
	.dbline 12
;  UDR=c;}
	out 0xc,R16
	.dbline -2
	.dbline 12
L9:
	.dbline 0 ; func end
	ret
	.dbsym r c 16 c
	.dbend
	.dbfunc e Set_CS _Set_CS fV
;          level -> R16
	.even
_Set_CS::
	.dbline -1
	.dbline 15
; //##############################选通SPI器件###############################//
; void Set_CS(uchar level)          //
; {if(level)    PORTB |=0x10;        //
	.dbline 15
	tst R16
	breq L14
	.dbline 15
	sbi 0x18,4
	xjmp L15
L14:
	.dbline 16
	in R24,0x18
	andi R24,239
	out 0x18,R24
L15:
	.dbline -2
	.dbline 17
;  else         PORTB &=0xef;        //
; }
L13:
	.dbline 0 ; func end
	ret
	.dbsym r level 16 c
	.dbend
	.dbfunc e Reset_28J60 _Reset_28J60 fV
;          clear -> R20
	.even
_Reset_28J60::
	xcall push_gset1
	.dbline -1
	.dbline 20
; //################################28J60复位#####################################
; void Reset_28J60(void)
; {uchar clear;
	.dbline 21
;  Set_CS(0);          //使能SPI器件
	clr R16
	xcall _Set_CS
	.dbline 22
;  SPDR=0xFF;		     //复位指令
	ldi R24,255
	out 0xf,R24
L17:
	.dbline 23
L18:
	.dbline 23
;  while(!(SPSR&0x80));//等待SPIF置位,等数据发送完毕
	sbis 0xe,7
	rjmp L17
	.dbline 24
;  clear=SPSR;
	in R20,0xe
	.dbline 25
;  clear=SPDR;         //通过先读SPSR,紧接着访问SPDR来对SPIF清零
	in R20,0xf
	.dbline 26
;  Set_CS(1);          //关SPI器件
	ldi R16,1
	xcall _Set_CS
	.dbline -2
	.dbline 27
; }
L16:
	xcall pop_gset1
	.dbline 0 ; func end
	ret
	.dbsym r clear 20 c
	.dbend
	.dbfunc e Read_Control_Register _Read_Control_Register fc
;          clear -> R20
;        address -> R10
;             EM -> R22
	.even
_Read_Control_Register::
	xcall push_gset3
	mov R10,R18
	mov R22,R16
	.dbline -1
	.dbline 31
; //#########################读28J60控制寄存器#################################
; uchar Read_Control_Register(uchar EM,uchar address)
; //EM=0表示读的是ETH,EM=1表示读的是MAC和MII控制寄存器
; {uchar clear;
	.dbline 32
;  Set_CS(0);          //使能SPI器件
	clr R16
	xcall _Set_CS
	.dbline 34
;  
;  SPDR=address;		 //送地址,28J60中控制寄存器读操作前3位为0后5位为地址
	out 0xf,R10
L21:
	.dbline 35
L22:
	.dbline 35
;  while(!(SPSR&0x80));//等待SPIF置位,等数据发送完毕
	sbis 0xe,7
	rjmp L21
	.dbline 36
;  clear=SPSR;
	in R20,0xe
	.dbline 37
;  clear=SPDR;         //通过先读SPSR,紧接着访问SPDR来对SPIF清零
	in R20,0xf
	.dbline 39
;  
;  SPDR=0xc0;//随便送个数以起动时钟以接收从28J60控制寄存器里传来的数据,
	ldi R24,192
	out 0xf,R24
L24:
	.dbline 41
L25:
	.dbline 41
;            //这里因为28J60中没有用到0xc0指令固先用0xc0作为随便一个数
;  while(!(SPSR&0x80));
	sbis 0xe,7
	rjmp L24
	.dbline 42
;  clear=SPSR;
	in R20,0xe
	.dbline 43
;  clear=SPDR;         //接收到控制寄存器里的数据
	in R20,0xf
	.dbline 44
;  if(EM==1){
	cpi R22,1
	brne L27
	.dbline 44
	.dbline 45
;  		   SPDR=0xc0;//随便送个数以起动时钟以接收从28J60控制寄存器里传来的数据
	ldi R24,192
	out 0xf,R24
L29:
	.dbline 46
L30:
	.dbline 46
;            while(!(SPSR&0x80));
	sbis 0xe,7
	rjmp L29
	.dbline 47
;  		   clear=SPSR;
	in R20,0xe
	.dbline 48
;  		   clear=SPDR;         //接收到控制寄存器里的数据
	in R20,0xf
	.dbline 49
;  }//因为读MAC和MII寄存器时读出来的第一个字节是无效的,因此要读两次
L27:
	.dbline 50
;  Set_CS(1);          //关SPI器件
	ldi R16,1
	xcall _Set_CS
	.dbline 51
;  return clear;
	mov R16,R20
	.dbline -2
L20:
	xcall pop_gset3
	.dbline 0 ; func end
	ret
	.dbsym r clear 20 c
	.dbsym r address 10 c
	.dbsym r EM 22 c
	.dbend
	.dbfunc e Write_Control_Register _Write_Control_Register fV
;          clear -> R20
;           date -> R22
;        address -> R20
	.even
_Write_Control_Register::
	xcall push_gset2
	mov R22,R18
	mov R20,R16
	.dbline -1
	.dbline 55
; }
; //###########################写28J60控制寄存器##################################
; void Write_Control_Register(uchar address,uchar date)   
; {uchar clear;
	.dbline 56
;  address=address+0x40;//28J60中控制寄存器写操作前3位为010后5位为地址
	subi R20,192    ; addi 64
	.dbline 57
;  Set_CS(0);           //使能SPI器件
	clr R16
	xcall _Set_CS
	.dbline 59
;  
;  SPDR=address;		  //送地址,28J60中控制寄存器写操作前3位为010后5位为地址
	out 0xf,R20
L33:
	.dbline 60
L34:
	.dbline 60
;  while(!(SPSR&0x80)); //等待SPIF置位,等数据发送完毕
	sbis 0xe,7
	rjmp L33
	.dbline 61
;  clear=SPSR;
	in R20,0xe
	.dbline 62
;  clear=SPDR;          //通过先读SPSR,紧接着访问SPDR来对SPIF清零
	in R20,0xf
	.dbline 64
;  
;  SPDR=date;
	out 0xf,R22
L36:
	.dbline 65
L37:
	.dbline 65
;  while(!(SPSR&0x80));
	sbis 0xe,7
	rjmp L36
	.dbline 66
;  clear=SPSR;
	in R20,0xe
	.dbline 67
;  clear=SPDR;         
	in R20,0xf
	.dbline 69
;  
;  Set_CS(1);          //关SPI器件
	ldi R16,1
	xcall _Set_CS
	.dbline -2
	.dbline 70
;  }
L32:
	xcall pop_gset2
	.dbline 0 ; func end
	ret
	.dbsym r clear 20 c
	.dbsym r date 22 c
	.dbsym r address 20 c
	.dbend
	.dbfunc e Read_Buffer_Memory_order _Read_Buffer_Memory_order fV
;          clear -> R20
	.even
_Read_Buffer_Memory_order::
	xcall push_gset1
	.dbline -1
	.dbline 73
; //#########################读缓冲存储器#################################
; void Read_Buffer_Memory_order(void)//送读缓冲存储器命令,连续读时用到
; {uchar clear;
	.dbline 74
;  Set_CS(0);        //使能SPI器件
	clr R16
	xcall _Set_CS
	.dbline 76
;  
;  SPDR=0x3A;		 //送命令,28J60中读缓冲存储器操作前3位为001后5位为常量11010
	ldi R24,58
	out 0xf,R24
L40:
	.dbline 77
L41:
	.dbline 77
;  while(!(SPSR&0x80));//等待SPIF置位,等数据发送完毕
	sbis 0xe,7
	rjmp L40
	.dbline 78
;  clear=SPSR;
	in R20,0xe
	.dbline 79
;  clear=SPDR;         //通过先读SPSR,紧接着访问SPDR来对SPIF清零
	in R20,0xf
	.dbline -2
	.dbline 80
; }
L39:
	xcall pop_gset1
	.dbline 0 ; func end
	ret
	.dbsym r clear 20 c
	.dbend
	.dbfunc e Read_Buffer_Memory_date _Read_Buffer_Memory_date fc
;          clear -> R16
	.even
_Read_Buffer_Memory_date::
	.dbline -1
	.dbline 82
; uchar Read_Buffer_Memory_date(void)//收到读到的数据,连续读时用到此函数
; {uchar clear;
	.dbline 83
;  SPDR=0xc0;//随便送个数以起动时钟以接收从28J60控制寄存器里传来的数据
	ldi R24,192
	out 0xf,R24
L44:
	.dbline 84
L45:
	.dbline 84
;  while(!(SPSR&0x80));
	sbis 0xe,7
	rjmp L44
	.dbline 85
;  clear=SPSR;
	in R16,0xe
	.dbline 86
;  clear=SPDR;         //接收到控制寄存器里的数据
	in R16,0xf
	.dbline 87
;  return clear;//返回读到的数据
	.dbline -2
L43:
	.dbline 0 ; func end
	ret
	.dbsym r clear 16 c
	.dbend
	.dbfunc e Read_Buffer_Memory_END _Read_Buffer_Memory_END fV
	.even
_Read_Buffer_Memory_END::
	.dbline -1
	.dbline 90
; }
; void Read_Buffer_Memory_END(void)//读结束
; {Set_CS(1);          //关SPI器件
	.dbline 90
	ldi R16,1
	.dbline -2
	.dbline 91
; }
L47:
	.dbline 0 ; func end
	xjmp _Set_CS
	.dbend
	.dbfunc e Read_Buffer_Memory _Read_Buffer_Memory fc
;          clear -> R20
	.even
_Read_Buffer_Memory::
	xcall push_gset1
	.dbline -1
	.dbline 94
; //#########################读缓冲存储器#################################
; uchar Read_Buffer_Memory(void)//只读一次,地址是由ERDPT指向的存储器中的数据将从SO脚移出
; {uchar clear;
	.dbline 95
;  Set_CS(0);        //使能SPI器件
	clr R16
	xcall _Set_CS
	.dbline 97
;  
;  SPDR=0x3A;		 //送命令,28J60中读缓冲存储器操作前3位为001后5位为常量11010
	ldi R24,58
	out 0xf,R24
L49:
	.dbline 98
L50:
	.dbline 98
;  while(!(SPSR&0x80));//等待SPIF置位,等数据发送完毕
	sbis 0xe,7
	rjmp L49
	.dbline 99
;  clear=SPSR;
	in R20,0xe
	.dbline 100
;  clear=SPDR;         //通过先读SPSR,紧接着访问SPDR来对SPIF清零
	in R20,0xf
	.dbline 102
;  
;  SPDR=0xc0;//随便送个数以起动时钟以接收从28J60控制寄存器里传来的数据
	ldi R24,192
	out 0xf,R24
L52:
	.dbline 103
L53:
	.dbline 103
;  while(!(SPSR&0x80));
	sbis 0xe,7
	rjmp L52
	.dbline 104
;  clear=SPSR;
	in R20,0xe
	.dbline 105
;  clear=SPDR;         //接收到控制寄存器里的数据
	in R20,0xf

⌨️ 快捷键说明

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