📄 mp3.lst
字号:
(0125) ** 调用模块:
(0126) ** 说明:
(0127) ** 注意:
(0128) ** 日 期: 2006年8月29日
(0129) ********************************************************************************************************/
(0130) uint8 DeQueue(CirQueue * Q)
(0131) {
(0132) uint8 temp;
(0133) if(EmptyQueue(Q))
0941 01FB MOVW R30,R22
0942 8022 LDD R2,Z+2
0943 2022 TST R2
0944 F429 BNE 0x094A
(0134) {
(0135) Q->errorcode=QUEUE_UNDERFLOW;
0945 E082 LDI R24,2
0946 01FB MOVW R30,R22
0947 8386 STD Z+6,R24
(0136) return FALSE;
0948 2700 CLR R16
0949 C01B RJMP 0x0965
(0137) }
(0138) //CLI();
(0139) Q->count--;
094A 01CB MOVW R24,R22
094B 9602 ADIW R24,2
094C 01FC MOVW R30,R24
094D 8180 LDD R24,Z+0
094E 5081 SUBI R24,1
094F 8380 STD Z+0,R24
(0140) temp=Q->data[Q->front];
0950 01FB MOVW R30,R22
0951 8023 LDD R2,Z+3
0952 8034 LDD R3,Z+4
0953 01FB MOVW R30,R22
0954 81E0 LDD R30,Z+0
0955 27FF CLR R31
0956 0DE2 ADD R30,R2
0957 1DF3 ADC R31,R3
0958 8140 LDD R20,Z+0
(0141) Q->front=(Q->front+1)%Q->queuesize;
0959 01FB MOVW R30,R22
095A 8115 LDD R17,Z+5
095B 01FB MOVW R30,R22
095C 8100 LDD R16,Z+0
095D 5F0F SUBI R16,0xFF
095E 940E18B7 CALL mod8u
0960 01FB MOVW R30,R22
0961 8300 STD Z+0,R16
(0142) Q->errorcode=QUEUE_OK;
0962 2422 CLR R2
0963 8226 STD Z+6,R2
(0143) //SEI();
(0144) return temp;
0964 2F04 MOV R16,R20
0965 940E190F CALL pop_gset2
0967 9508 RET
(0145) }
(0146) /*********************************************************************************************************
(0147) ** 函数名称:FrontQueueData
(0148) ** 功能描述:出队
(0149) ** 输 入:
(0150) ** 输 出:
(0151) ** 全局变量:
(0152) ** 调用模块:
(0153) ** 说明:
(0154) ** 注意:
(0155) ** 日 期: 2006年8月29日
(0156) ********************************************************************************************************/
(0157) uint8 FrontQueueData(CirQueue * Q)
(0158) {
(0159) if(EmptyQueue(Q))
_FrontQueueData:
Q --> R16
0968 01F8 MOVW R30,R16
0969 8022 LDD R2,Z+2
096A 2022 TST R2
096B F429 BNE 0x0971
(0160) {
(0161) Q->errorcode=QUEUE_UNDERFLOW;
096C E082 LDI R24,2
096D 01F8 MOVW R30,R16
096E 8386 STD Z+6,R24
(0162) return FALSE;
096F 2700 CLR R16
0970 C009 RJMP 0x097A
(0163) }
(0164) return Q->data[Q->front];
0971 01F8 MOVW R30,R16
0972 8023 LDD R2,Z+3
0973 8034 LDD R3,Z+4
0974 01F8 MOVW R30,R16
0975 81E0 LDD R30,Z+0
0976 27FF CLR R31
0977 0DE2 ADD R30,R2
0978 1DF3 ADC R31,R3
0979 8100 LDD R16,Z+0
097A 9508 RET
_spi_stc_isr:
097B 940E195F CALL push_lset
FILE: D:\桌面\mp3\SPI\spi.c
(0001) /*********************************************************************************************************
(0002) ** SPI 驱动程序
(0003) ** (c) Copyright 2006-2008, limaokui
(0004) ** All Rights Reserved
(0005) **
(0006) ** V1.0.0
(0007) **
(0008) **
(0009) **--------------文件信息--------------------------------------------------------------------------------
(0010) **文 件 名:SPI.c
(0011) **创 建 人: 李茂奎
(0012) **最后修改日期: 2006年9月2日
(0013) **描 述: SPI驱动程序
(0014) **
(0015) **--------------历史版本信息----------------------------------------------------------------------------
(0016) ** 创建人: 李茂奎
(0017) ** 版 本: V1.00
(0018) ** 日 期: 2006年9月2日
(0019) ** 描 述: 原始版本
(0020) **
(0021) **------------------------------------------------------------------------------------------------------
(0022) ** 修改人: 李茂奎
(0023) ** 版 本:
(0024) ** 日 期:
(0025) ** 描 述:
(0026) **
(0027) **--------------当前版本修订------------------------------------------------------------------------------
(0028) ** 修改人: 李茂奎
(0029) ** 日 期: 2006年9月2日
(0030) ** 描 述:
(0031) **
(0032) **------------------------------------------------------------------------------------------------------
(0033) *********************************************************************************************************/
(0034) /*
(0035) ATmega128的SPI采用硬件方式实现面向字节的全双工3线同步通信,
(0036) 支持主机、从机和2种不同极性的SPI时序,通信速率有7种选择,
(0037) 主机方式的最高速率为1/2系统时钟,从机方式最高速率为1/4系统时钟。
(0038)
(0039) AVR的SPI由一个16位的循环移位寄存器构成,当数据从主机方移出时,从机的数据同时也被移入,
(0040) 因此SPI的发送和接收在一个中断服务中完成。
(0041) 在SPI中断服务程序中,先从SPDR中读一个接收的字节存入接收数据缓冲器中,再从发送数据缓冲
(0042) 器取出一个字节写入SPDR中,由SPI发送到从机。
(0043) 数据一旦写入SPDR,ISP硬件开始发送数据。
(0044) 下一次ISP中断时,表示发送完成,并同时收到一个数据。
(0045) SPI为硬件接口和传输完成中断申请,所以使用SPI传输数据的有效方法是采用中断方式+数据缓存器的设计方法。
(0046)
(0047) 在对SPI初始化时,应注意以下几点:
(0048) .正确选择和设置主机或从机,以及工作模式(极性),数据传输率;
(0049) .注意传送字节的顺序,是低位优先(LSB First)还是高位优先(MSB Frist);
(0050) .正确设置MOSI和MISO接口的输入输出方向,输入引脚使用上拉电阻,可以节省总线上的吊高电阻。
(0051)
(0052)
(0053) */
(0054) #include "config.h"
(0055)
(0056) static uint8 Spi_Receive_Data[SPI_RECEIVE_DATA_BUFFER_SIZE];
(0057) static uint8 Spi_Send_Data[SPI_SEND_DATA_BUFFER_SIZE];
(0058) CirQueue Spi_Receive_Buffer={0,0,0,Spi_Receive_Data,SPI_RECEIVE_DATA_BUFFER_SIZE,0,0,0};
(0059) CirQueue Spi_Send_Buffer={0,0,0,Spi_Send_Data,SPI_SEND_DATA_BUFFER_SIZE,0,0,0};
(0060)
(0061) #pragma interrupt_handler spi_stc_isr:iv_SPI_STC
(0062) void spi_stc_isr(void)
(0063) {
(0064) if(Spi_Receive_Buffer.status==SPI_DATA_RECEIVE)
097D 918000B4 LDS R24,0xB4
097F 3081 CPI R24,1
0980 F429 BNE 0x0986
(0065) EnQueue(&Spi_Receive_Buffer,SPDR); //从SPI口读出收到的字节
0981 B12F IN R18,0x0F
0982 EA0D LDI R16,0xAD
0983 E010 LDI R17,0
0984 940E090B CALL _EnQueue
(0066) if (Spi_Send_Buffer.status==SPI_DATA_SEND)
0986 918000BD LDS R24,0xBD
0988 3082 CPI R24,2
0989 F469 BNE 0x0997
(0067) {
(0068) if(!EmptyQueue(&Spi_Send_Buffer))//如果发送缓冲区中有待发的数据
098A 902000B8 LDS R2,Spi_Send_Buffer+2
098C 2022 TST R2
098D F031 BEQ 0x0994
(0069) {
(0070) SPDR = DeQueue(&Spi_Send_Buffer); //发送一个字节数据,并调整指针
098E EB06 LDI R16,0xB6
098F E010 LDI R17,0
0990 940E093E CALL _DeQueue
0992 B90F OUT 0x0F,R16
(0071) }
0993 C003 RJMP 0x0997
(0072) else
(0073) {
(0074) Spi_Send_Buffer.status=SPI_DATA_FREE;
0994 2422 CLR R2
0995 922000BD STS 0xBD,R2
(0075) }
(0076) }
0997 940E1976 CALL pop_lset
0999 9518 RETI
_Spi_Get_Char:
data --> R20
099A 940E1923 CALL push_gset1
(0077) }
(0078)
(0079)
(0080)
(0081) uint8 Spi_Get_Char(void)
(0082) {
(0083) uint8 data;
(0084) while (EmptyQueue(&Spi_Receive_Buffer)); //无接收数据,等待
099C 902000AF LDS R2,Spi_Receive_Buffer+2
099E 2022 TST R2
099F F3E1 BEQ 0x099C
(0085) data = DeQueue(&Spi_Receive_Buffer); //从接收缓冲区取出一个SPI收到的数据
09A0 EA0D LDI R16,0xAD
09A1 E010 LDI R17,0
09A2 940E093E CALL _DeQueue
09A4 2F40 MOV R20,R16
(0086) return data;
09A5 940E1926 CALL pop_gset1
09A7 9508 RET
_Spi_Put_Char:
c --> R20
09A8 940E1923 CALL push_gset1
09AA 2F40 MOV R20,R16
(0087) }
(0088)
(0089) void Spi_Put_Char(uint8 c)
(0090) {
(0091) while (FullQueue(&Spi_Send_Buffer));//发送缓冲区满,等待
09AB 902000BB LDS R2,0xBB
09AD 903000B8 LDS R3,Spi_Send_Buffer+2
09AF 1432 CP R3,R2
09B0 F3D1 BEQ 0x09AB
(0092) if (Spi_Send_Buffer.count)//发送缓冲区已中有待发数据
09B1 2033 TST R3
09B2 F031 BEQ 0x09B9
(0093) { //或SPI正在发送数据时
(0094) EnQueue(&Spi_Send_Buffer,c);//将数据放入发送缓冲区排队
09B3 2F24 MOV R18,R20
09B4 EB06 LDI R16,0xB6
09B5 E010 LDI R17,0
09B6 940E090B CALL _EnQueue
(0095) }
09B8 C001 RJMP 0x09BA
(0096) else
(0097) SPDR = c; //发送缓冲区中空且SPI口空闲,直接放入SPDR由SIP口发送
09B9 B94F OUT 0x0F,R20
09BA 940E1926 CALL pop_gset1
09BC 9508 RET
_Spi_Receive:
i --> R20
length --> R22
buffer --> R10
09BD 940E191F CALL push_gset3
09BF 01B9 MOVW R22,R18
09C0 0158 MOVW R10,R16
(0098) }
(0099)
(0100)
(0101) uint8 Spi_Receive(uint8 *buffer,uint16 length)
(0102) {
(0103) uint16 i;
(0104) Spi_Receive_Buffer.status=SPI_DATA_RECEIVE;
09C1 E081 LDI R24,1
09C2 938000B4 STS 0xB4,R24
(0105) for(i=0;i<length;i++)
09C4 2744 CLR R20
09C5 2755 CLR R21
09C6 C006 RJMP 0x09CD
(0106) {
(0107) *buffer++=Spi_Get_Char();
09C7 DFD2 RCALL _Spi_Get_Char
09C8 01F5 MOVW R30,R10
09C9 9301 ST R16,Z+
09CA 015F MOVW R10,R30
09CB 5F4F SUBI R20,0xFF
09CC 4F5F SBCI R21,0xFF
09CD 1746 CP R20,R22
09CE 0757 CPC R21,R23
09CF F3B8 BCS 0x09C7
(0108) }
(0109) Spi_Receive_Buffer.status=SPI_DATA_FREE;
09D0 2422 CLR R2
09D1 922000B4 STS 0xB4,R2
(0110) return i;
09D3 2F04 MOV R16,R20
09D4 940E1912 CALL pop_gset3
09D6 9508 RET
_Spi_Send:
i --> R20
length --> R22
buffer --> R10
09D7 940E191F CALL push_gset3
09D9 01B9 MOVW R22,R18
09DA 0158 MOVW R10,R16
(0111) }
(0112)
(0113) uint8 Spi_Send(uint8 *buffer,uint16 length)
(0114) {
(0115) uint16 i;
(0116) Spi_Send_Buffer.status=SPI_DATA_SEND;
09DB E082 LDI R24,2
09DC 938000BD STS 0xBD,R24
(0117) for(i=0;i<length;i++)
09DE 2744 CLR R20
09DF 2755 CLR R21
09E0 C006 RJMP 0x09E7
(0118) {
(0119) Spi_Put_Char(*buffer++);
09E1 01F5 MOVW R30,R10
09E2 9101 LD R16,Z+
09E3 015F MOVW R10,R30
09E4 DFC3 RCALL _Spi_Put_Char
09E5 5F4F SUBI R20,0xFF
09E6 4F5F SBCI R21,0xFF
09E7 1746 CP R20,R22
09E8 0757 CPC R21,R23
09E9 F3B8 BCS 0x09E1
(0120) }
(0121) Spi_Send_Buffer.status=SPI_DATA_FREE;
09EA 2422 CLR R2
09EB 922000BD STS 0xBD,R2
(0122) return i;
09ED 2F04 MOV R16,R20
09EE 940E1912 CALL pop_gset3
09F0 9508 RET
_Spi_SendReceive:
ptr --> R22
i --> R20
receivelength --> R10
sendlength --> R12
buffer --> R14
09F1 940E191B CALL push_gset5
09F3 0169 MOVW R12,R18
09F4 0178 MOVW R14,R16
09F5 84AA LDD R10,Y+10
09F6 84BB LDD R11,Y+11
(0123) }
(0124)
(0125) uint8 Spi_SendReceive(uint8 *buffer,uint16 sendlength,uint16 receivelength)
(0126) {
(0127) uint16 i;
(0128) uint8 *ptr;
(0129) ptr=buffer;
09F7 01B7 MOVW R22,R14
(0130) if (receivelength!=0)
09F8 20AA TST R10
09F9 F411 BNE 0x09FC
09FA 20BB TST R11
09FB F019 BEQ 0x09FF
(0131) {
(0132) Spi_Receive_Buffer.status=SPI_DATA_RECEIVE;
09FC E081 LDI R24,1
09FD 938000B4 STS 0xB4,R24
(0133) }
(0134) Spi_Send_Buffer.status=SPI_DATA_SEND;
09FF E082 LDI R24,2
0A00 938000BD STS 0xBD,R24
(0135) for(i=0;i<sendlength;i++)
0A02 2744 CLR R20
0A03 2755 CLR R21
0A04 C006 RJMP 0x0A0B
(0136) {
(0137) Spi_Put_Char(*ptr++);
0A05 01FB MOVW R30,R22
0A06 9101 LD R16,Z+
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -