📄 mp3.lst
字号:
0A07 01BF MOVW R22,R30
0A08 DF9F RCALL _Spi_Put_Char
0A09 5F4F SUBI R20,0xFF
0A0A 4F5F SBCI R21,0xFF
0A0B 154C CP R20,R12
0A0C 055D CPC R21,R13
0A0D F3B8 BCS 0x0A05
(0138) }
(0139) ptr=buffer;
0A0E 01B7 MOVW R22,R14
(0140) for(i=0;(i<receivelength)&&(i<sendlength);i++)
0A0F 2744 CLR R20
0A10 2755 CLR R21
0A11 C006 RJMP 0x0A18
(0141) {
(0142) *ptr++=Spi_Get_Char();
0A12 DF87 RCALL _Spi_Get_Char
0A13 01FB MOVW R30,R22
0A14 9301 ST R16,Z+
0A15 01BF MOVW R22,R30
0A16 5F4F SUBI R20,0xFF
0A17 4F5F SBCI R21,0xFF
0A18 154A CP R20,R10
0A19 055B CPC R21,R11
0A1A F418 BCC 0x0A1E
0A1B 154C CP R20,R12
0A1C 055D CPC R21,R13
0A1D F3A0 BCS 0x0A12
(0143) }
(0144) Spi_Send_Buffer.status=SPI_DATA_FREE;
0A1E 2422 CLR R2
0A1F 922000BD STS 0xBD,R2
(0145) Spi_Receive_Buffer.status=SPI_DATA_FREE;
0A21 922000B4 STS 0xB4,R2
(0146) return i;
0A23 2F04 MOV R16,R20
0A24 940E1918 CALL pop_gset5
0A26 9508 RET
(0147) }
(0148)
(0149)
(0150) void Spi_Init(void)
(0151) {
(0152) uint8 temp;
(0153)
(0154) #if (CPU_TYPE == M32)|| (CPU_TYPE == M16) // MISO-PB6,MOSI-PB5,SCK-PB7,SS-PB4
(0155) #define DDR_SPI DDRB
(0156) #define PORT_SPI PORTB
(0157) #define DD_MOSI 5
(0158) #define DD_MISO 6
(0159) #define DD_SCK 7
(0160) #define DD_SS 4
(0161) #endif
(0162) #if CPU_TYPE == M8 // MISO-PB6,MOSI-PB5,SCK-PB7,SS-PB4
(0163) #define DDR_SPI DDRB
(0164) #define PORT_SPI PORTB
(0165) #define DD_MOSI 3
(0166) #define DD_MISO 4
(0167) #define DD_SCK 5
(0168) #define DD_SS 2
(0169) #endif
(0170) #if (CPU_TYPE == M128)||(CPU_TYPE == M64 ) // MISO-PB6,MOSI-PB5,SCK-PB7,SS-PB4
(0171) #define DDR_SPI DDRB
(0172) #define PORT_SPI PORTB
(0173) #define DD_MOSI 2
(0174) #define DD_MISO 3
(0175) #define DD_SCK 1
(0176) #define DD_SS 0
(0177) #endif
(0178) DDR_SPI = DDR_SPI|(1<<DD_SS)|(1<<DD_MOSI)|(1<<DD_SCK); //MISO=input and MOSI,SCK,SS = output
_Spi_Init:
temp --> R16
0A27 B387 IN R24,0x17
0A28 6B80 ORI R24,0xB0
0A29 BB87 OUT 0x17,R24
(0179) PORTB |=(1<<DD_MISO)|(1<<DD_SS); //MISO上拉电阻有效
0A2A B388 IN R24,0x18
0A2B 6580 ORI R24,0x50
0A2C BB88 OUT 0x18,R24
(0180) SPCR = (1<<SPIE)|(1<<SPE)|(1<<MSTR); //SPI允许,4X 主机模式,MSB先发,SPI模式0 (CPOL CPHA 00(0) 01(1) 10(2) 11(3))
0A2D ED80 LDI R24,0xD0
0A2E B98D OUT 0x0D,R24
(0181) // SPSR = 0;
(0182) SPSR = (1<<SPI2X); //enable spi2x
0A2F E081 LDI R24,1
0A30 B98E OUT 0x0E,R24
(0183) temp = SPSR;
0A31 B10E IN R16,0x0E
(0184) temp = SPDR; //清空SPI,和中断标志,使SPI空闲
0A32 B10F IN R16,0x0F
0A33 9508 RET
_Delay:
i --> R20
n --> R16
0A34 940E1923 CALL push_gset1
FILE: D:\桌面\mp3\TWI\TWI.c
(0001) /*********************************************************************************************************
(0002) ** TWI 驱动程序
(0003) ** (c) Copyright 2006-2008, limaokui
(0004) ** All Rights Reserved
(0005) **
(0006) ** V1.0.0
(0007) **
(0008) **
(0009) **--------------文件信息--------------------------------------------------------------------------------
(0010) **文 件 名:TWI.h
(0011) **创 建 人: 李茂奎
(0012) **最后修改日期: 2006年8月29日
(0013) **描 述: TWI驱动程序
(0014) **
(0015) **--------------历史版本信息----------------------------------------------------------------------------
(0016) ** 创建人: 李茂奎
(0017) ** 版 本: V1.00
(0018) ** 日 期: 2006年8月29日
(0019) ** 描 述: 原始版本
(0020) **
(0021) **------------------------------------------------------------------------------------------------------
(0022) ** 修改人: 李茂奎
(0023) ** 版 本:
(0024) ** 日 期:
(0025) ** 描 述:
(0026) **
(0027) **--------------当前版本修订------------------------------------------------------------------------------
(0028) ** 修改人: 李茂奎
(0029) ** 日 期: 2006年9月1日
(0030) ** 描 述:
(0031) **
(0032) **------------------------------------------------------------------------------------------------------
(0033) *********************************************************************************************************/
(0034) /*
(0035) 说明:1、本驱动程序已经实现了TWI中断通讯的四种模式:MT、MR、ST、SR。
(0036) 2、MT方式调用Twi_MasterSend()函数,用到了Twi_SendBuffer队列,
(0037) 最大单次发送255Btye,理论上两次发送间隔5MS以上。
(0038) 3、MR方式调用Twi_MasterRecive()函数,用到了Twi_ReceiveBuffer队列,
(0039) 最大单次发送255Btye,理论上两次发送间隔5MS以上。
(0040) 4、SR方式用户不必关心何时中断,在中断结束后,调用Twi_SlaveReceiveService()函数,
(0041) 此函数将接收到的数据传给上层缓冲区Twi_LocalBuffer,用到了Twi_ReceiveBuffer、Twi_LocalBuffer队列,
(0042) 最大单次发送255Btye。上层程序仅需检测Twi_LocalBuffer中的status即可,即若status值
(0043) TWI_DATA_READY,就可以读取数据,读完后设置LocalBuffer的Status为TWI_DATA_FREE。
(0044) 5、ST方式用户不必关心何时中断,在中断结束后,调用Twi_TransmintReceiveService()函数S玫搅薚wi_ReceiveBuffer、Twi_LocalBuffer队列,
(0045) 如果想使能从机发送则可将要发数据传入LocalBuffer中并设置Status为TWI_DATA_SEND,在写
(0046) LocalBuffer之前,应检测STATUS是否为Status为TWI_DATA_FREE。
(0047) 6、非中断模式的接收发送没有经过验证。使用时请注意。
(0048) 7、使用时首先调用TwiInit()进行初始化,(循环队列的长度可以自己修改对应的数组和结构中的queuesize),
(0049) 然后打开中断即可。对于不同的单片机,此驱动中通过定义CPU_TYPE实现切换。对应的定义在config中。
(0050) */
(0051) #include "config.h"
(0052) // Twi标准波特率:
(0053) // 低速 100KHz
(0054) // 高速 400KHz
(0055)
(0056) // Twi_ 状态和地址变量
(0057) static volatile eTwi_StateType Twi_State; // 用于独占TWI的资源分配的信号量机制
(0058) static volatile uint8 Twi_DeviceAddrRW;
(0059) // 发送缓冲区
(0060) static uint8 Twi_SendData[TWI_SEND_DATA_BUFFER_SIZE];
(0061) CirQueue Twi_SendBuffer={0,0,0,Twi_SendData,TWI_SEND_DATA_BUFFER_SIZE,QUEUE_OK,TWI_DATA_FREE,0};
(0062) // 接收缓冲区
(0063) static uint8 Twi_ReceiveData[TWI_RECEIVE_DATA_BUFFER_SIZE];
(0064) CirQueue Twi_ReceiveBuffer={0,0,0,(uint8 *)Twi_ReceiveData,TWI_RECEIVE_DATA_BUFFER_SIZE,QUEUE_OK,TWI_DATA_FREE,0};
(0065) //本地缓冲区,当为从机时,与TWI接口
(0066) static uint8 LocalBuffer[TWI_LOCAL_DATA_BUFFER_SIZE];
(0067) CirQueue Twi_LocalBuffer={0,0,0,LocalBuffer,TWI_LOCAL_DATA_BUFFER_SIZE,QUEUE_OK,TWI_DATA_FREE,0};
(0068) //错误代码
(0069) static volatile uint8 TwiErrorCode;
(0070)
(0071) // 指向接收处理函数的指针,当本机被选中从接收时调用函数:Twi_SlaveReceive
(0072) static void (*Twi_SlaveReceive)(uint8 receiveDataLength, uint8* recieveData);
(0073) // 指向发送处理函数的指针,当本机被选中从发送时调用函数:ITwi_SlaveTransmit
(0074) static uint8 (*Twi_SlaveTransmit)(uint8 transmitDataLengthMax, uint8* transmitData);
(0075)
(0076)
(0077)
(0078) /*************************************************************************************
(0079) **延时公式
(0080) ** i*500-100 US (8>i>2)
(0081) ** i*500 (255>i>8)
(0082) ** i=1精确延时100us
(0083) ** i=2 精确延时660US
(0084) ** i=6 精确延时2.9ms
(0085) ** i=10 精确延时5ms
(0086) ** i=20 10ms
(0087) ** i=100 50ms
(0088) ** i=200 100ms
(0089) ** i=255 128ms
(0090) **************************************************************************************/
(0091) void Delay(uint8 n)
(0092) {
(0093) uint8 i;
(0094) for(i=36;n!=0;n--)
0A36 E244 LDI R20,0x24
0A37 C007 RJMP 0x0A3F
(0095) {
(0096) while(--i);
0A38 2F84 MOV R24,R20
0A39 5081 SUBI R24,1
0A3A 2F48 MOV R20,R24
0A3B 2388 TST R24
0A3C F7D9 BNE 0x0A38
(0097) WDR(); //喂狗;
0A3D 95A8 WDR
0A3E 950A DEC R16
0A3F 2300 TST R16
0A40 F7B9 BNE 0x0A38
0A41 940E1926 CALL pop_gset1
0A43 9508 RET
_Twi_SetBitrate:
bitrate_div --> R10
bitrateKHz --> R10
0A44 940E191F CALL push_gset3
0A46 0158 MOVW R10,R16
(0098) }
(0099) }
(0100) /*********************************************************************************************************
(0101) ** 函数名称:Twi_SetBitrate
(0102) ** 功能描述:设置TWI总线的速率
(0103) ** 输 入: bitrateKHZ : 总线速率
(0104) ** 输 出:
(0105) ** 全局变量:
(0106) ** 调用模块: 无
(0107) ** 说明:
(0108) ** 注意:
(0109) ** 日 期: 2006年8月29日
(0110) ********************************************************************************************************/
(0111) void Twi_SetBitrate(uint16 bitrateKHz){
(0112) uint8 bitrate_div;
(0113) WDR(); //喂狗;
0A47 95A8 WDR
(0114) // SCL freq = F_CPU/(16+2*TWBR))
(0115) #ifdef TWPS0
(0116) // 对于用速率分频的AVR (mega128)
(0117) // SCL freq = F_CPU/(16+2*TWBR*4^TWPS)
(0118) // set TWPS to zero
(0119) TWSR&=~(1<<TWPS0);
0A48 9808 CBI 0x01,0
(0120) TWSR&=~(1<<TWPS1);
0A49 9809 CBI 0x01,1
(0121) #endif
(0122) // 计算分频
(0123) bitrate_div = ((F_CPU/1000)/bitrateKHz);
0A4A 0115 MOVW R2,R10
0A4B 2444 CLR R4
0A4C 2455 CLR R5
0A4D E949 LDI R20,0x99
0A4E E359 LDI R21,0x39
0A4F E060 LDI R22,0
0A50 E070 LDI R23,0
0A51 925A ST R5,-Y
0A52 924A ST R4,-Y
0A53 923A ST R3,-Y
0A54 922A ST R2,-Y
0A55 018A MOVW R16,R20
0A56 019B MOVW R18,R22
0A57 940E184C CALL div32s
0A59 2EA0 MOV R10,R16
(0124) if(bitrate_div >= 16)
0A5A 2D8A MOV R24,R10
0A5B 3100 CPI R16,0x10
0A5C F018 BCS 0x0A60
(0125) bitrate_div = (bitrate_div-16)/2;
0A5D 5180 SUBI R24,0x10
0A5E 2EA8 MOV R10,R24
0A5F 94A6 LSR R10
(0126) TWBR = bitrate_div;
0A60 B8A0 OUT 0x00,R10
0A61 940E1912 CALL pop_gset3
0A63 9508 RET
_Twi_MasterSend:
result --> R20
i --> R22
data --> R10
length --> R12
deviceAddr --> R14
0A64 940E191B CALL push_gset5
0A66 2EC2 MOV R12,R18
0A67 2EE0 MOV R14,R16
0A68 84AA LDD R10,Y+10
0A69 84BB LDD R11,Y+11
(0127) }
(0128) /*********************************************************************************************************
(0129) ** 函数名称:Twi_MasterSend
(0130) ** 功能描述:主发送
(0131) ** 输 入: deviceAddr:从机地址
(0132) ** length:数据长度
(0133) ** * data:发送缓冲区指针
(0134) **
(0135) ** 输 出: 发送的字节数
(0136) ** 全局变量:
(0137) ** 调用模块:
(0138) ** 说明:
(0139) ** 注意:
(0140) ** 日 期: 2006年8月29日
(0141) ********************************************************************************************************/
(0142) uint8 Twi_MasterSend(uint8 deviceAddr, uint8 length, uint8* data)
(0143) {
(0144) uint8 i,result=0;
0A6A 2744 CLR R20
(0145) WDR(); //喂狗;
0A6B 95A8 WDR
(0146) // 等待总线准备完成
(0147) while(Twi_State); //此处为独占TWI的信号量机制
0A6C 902001FC LDS R2,Twi_State
0A6E 2022 TST R2
0A6F F7E1 BNE 0x0A6C
(0148) // 设置状态
(0149) Twi_State = TWI_MASTER_TX;
0A70 E082 LDI R24,2
0A71 938001FC STS Twi_State,R24
(0150) // 准备数据
(0151) Twi_DeviceAddrRW = (deviceAddr & 0xFE); // RW 为0: 写操作
0A73 2D8E MOV R24,R14
0A74 7F8E ANDI R24,0xFE
0A75 938001FB STS Twi_DeviceAddrRW,R24
(0152) if(Twi_SendBuffer.status==TWI_DATA_FREE)
0A77 902000C6 LDS R2,0xC6
0A79 2022 TST R2
0A7A F439 BNE 0x0A82
(0153) {
(0154) InitQueue(&Twi_SendBuffer); //清空上次发送的信息
0A7B EB0F LDI R16,0xBF
0A7C E010 LDI R17,0
0A7D 940E08FE CALL _InitQueue
(0155) Twi_SendBuffer.status=TWI_DATA_SEND;
0A7F E082 LDI R24,2
0A80 938000C6 STS 0xC6,R24
(0156) }
(0157) for(i=0; (i<length)&&(Twi_SendBuffer.errorcode!=QUEUE_OVERFLOW); i++)
0A82 2766 CLR R22
0A83 C008 RJMP 0x0A8C
(0158) EnQueue(&Twi_SendBuffer,*data++);
0A84 01F5 MOVW R30,R10
0A85 9121 LD R18,Z+
0A86 015F MOVW R10,R30
0A87 EB0F LDI R16,0xBF
0A88 E010 LDI R17,0
0A89 940E090B CALL _EnQueue
0A8B 9563 INC R22
0A8C 156C CP R22,R12
0A8D F420 BCC 0x0A92
0A8E 918000C5 LDS R24,0xC5
0A90 3081 CPI R24,1
0A91 F791 BNE 0x0A84
(0159) result=i;
0A92 2F46 MOV R20,R22
(0160)
(0161) // 发送开始条件
(0162) Twi_Start();
0A93 B786 IN R24,0x36
0A94 708F ANDI R24,0xF
0A95 6A80 ORI R24,0xA0
0A96 BF86 OUT 0x36,R24
(0163) WDR(); //喂狗;
0A97 95A8 WDR
(0164) while(Twi_State);
0A98 902001FC LDS R2,Twi_State
0A9A 2022 TST R2
0A9B F7E1 BNE 0x0A98
(0165) WDR(); //喂狗;
0A9C 95A8 WDR
(0166) i=0;
0A9D 2766 CLR R22
0A9E C019 RJMP 0x0AB8
(0167) while(((TwiErrorCode==TW_MT_SLA_NACK)||(TwiErrorCode==TW_MT_ARB_LOST)||(TwiErrorCode==TW_MT_DATA_NACK))&&i<TWI_FAIL_MAX) //器件不响应或总线仲裁失败
(0168) {
(0169) i++;
0A9F 9563 INC R22
(0170) if((TwiErrorCode==TW_MT_DATA_NACK)&&(Twi_SendBuffer.count==0))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -