📄 spi_test.lst
字号:
__text_start:
__start:
002A E5CF LDI R28,0x5F
002B E0D4 LDI R29,4
002C BFCD OUT 0x3D,R28
002D BFDE OUT 0x3E,R29
002E 52C0 SUBI R28,0x20
002F 40D0 SBCI R29,0
0030 EA0A LDI R16,0xAA
0031 8308 STD Y+0,R16
0032 2400 CLR R0
0033 E6E0 LDI R30,0x60
0034 E0F0 LDI R31,0
0035 E010 LDI R17,0
0036 37ED CPI R30,0x7D
0037 07F1 CPC R31,R17
0038 F011 BEQ 0x003B
0039 9201 ST R0,Z+
003A CFFB RJMP 0x0036
003B 8300 STD Z+0,R16
003C E5E4 LDI R30,0x54
003D E0F0 LDI R31,0
003E E6A0 LDI R26,0x60
003F E0B0 LDI R27,0
0040 E010 LDI R17,0
0041 35E4 CPI R30,0x54
0042 07F1 CPC R31,R17
0043 F021 BEQ 0x0048
0044 95C8 LPM
0045 9631 ADIW R30,1
0046 920D ST R0,X+
0047 CFF9 RJMP 0x0041
0048 940E00FA CALL _main
_exit:
004A CFFF RJMP _exit
_spi_stc_isr:
004B 922A ST R2,-Y
004C 938A ST R24,-Y
004D 939A ST R25,-Y
004E 93EA ST R30,-Y
004F 93FA ST R31,-Y
0050 B62F IN R2,0x3F
0051 922A ST R2,-Y
FILE: F:\IccAvr_Pro\Spi_test.c
(0001) #include <iom16v.h>
(0002) #include <macros.h>
(0003) #include "Display.h"
(0004)
(0005) #define SIZE 10
(0006) #define MOSI PORTB5
(0007) #define MISO PINB6
(0008) #define SCK PORTB7
(0009) #define SS PORTB4
(0010)
(0011) unsigned char SPI_rx_buff[SIZE];
(0012) unsigned char SPI_tx_buff[SIZE];
(0013) unsigned char rx_wr_index,rx_rd_index,rx_counter,rx_buffer_overflow;
(0014) unsigned char tx_wr_index,tx_rd_index,tx_counter,SPI_ok,SPI_datain;
(0015)
(0016) #pragma interrupt_handler spi_stc_isr:11
(0017) void spi_stc_isr(void)
(0018) {
(0019) //PORTB|=BIT(SS);
(0020) SPI_rx_buff[rx_wr_index] = SPDR; //从ISP口读出收到的字节
0052 E783 LDI R24,0x73
0053 E090 LDI R25,0
0054 91E00068 LDS R30,rx_wr_index
0056 27FF CLR R31
0057 0FE8 ADD R30,R24
0058 1FF9 ADC R31,R25
0059 B02F IN R2,0x0F
005A 8220 STD Z+0,R2
(0021) SPI_datain=1;
005B E081 LDI R24,1
005C 93800060 STS SPI_datain,R24
(0022) SPI_ok=1;
005E 93800061 STS SPI_ok,R24
(0023) if (++rx_wr_index == SIZE) rx_wr_index = 0; //放入接收缓冲区,并调整队列指针
0060 91800068 LDS R24,rx_wr_index
0062 5F8F SUBI R24,0xFF
0063 2E28 MOV R2,R24
0064 92200068 STS rx_wr_index,R2
0066 308A CPI R24,0xA
0067 F419 BNE 0x006B
0068 2422 CLR R2
0069 92200068 STS rx_wr_index,R2
(0024) if (++rx_counter == SIZE)
006B 91800066 LDS R24,rx_counter
006D 5F8F SUBI R24,0xFF
006E 2E28 MOV R2,R24
006F 92200066 STS rx_counter,R2
0071 308A CPI R24,0xA
0072 F431 BNE 0x0079
(0025) {
(0026) rx_counter = 0;
0073 2422 CLR R2
0074 92200066 STS rx_counter,R2
(0027) rx_buffer_overflow = 1;
0076 E081 LDI R24,1
0077 93800065 STS rx_buffer_overflow,R24
(0028) }
(0029) if (tx_counter) //如果发送缓冲区中有待发的数据
0079 90200062 LDS R2,tx_counter
007B 2022 TST R2
007C F0D9 BEQ 0x0098
(0030) {
(0031) --tx_counter;
007D 2D82 MOV R24,R2
007E 5081 SUBI R24,1
007F 93800062 STS tx_counter,R24
(0032) //PORTB&=~BIT(SS);
(0033) SPDR = SPI_tx_buff[tx_rd_index]; //发送一个字节数据,并调整指针
0081 E689 LDI R24,0x69
0082 E090 LDI R25,0
0083 91E00063 LDS R30,tx_rd_index
0085 27FF CLR R31
0086 0FE8 ADD R30,R24
0087 1FF9 ADC R31,R25
0088 8020 LDD R2,Z+0
0089 B82F OUT 0x0F,R2
(0034) SPI_ok=0;
008A 2422 CLR R2
008B 92200061 STS SPI_ok,R2
(0035) if (++tx_rd_index == SIZE) tx_rd_index = 0;
008D 91800063 LDS R24,tx_rd_index
008F 5F8F SUBI R24,0xFF
0090 2E28 MOV R2,R24
0091 92200063 STS tx_rd_index,R2
0093 308A CPI R24,0xA
0094 F419 BNE 0x0098
0095 2422 CLR R2
0096 92200063 STS tx_rd_index,R2
(0036) }
0098 9029 LD R2,Y+
0099 BE2F OUT 0x3F,R2
009A 91F9 LD R31,Y+
009B 91E9 LD R30,Y+
009C 9199 LD R25,Y+
009D 9189 LD R24,Y+
009E 9029 LD R2,Y+
009F 9518 RETI
(0037) }
(0038)
(0039) unsigned char getSPIchar(void)
(0040) {
(0041) unsigned char data;
(0042) while (rx_counter == 0); //无接收数据,等待
_getSPIchar:
data --> R16
00A0 90200066 LDS R2,rx_counter
00A2 2022 TST R2
00A3 F3E1 BEQ 0x00A0
(0043) data = SPI_rx_buff[rx_rd_index]; //从接收缓冲区取出一个SPI收到的数据
00A4 E783 LDI R24,0x73
00A5 E090 LDI R25,0
00A6 91E00067 LDS R30,rx_rd_index
00A8 27FF CLR R31
00A9 0FE8 ADD R30,R24
00AA 1FF9 ADC R31,R25
00AB 8100 LDD R16,Z+0
(0044) if (++rx_rd_index == SIZE) rx_rd_index = 0; //调整指针
00AC 91800067 LDS R24,rx_rd_index
00AE 5F8F SUBI R24,0xFF
00AF 2E28 MOV R2,R24
00B0 92200067 STS rx_rd_index,R2
00B2 308A CPI R24,0xA
00B3 F419 BNE 0x00B7
00B4 2422 CLR R2
00B5 92200067 STS rx_rd_index,R2
(0045) CLI();
00B7 94F8 BCLR 7
(0046) --rx_counter;
00B8 91800066 LDS R24,rx_counter
00BA 5081 SUBI R24,1
00BB 93800066 STS rx_counter,R24
(0047) SEI();
00BD 9478 BSET 7
(0048) return data;
00BE 9508 RET
(0049) }
(0050)
(0051) void putSPIchar(char c)
(0052) {
(0053) while (tx_counter == SIZE);//发送缓冲区满,等待
_putSPIchar:
c --> R16
00BF 91800062 LDS R24,tx_counter
00C1 308A CPI R24,0xA
00C2 F3E1 BEQ 0x00BF
(0054) CLI();
00C3 94F8 BCLR 7
(0055) if (tx_counter || (SPI_ok==0))//发送缓冲区已中有待发数据
00C4 2388 TST R24
00C5 F421 BNE 0x00CA
00C6 90200061 LDS R2,SPI_ok
00C8 2022 TST R2
00C9 F4C9 BNE 0x00E3
(0056) { //或SPI正在发送数据时
(0057) SPI_tx_buff[tx_wr_index] = c; //将数据放入发送缓冲区排队
00CA E689 LDI R24,0x69
00CB E090 LDI R25,0
00CC 91E00064 LDS R30,tx_wr_index
00CE 27FF CLR R31
00CF 0FE8 ADD R30,R24
00D0 1FF9 ADC R31,R25
00D1 8300 STD Z+0,R16
(0058) if (++tx_wr_index == SIZE) tx_wr_index = 0; //调整指针
00D2 91800064 LDS R24,tx_wr_index
00D4 5F8F SUBI R24,0xFF
00D5 2E28 MOV R2,R24
00D6 92200064 STS tx_wr_index,R2
00D8 308A CPI R24,0xA
00D9 F419 BNE 0x00DD
00DA 2422 CLR R2
00DB 92200064 STS tx_wr_index,R2
(0059) ++tx_counter;
00DD 91800062 LDS R24,tx_counter
00DF 5F8F SUBI R24,0xFF
00E0 93800062 STS tx_counter,R24
(0060) }
00E2 C004 RJMP 0x00E7
(0061) else
(0062) {
(0063) //PORTB&=~BIT(SS);
(0064) SPDR = c; //发送缓冲区中空且SPI口空闲,直接放入SPDR由SIP口发送
00E3 B90F OUT 0x0F,R16
(0065) SPI_ok=0;
00E4 2422 CLR R2
00E5 92200061 STS SPI_ok,R2
(0066) }
(0067) SEI();
00E7 9478 BSET 7
00E8 9508 RET
(0068) }
(0069)
(0070) //主机模式
(0071) void spi_init(void)
(0072) {
(0073) unsigned char temp;
(0074) DDRB |= BIT(MOSI)|BIT(SCK)|BIT(SS); //MISO=input and MOSI,SCK,SS = output
_spi_init:
temp --> R16
00E9 B387 IN R24,0x17
00EA 6B80 ORI R24,0xB0
00EB BB87 OUT 0x17,R24
(0075) DDRB &=~BIT(MISO);
00EC 98BE CBI 0x17,6
(0076) PORTB|= BIT(SCK)|BIT(MOSI)|BIT(SS); //MISO上拉电阻有效
00ED B388 IN R24,0x18
00EE 6B80 ORI R24,0xB0
00EF BB88 OUT 0x18,R24
(0077) SPCR = 0xD4; //SPI允许,主机模式,MSB,允许SPI中断,极性方式01,1/4系统时钟速率
00F0 ED84 LDI R24,0xD4
00F1 B98D OUT 0x0D,R24
(0078) SPSR = 0x00;
00F2 2422 CLR R2
00F3 B82E OUT 0x0E,R2
(0079) temp = SPSR;
00F4 B10E IN R16,0x0E
(0080) temp = SPDR; //清空SPI,和中断标志,使SPI空闲
00F5 B10F IN R16,0x0F
(0081) SPI_ok=1;
00F6 E081 LDI R24,1
00F7 93800061 STS SPI_ok,R24
00F9 9508 RET
_main:
j --> R20
data --> Y+0
i --> R22
00FA 9725 SBIW R28,5
(0082) }
(0083)
(0084) void main(void)
(0085) {
(0086) unsigned char i=0,j=0;
00FB 2766 CLR R22
00FC 2744 CLR R20
(0087) unsigned char data[5];
(0088)
(0089) CLI(); //关中断
00FD 94F8 BCLR 7
(0090) spi_init(); //初始化SPI接口
00FE DFEA RCALL _spi_init
(0091) SEI(); //开中断
00FF 9478 BSET 7
(0092) PORTB&=~BIT(SS);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -