📄 spi_test_slave.lst
字号:
__start:
__text_start:
002E E5CF LDI R28,0x5F
002F E0D4 LDI R29,4
0030 BFCD OUT 0x3D,R28
0031 BFDE OUT 0x3E,R29
0032 51C0 SUBI R28,0x10
0033 40D0 SBCI R29,0
0034 EA0A LDI R16,0xAA
0035 8308 STD Y+0,R16
0036 2400 CLR R0
0037 E6E0 LDI R30,0x60
0038 E0F0 LDI R31,0
0039 E011 LDI R17,1
003A 33E1 CPI R30,0x31
003B 07F1 CPC R31,R17
003C F011 BEQ 0x003F
003D 9201 ST R0,Z+
003E CFFB RJMP 0x003A
003F 8300 STD Z+0,R16
0040 E5EC LDI R30,0x5C
0041 E0F0 LDI R31,0
0042 E6A0 LDI R26,0x60
0043 E0B0 LDI R27,0
0044 E010 LDI R17,0
0045 35EC CPI R30,0x5C
0046 07F1 CPC R31,R17
0047 F021 BEQ 0x004C
0048 95C8 LPM
0049 9631 ADIW R30,1
004A 920D ST R0,X+
004B CFF9 RJMP 0x0045
004C 940E00FB CALL _main
_exit:
004E CFFF RJMP _exit
_spi_stc_isr:
004F 922A ST R2,-Y
0050 938A ST R24,-Y
0051 939A ST R25,-Y
0052 93EA ST R30,-Y
0053 93FA ST R31,-Y
0054 B62F IN R2,0x3F
0055 922A ST R2,-Y
FILE: F:\IccAvr_Pro\Spi_test_slave.c
(0001) #include <iom16v.h>
(0002) #include <macros.h>
(0003) #define SIZE 100
(0004) #define MOSI PORTB5
(0005) #define MISO PINB6
(0006) #define SCK PORTB7
(0007) #define SS PORTB4
(0008)
(0009) unsigned char SPI_rx_buff[SIZE];
(0010) unsigned char SPI_tx_buff[SIZE];
(0011) unsigned char rx_wr_index,rx_rd_index,rx_counter,rx_buffer_overflow;
(0012) unsigned char tx_wr_index,tx_rd_index,tx_counter,SPI_ok,SPI_datain;
(0013)
(0014) #pragma interrupt_handler spi_stc_isr:18
(0015) void spi_stc_isr(void)
(0016) {
(0017) SPI_rx_buff[rx_wr_index] = SPDR; //从ISP口读出收到的字节
0056 EC8D LDI R24,0xCD
0057 E090 LDI R25,0
0058 91E00068 LDS R30,rx_wr_index
005A 27FF CLR R31
005B 0FE8 ADD R30,R24
005C 1FF9 ADC R31,R25
005D B02F IN R2,0x0F
005E 8220 STD Z+0,R2
(0018) SPI_ok=1;
005F E081 LDI R24,1
0060 93800061 STS SPI_ok,R24
(0019) SPI_datain=1;
0062 93800060 STS SPI_datain,R24
(0020) if (++rx_wr_index == SIZE) rx_wr_index = 0; //放入接收缓冲区,并调整队列指针
0064 91800068 LDS R24,rx_wr_index
0066 5F8F SUBI R24,0xFF
0067 2E28 MOV R2,R24
0068 92200068 STS rx_wr_index,R2
006A 3684 CPI R24,0x64
006B F419 BNE 0x006F
006C 2422 CLR R2
006D 92200068 STS rx_wr_index,R2
(0021) if (++rx_counter == SIZE)
006F 91800066 LDS R24,rx_counter
0071 5F8F SUBI R24,0xFF
0072 2E28 MOV R2,R24
0073 92200066 STS rx_counter,R2
0075 3684 CPI R24,0x64
0076 F431 BNE 0x007D
(0022) {
(0023) rx_counter = 0;
0077 2422 CLR R2
0078 92200066 STS rx_counter,R2
(0024) rx_buffer_overflow = 1;
007A E081 LDI R24,1
007B 93800065 STS rx_buffer_overflow,R24
(0025) }
(0026) if (tx_counter) //如果发送缓冲区中有待发的数据
007D 90200062 LDS R2,tx_counter
007F 2022 TST R2
0080 F0D9 BEQ 0x009C
(0027) {
(0028) --tx_counter;
0081 2D82 MOV R24,R2
0082 5081 SUBI R24,1
0083 93800062 STS tx_counter,R24
(0029) SPDR = SPI_tx_buff[tx_rd_index]; //发送一个字节数据,并调整指针
0085 E689 LDI R24,0x69
0086 E090 LDI R25,0
0087 91E00063 LDS R30,tx_rd_index
0089 27FF CLR R31
008A 0FE8 ADD R30,R24
008B 1FF9 ADC R31,R25
008C 8020 LDD R2,Z+0
008D B82F OUT 0x0F,R2
(0030) SPI_ok=0;
008E 2422 CLR R2
008F 92200061 STS SPI_ok,R2
(0031) if (++tx_rd_index == SIZE) tx_rd_index = 0;
0091 91800063 LDS R24,tx_rd_index
0093 5F8F SUBI R24,0xFF
0094 2E28 MOV R2,R24
0095 92200063 STS tx_rd_index,R2
0097 3684 CPI R24,0x64
0098 F419 BNE 0x009C
0099 2422 CLR R2
009A 92200063 STS tx_rd_index,R2
(0032) }
009C 9029 LD R2,Y+
009D BE2F OUT 0x3F,R2
009E 91F9 LD R31,Y+
009F 91E9 LD R30,Y+
00A0 9199 LD R25,Y+
00A1 9189 LD R24,Y+
00A2 9029 LD R2,Y+
00A3 9518 RETI
(0033) }
(0034)
(0035) unsigned char getSPIchar(void)
(0036) {
(0037) unsigned char data;
(0038) while (rx_counter == 0); //无接收数据,等待
_getSPIchar:
data --> R16
00A4 90200066 LDS R2,rx_counter
00A6 2022 TST R2
00A7 F3E1 BEQ 0x00A4
(0039) data = SPI_rx_buff[rx_rd_index]; //从接收缓冲区取出一个SPI收到的数据
00A8 EC8D LDI R24,0xCD
00A9 E090 LDI R25,0
00AA 91E00067 LDS R30,rx_rd_index
00AC 27FF CLR R31
00AD 0FE8 ADD R30,R24
00AE 1FF9 ADC R31,R25
00AF 8100 LDD R16,Z+0
(0040) if (++rx_rd_index == SIZE) rx_rd_index = 0; //调整指针
00B0 91800067 LDS R24,rx_rd_index
00B2 5F8F SUBI R24,0xFF
00B3 2E28 MOV R2,R24
00B4 92200067 STS rx_rd_index,R2
00B6 3684 CPI R24,0x64
00B7 F419 BNE 0x00BB
00B8 2422 CLR R2
00B9 92200067 STS rx_rd_index,R2
(0041) CLI();
00BB 94F8 BCLR 7
(0042) --rx_counter;
00BC 91800066 LDS R24,rx_counter
00BE 5081 SUBI R24,1
00BF 93800066 STS rx_counter,R24
(0043) SEI();
00C1 9478 BSET 7
(0044) return data;
00C2 9508 RET
(0045) }
(0046)
(0047) void putSPIchar(char c)
(0048) {
(0049) while (tx_counter == SIZE);//发送缓冲区满,等待
_putSPIchar:
c --> R16
00C3 91800062 LDS R24,tx_counter
00C5 3684 CPI R24,0x64
00C6 F3E1 BEQ 0x00C3
(0050) CLI();
00C7 94F8 BCLR 7
(0051) if (tx_counter || (SPI_ok==0))//发送缓冲区已中有待发数据
00C8 2388 TST R24
00C9 F421 BNE 0x00CE
00CA 90200061 LDS R2,SPI_ok
00CC 2022 TST R2
00CD F4C9 BNE 0x00E7
(0052) { //或SPI正在发送数据时
(0053) SPI_tx_buff[tx_wr_index] = c; //将数据放入发送缓冲区排队
00CE E689 LDI R24,0x69
00CF E090 LDI R25,0
00D0 91E00064 LDS R30,tx_wr_index
00D2 27FF CLR R31
00D3 0FE8 ADD R30,R24
00D4 1FF9 ADC R31,R25
00D5 8300 STD Z+0,R16
(0054) if (++tx_wr_index == SIZE) tx_wr_index = 0; //调整指针
00D6 91800064 LDS R24,tx_wr_index
00D8 5F8F SUBI R24,0xFF
00D9 2E28 MOV R2,R24
00DA 92200064 STS tx_wr_index,R2
00DC 3684 CPI R24,0x64
00DD F419 BNE 0x00E1
00DE 2422 CLR R2
00DF 92200064 STS tx_wr_index,R2
(0055) ++tx_counter;
00E1 91800062 LDS R24,tx_counter
00E3 5F8F SUBI R24,0xFF
00E4 93800062 STS tx_counter,R24
(0056) }
00E6 C001 RJMP 0x00E8
(0057) else
(0058) SPDR = c; //发送缓冲区中空且SPI口空闲,直接放入SPDR由SIP口发送
00E7 B90F OUT 0x0F,R16
(0059) SPI_ok=0;
00E8 2422 CLR R2
00E9 92200061 STS SPI_ok,R2
(0060) SEI();
00EB 9478 BSET 7
00EC 9508 RET
(0061) }
(0062)
(0063) //从机模式
(0064) void spi_init(void)
(0065) {
(0066) unsigned char temp;
(0067) //MISO=ouput and MOSI,SCK,SS = input
(0068) DDRB |=BIT(MISO);
_spi_init:
temp --> R16
00ED 9ABE SBI 0x17,6
(0069) PORTB |=BIT(MISO); //MISO上拉电阻有效
00EE 9AC6 SBI 0x18,6
(0070) SPCR = 0xC4; //SPI允许,从机模式,MSB,允许SPI中断 极性方式01,1/4系统时钟速率
00EF EC84 LDI R24,0xC4
00F0 B98D OUT 0x0D,R24
(0071) SPSR = 0x00;
00F1 2422 CLR R2
00F2 B82E OUT 0x0E,R2
(0072) temp = SPSR;
00F3 B10E IN R16,0x0E
(0073) temp = SPDR; //清空SPI,和中断标志,使SPI空闲
00F4 B10F IN R16,0x0F
(0074) SPI_ok=1;
00F5 E081 LDI R24,1
00F6 93800061 STS SPI_ok,R24
(0075) SPI_datain=0;
00F8 92200060 STS SPI_datain,R2
00FA 9508 RET
_main:
data --> Y+0
i --> R20
00FB 9728 SBIW R28,0x8
(0076) }
(0077)
(0078) void main(void)
(0079) {
(0080) unsigned char i=0;
00FC 2744 CLR R20
(0081) unsigned char data[8]={1,2,3,4,5,6,7};
00FD E584 LDI R24,0x54
00FE E090 LDI R25,0
00FF 01FE MOVW R30,R28
0100 E008 LDI R16,0x8
0101 E010 LDI R17,0
0102 93FA ST R31,-Y
0103 93EA ST R30,-Y
0104 939A ST R25,-Y
0105 938A ST R24,-Y
0106 940E0128 CALL asgncblk
(0082) CLI(); //关中断
0108 94F8 BCLR 7
(0083) spi_init(); //初始化SPI接口
0109 DFE3 RCALL _spi_init
(0084) SEI(); //开中断
010A 9478 BSET 7
010B C019 RJMP 0x0125
(0085) while(1)
(0086) {
(0087) if(SPI_datain)
010C 90200060 LDS R2,SPI_datain
010E 2022 TST R2
010F F0A9 BEQ 0x0125
(0088) {
(0089) for (i=0;i<7;i++)
0110 2744 CLR R20
0111 C00E RJMP 0x0120
(0090) {
(0091) if(getSPIchar()==0xAA)
0112 DF91 RCALL _getSPIchar
0113 3A0A CPI R16,0xAA
0114 F441 BNE 0x011D
(0092) putSPIchar(data[i]);
0115 01CE MOVW R24,R28
0116 2FE4 MOV R30,R20
0117 27FF CLR R31
0118 0FE8 ADD R30,R24
0119 1FF9 ADC R31,R25
011A 8100 LDD R16,Z+0
011B DFA7 RCALL _putSPIchar
011C C002 RJMP 0x011F
(0093) else
(0094) putSPIchar(0xee);
011D EE0E LDI R16,0xEE
011E DFA4 RCALL _putSPIchar
011F 9543 INC R20
0120 3047 CPI R20,7
0121 F380 BCS 0x0112
(0095) }
(0096) SPI_datain=0;
FILE: <library>
0122 2422 CLR R2
0123 92200060 STS SPI_datain,R2
0125 CFE6 RJMP 0x010C
0126 9628 ADIW R28,0x8
0127 9508 RET
asgncblk:
0128 93AA ST R26,-Y
0129 93BA ST R27,-Y
012A 93EA ST R30,-Y
012B 93FA ST R31,-Y
012C 920A ST R0,-Y
012D 81AF LDD R26,Y+7
012E 85B8 LDD R27,Y+8
012F 81ED LDD R30,Y+5
0130 81FE LDD R31,Y+6
0131 3000 CPI R16,0
0132 0701 CPC R16,R17
0133 F031 BEQ 0x013A
0134 95C8 LPM
0135 920D ST R0,X+
0136 9631 ADIW R30,1
0137 5001 SUBI R16,1
0138 4010 SBCI R17,0
0139 CFF7 RJMP 0x0131
013A 9009 LD R0,Y+
013B 91F9 LD R31,Y+
013C 91E9 LD R30,Y+
013D 91B9 LD R27,Y+
013E 91A9 LD R26,Y+
013F 9624 ADIW R28,4
0140 9508 RET
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -