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

📄 spi.s

📁 mp3代码 要用的干净下啊 希望用东西共享啊
💻 S
字号:
	.module spi.c
	.area data(ram, con, rel)
_Spi_Receive_Buffer::
	.blkb 1
	.area idata
	.byte 0
	.area data(ram, con, rel)
	.blkb 1
	.area idata
	.byte 0
	.area data(ram, con, rel)
	.blkb 1
	.area idata
	.byte 0
	.area data(ram, con, rel)
	.blkw 1
	.area idata
	.word _Spi_Receive_Data
	.area data(ram, con, rel)
	.blkb 1
	.area idata
	.byte 255
	.area data(ram, con, rel)
	.blkb 1
	.area idata
	.byte 0
	.area data(ram, con, rel)
	.blkb 1
	.area idata
	.byte 0
	.area data(ram, con, rel)
	.blkb 1
	.area idata
	.byte 0
	.area data(ram, con, rel)
	.dbfile D:\桌面\mp3\SPI\spi.c
	.dbstruct 0 9 .1
	.dbfield 0 front c
	.dbfield 1 rear c
	.dbfield 2 count c
	.dbfield 3 data pc
	.dbfield 5 queuesize c
	.dbfield 6 errorcode c
	.dbfield 7 status c
	.dbfield 8 memo c
	.dbend
	.dbsym e Spi_Receive_Buffer _Spi_Receive_Buffer S[.1]
_Spi_Send_Buffer::
	.blkb 1
	.area idata
	.byte 0
	.area data(ram, con, rel)
	.dbfile D:\桌面\mp3\SPI\spi.c
	.blkb 1
	.area idata
	.byte 0
	.area data(ram, con, rel)
	.dbfile D:\桌面\mp3\SPI\spi.c
	.blkb 1
	.area idata
	.byte 0
	.area data(ram, con, rel)
	.dbfile D:\桌面\mp3\SPI\spi.c
	.blkw 1
	.area idata
	.word _Spi_Send_Data
	.area data(ram, con, rel)
	.dbfile D:\桌面\mp3\SPI\spi.c
	.blkb 1
	.area idata
	.byte 10
	.area data(ram, con, rel)
	.dbfile D:\桌面\mp3\SPI\spi.c
	.blkb 1
	.area idata
	.byte 0
	.area data(ram, con, rel)
	.dbfile D:\桌面\mp3\SPI\spi.c
	.blkb 1
	.area idata
	.byte 0
	.area data(ram, con, rel)
	.dbfile D:\桌面\mp3\SPI\spi.c
	.blkb 1
	.area idata
	.byte 0
	.area data(ram, con, rel)
	.dbfile D:\桌面\mp3\SPI\spi.c
	.dbsym e Spi_Send_Buffer _Spi_Send_Buffer S[.1]
	.area vector(rom, abs)
	.org 48
	jmp _spi_stc_isr
	.area data(ram, con, rel)
	.dbfile D:\桌面\mp3\SPI\spi.c
	.area text(rom, con, rel)
	.dbfile D:\桌面\mp3\SPI\spi.c
	.dbfunc e spi_stc_isr _spi_stc_isr fV
	.even
_spi_stc_isr::
	xcall push_lset
	.dbline -1
	.dbline 63
; /*********************************************************************************************************
; **				          			       SPI 驱动程序
; **                                  (c) Copyright 2006-2008, limaokui
; **                                           All Rights Reserved
; **
; **                                             V1.0.0
; **
; **
; **--------------文件信息--------------------------------------------------------------------------------
; **文   件   名:SPI.c
; **创   建   人: 李茂奎
; **最后修改日期:  2006年9月2日
; **描        述:  SPI驱动程序
; **
; **--------------历史版本信息----------------------------------------------------------------------------
; ** 创建人: 李茂奎
; ** 版  本: V1.00
; ** 日 期: 2006年9月2日
; ** 描 述: 原始版本
; **
; **------------------------------------------------------------------------------------------------------
; ** 修改人: 李茂奎
; ** 版  本:
; ** 日 期:
; ** 描 述: 
; **
; **--------------当前版本修订------------------------------------------------------------------------------
; ** 修改人:    李茂奎																					  
; ** 日 期:	 2006年9月2日
; ** 描 述:   
; **
; **------------------------------------------------------------------------------------------------------
; *********************************************************************************************************/
; /*
; ATmega128的SPI采用硬件方式实现面向字节的全双工3线同步通信,
; 支持主机、从机和2种不同极性的SPI时序,通信速率有7种选择,
; 主机方式的最高速率为1/2系统时钟,从机方式最高速率为1/4系统时钟。
; 
; AVR的SPI由一个16位的循环移位寄存器构成,当数据从主机方移出时,从机的数据同时也被移入,
; 因此SPI的发送和接收在一个中断服务中完成。
; 在SPI中断服务程序中,先从SPDR中读一个接收的字节存入接收数据缓冲器中,再从发送数据缓冲
; 器取出一个字节写入SPDR中,由SPI发送到从机。
; 数据一旦写入SPDR,ISP硬件开始发送数据。
; 下一次ISP中断时,表示发送完成,并同时收到一个数据。
; SPI为硬件接口和传输完成中断申请,所以使用SPI传输数据的有效方法是采用中断方式+数据缓存器的设计方法。
; 
; 在对SPI初始化时,应注意以下几点: 
; .正确选择和设置主机或从机,以及工作模式(极性),数据传输率; 
; .注意传送字节的顺序,是低位优先(LSB First)还是高位优先(MSB Frist); 
; .正确设置MOSI和MISO接口的输入输出方向,输入引脚使用上拉电阻,可以节省总线上的吊高电阻。 
; 
; 
; */
; #include "config.h"
; 
; static uint8 Spi_Receive_Data[SPI_RECEIVE_DATA_BUFFER_SIZE];
; static uint8 Spi_Send_Data[SPI_SEND_DATA_BUFFER_SIZE];
; CirQueue Spi_Receive_Buffer={0,0,0,Spi_Receive_Data,SPI_RECEIVE_DATA_BUFFER_SIZE,0,0,0};
; CirQueue Spi_Send_Buffer={0,0,0,Spi_Send_Data,SPI_SEND_DATA_BUFFER_SIZE,0,0,0};
; 
; #pragma interrupt_handler spi_stc_isr:iv_SPI_STC 
; void spi_stc_isr(void) 
; { 
	.dbline 64
;    if(Spi_Receive_Buffer.status==SPI_DATA_RECEIVE)
	lds R24,_Spi_Receive_Buffer+7
	cpi R24,1
	brne L8
	.dbline 65
;        EnQueue(&Spi_Receive_Buffer,SPDR); //从SPI口读出收到的字节 
	in R18,0xf
	ldi R16,<_Spi_Receive_Buffer
	ldi R17,>_Spi_Receive_Buffer
	xcall _EnQueue
L8:
	.dbline 66
;    if (Spi_Send_Buffer.status==SPI_DATA_SEND) 
	lds R24,_Spi_Send_Buffer+7
	cpi R24,2
	brne L11
	.dbline 67
;     { 
	.dbline 68
;       if(!EmptyQueue(&Spi_Send_Buffer))//如果发送缓冲区中有待发的数据 
	lds R2,_Spi_Send_Buffer+2
	tst R2
	breq L14
	.dbline 69
; 	      {
	.dbline 70
; 		  SPDR = DeQueue(&Spi_Send_Buffer); //发送一个字节数据,并调整指针
	ldi R16,<_Spi_Send_Buffer
	ldi R17,>_Spi_Send_Buffer
	xcall _DeQueue
	out 0xf,R16
	.dbline 71
; 		  }
	xjmp L15
L14:
	.dbline 73
; 	  else 
; 	      {
	.dbline 74
; 		  Spi_Send_Buffer.status=SPI_DATA_FREE;
	clr R2
	sts _Spi_Send_Buffer+7,R2
	.dbline 75
; 		  }
L15:
	.dbline 76
L11:
	.dbline -2
L7:
	xcall pop_lset
	.dbline 0 ; func end
	reti
	.dbend
	.dbfunc e Spi_Get_Char _Spi_Get_Char fc
;           data -> R20
	.even
_Spi_Get_Char::
	xcall push_gset1
	.dbline -1
	.dbline 82
;     } 
; } 
; 
; 
; 
; uint8 Spi_Get_Char(void) 
; { 
L19:
	.dbline 84
L20:
	.dbline 84
;   uint8 data;
;   while (EmptyQueue(&Spi_Receive_Buffer)); //无接收数据,等待 
	lds R2,_Spi_Receive_Buffer+2
	tst R2
	breq L19
	.dbline 85
;   data = DeQueue(&Spi_Receive_Buffer); //从接收缓冲区取出一个SPI收到的数据 
	ldi R16,<_Spi_Receive_Buffer
	ldi R17,>_Spi_Receive_Buffer
	xcall _DeQueue
	mov R20,R16
	.dbline 86
;   return data; 
	.dbline -2
L18:
	xcall pop_gset1
	.dbline 0 ; func end
	ret
	.dbsym r data 20 c
	.dbend
	.dbfunc e Spi_Put_Char _Spi_Put_Char fV
;              c -> R20
	.even
_Spi_Put_Char::
	xcall push_gset1
	mov R20,R16
	.dbline -1
	.dbline 90
; } 
; 
; void Spi_Put_Char(uint8 c) 
; { 
L24:
	.dbline 91
L25:
	.dbline 91
;   while (FullQueue(&Spi_Send_Buffer));//发送缓冲区满,等待 
	lds R2,_Spi_Send_Buffer+5
	lds R3,_Spi_Send_Buffer+2
	cp R3,R2
	breq L24
	.dbline 92
;   if (Spi_Send_Buffer.count)//发送缓冲区已中有待发数据 
	tst R3
	breq L29
	.dbline 93
;     { //或SPI正在发送数据时 
	.dbline 94
; 	  EnQueue(&Spi_Send_Buffer,c);//将数据放入发送缓冲区排队 
	mov R18,R20
	ldi R16,<_Spi_Send_Buffer
	ldi R17,>_Spi_Send_Buffer
	xcall _EnQueue
	.dbline 95
;     } 
	xjmp L30
L29:
	.dbline 97
	out 0xf,R20
L30:
	.dbline -2
L23:
	xcall pop_gset1
	.dbline 0 ; func end
	ret
	.dbsym r c 20 c
	.dbend
	.dbfunc e Spi_Receive _Spi_Receive fc
;              i -> R20,R21
;         length -> R22,R23
;         buffer -> R10,R11
	.even
_Spi_Receive::
	xcall push_gset3
	movw R22,R18
	movw R10,R16
	.dbline -1
	.dbline 102
;   else 
;     SPDR = c; //发送缓冲区中空且SPI口空闲,直接放入SPDR由SIP口发送 
; } 
; 
; 
; uint8 Spi_Receive(uint8 *buffer,uint16 length)
; {
	.dbline 104
; uint16 i;
; Spi_Receive_Buffer.status=SPI_DATA_RECEIVE;
	ldi R24,1
	sts _Spi_Receive_Buffer+7,R24
	.dbline 105
; for(i=0;i<length;i++)
	clr R20
	clr R21
	xjmp L37
L34:
	.dbline 106
	.dbline 107
	xcall _Spi_Get_Char
	movw R30,R10
	st Z+,R16
	movw R10,R30
	.dbline 108
L35:
	.dbline 105
	subi R20,255  ; offset = 1
	sbci R21,255
L37:
	.dbline 105
	cp R20,R22
	cpc R21,R23
	brlo L34
	.dbline 109
;  {
;  *buffer++=Spi_Get_Char();
;  }
; Spi_Receive_Buffer.status=SPI_DATA_FREE;
	clr R2
	sts _Spi_Receive_Buffer+7,R2
	.dbline 110
; return i;
	mov R16,R20
	.dbline -2
L32:
	xcall pop_gset3
	.dbline 0 ; func end
	ret
	.dbsym r i 20 i
	.dbsym r length 22 i
	.dbsym r buffer 10 pc
	.dbend
	.dbfunc e Spi_Send _Spi_Send fc
;              i -> R20,R21
;         length -> R22,R23
;         buffer -> R10,R11
	.even
_Spi_Send::
	xcall push_gset3
	movw R22,R18
	movw R10,R16
	.dbline -1
	.dbline 114
; }
; 
; uint8 Spi_Send(uint8 *buffer,uint16 length)
; {
	.dbline 116
; uint16 i;
; Spi_Send_Buffer.status=SPI_DATA_SEND;
	ldi R24,2
	sts _Spi_Send_Buffer+7,R24
	.dbline 117
; for(i=0;i<length;i++)
	clr R20
	clr R21
	xjmp L44
L41:
	.dbline 118
	.dbline 119
	movw R30,R10
	ld R16,Z+
	movw R10,R30
	xcall _Spi_Put_Char
	.dbline 120
L42:
	.dbline 117
	subi R20,255  ; offset = 1
	sbci R21,255
L44:
	.dbline 117
	cp R20,R22
	cpc R21,R23
	brlo L41
	.dbline 121
;  {
;  Spi_Put_Char(*buffer++); 
;  }
; Spi_Send_Buffer.status=SPI_DATA_FREE;
	clr R2
	sts _Spi_Send_Buffer+7,R2
	.dbline 122
; return i;
	mov R16,R20
	.dbline -2
L39:
	xcall pop_gset3
	.dbline 0 ; func end
	ret
	.dbsym r i 20 i
	.dbsym r length 22 i
	.dbsym r buffer 10 pc
	.dbend
	.dbfunc e Spi_SendReceive _Spi_SendReceive fc
;            ptr -> R22,R23
;              i -> R20,R21
;  receivelength -> R10,R11
;     sendlength -> R12,R13
;         buffer -> R14,R15
	.even
_Spi_SendReceive::
	xcall push_gset5
	movw R12,R18
	movw R14,R16
	ldd R10,y+10
	ldd R11,y+11
	.dbline -1
	.dbline 126
; }
; 
; uint8 Spi_SendReceive(uint8 *buffer,uint16 sendlength,uint16 receivelength)
; {
	.dbline 129
; uint16 i;
; uint8 *ptr;
; ptr=buffer;
	movw R22,R14
	.dbline 130
; if (receivelength!=0)
	tst R10
	brne X0
	tst R11
	breq L47
X0:
	.dbline 131
;     {
	.dbline 132
; 	Spi_Receive_Buffer.status=SPI_DATA_RECEIVE;
	ldi R24,1
	sts _Spi_Receive_Buffer+7,R24
	.dbline 133
; 	}
L47:
	.dbline 134
; Spi_Send_Buffer.status=SPI_DATA_SEND;
	ldi R24,2
	sts _Spi_Send_Buffer+7,R24
	.dbline 135
; for(i=0;i<sendlength;i++)
	clr R20
	clr R21
	xjmp L54
L51:
	.dbline 136
	.dbline 137
	movw R30,R22
	ld R16,Z+
	movw R22,R30
	xcall _Spi_Put_Char
	.dbline 138
L52:
	.dbline 135
	subi R20,255  ; offset = 1
	sbci R21,255
L54:
	.dbline 135
	cp R20,R12
	cpc R21,R13
	brlo L51
	.dbline 139
;  {
;  Spi_Put_Char(*ptr++); 
;  }
; ptr=buffer;
	movw R22,R14
	.dbline 140
; for(i=0;(i<receivelength)&&(i<sendlength);i++)
	clr R20
	clr R21
	xjmp L58
L55:
	.dbline 141
	.dbline 142
	xcall _Spi_Get_Char
	movw R30,R22
	st Z+,R16
	movw R22,R30
	.dbline 143
L56:
	.dbline 140
	subi R20,255  ; offset = 1
	sbci R21,255
L58:
	.dbline 140
	cp R20,R10
	cpc R21,R11
	brsh L59
	cp R20,R12
	cpc R21,R13
	brlo L55
L59:
	.dbline 144
;  {
;  *ptr++=Spi_Get_Char();
;  }
; Spi_Send_Buffer.status=SPI_DATA_FREE;
	clr R2
	sts _Spi_Send_Buffer+7,R2
	.dbline 145
; Spi_Receive_Buffer.status=SPI_DATA_FREE;
	sts _Spi_Receive_Buffer+7,R2
	.dbline 146
; return i;
	mov R16,R20
	.dbline -2
L46:
	xcall pop_gset5
	.dbline 0 ; func end
	ret
	.dbsym r ptr 22 pc
	.dbsym r i 20 i
	.dbsym r receivelength 10 i
	.dbsym r sendlength 12 i
	.dbsym r buffer 14 pc
	.dbend
	.dbfunc e Spi_Init _Spi_Init fV
;           temp -> R16
	.even
_Spi_Init::
	.dbline -1
	.dbline 151
; }
; 
; 
; void Spi_Init(void) 
; { 
	.dbline 178
;   uint8 temp;
; 
; #if (CPU_TYPE == M32)|| (CPU_TYPE == M16)      //   MISO-PB6,MOSI-PB5,SCK-PB7,SS-PB4 
;   #define DDR_SPI  DDRB
;   #define PORT_SPI PORTB
;   #define DD_MOSI  5
;   #define DD_MISO  6
;   #define DD_SCK   7
;   #define DD_SS    4
; #endif
; #if CPU_TYPE == M8       //   MISO-PB6,MOSI-PB5,SCK-PB7,SS-PB4 
;   #define DDR_SPI  DDRB
;   #define PORT_SPI PORTB
;   #define DD_MOSI  3
;   #define DD_MISO  4
;   #define DD_SCK   5
;   #define DD_SS    2
; #endif
; #if (CPU_TYPE == M128)||(CPU_TYPE == M64 )      //   MISO-PB6,MOSI-PB5,SCK-PB7,SS-PB4 
;   #define DDR_SPI  DDRB
;   #define PORT_SPI PORTB
;   #define DD_MOSI  2
;   #define DD_MISO  3
;   #define DD_SCK   1
;   #define DD_SS    0
; #endif
;   DDR_SPI = DDR_SPI|(1<<DD_SS)|(1<<DD_MOSI)|(1<<DD_SCK); //MISO=input and MOSI,SCK,SS = output
	in R24,0x17
	ori R24,176
	out 0x17,R24
	.dbline 179
;   PORTB |=(1<<DD_MISO)|(1<<DD_SS); //MISO上拉电阻有效 
	in R24,0x18
	ori R24,80
	out 0x18,R24
	.dbline 180
;   SPCR = (1<<SPIE)|(1<<SPE)|(1<<MSTR);  //SPI允许,4X 主机模式,MSB先发,SPI模式0 (CPOL CPHA 00(0) 01(1) 10(2) 11(3)) 
	ldi R24,208
	out 0xd,R24
	.dbline 182
; //  SPSR = 0; 
;   SPSR = (1<<SPI2X); //enable spi2x
	ldi R24,1
	out 0xe,R24
	.dbline 183
;   temp = SPSR; 
	in R16,0xe
	.dbline 184
;   temp = SPDR; //清空SPI,和中断标志,使SPI空闲 
	in R16,0xf
	.dbline -2
L62:
	.dbline 0 ; func end
	ret
	.dbsym r temp 16 c
	.dbend
	.area bss(ram, con, rel)
	.dbfile D:\桌面\mp3\SPI\spi.c
_Spi_Send_Data:
	.blkb 10
	.dbsym s Spi_Send_Data _Spi_Send_Data A[10:10]c
_Spi_Receive_Data:
	.blkb 255
	.dbsym s Spi_Receive_Data _Spi_Receive_Data A[255:255]c

⌨️ 快捷键说明

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