📄 spi_master.s
字号:
.module SPI_master.c
.area text(rom, con, rel)
.dbfile F:\IccAvr_Pro\SPI_master.c
.area vector(rom, abs)
.org 40
jmp _spi_stc_isr
.area text(rom, con, rel)
.dbfile F:\IccAvr_Pro\SPI_master.c
.dbfunc e spi_stc_isr _spi_stc_isr fV
.even
_spi_stc_isr::
st -y,R2
st -y,R24
st -y,R25
st -y,R30
st -y,R31
in R2,0x3f
st -y,R2
.dbline -1
.dbline 10
; #include "SPI_master.h"
;
; unsigned char SPI_rx_buff[SIZE];
; unsigned char SPI_tx_buff[SIZE];
; unsigned char rx_wr_index,rx_rd_index,rx_counter,rx_buffer_overflow;
; unsigned char tx_wr_index,tx_rd_index,tx_counter,SPI_ok,SPI_datain,temp;
;
; #pragma interrupt_handler spi_stc_isr:11
; void spi_stc_isr(void)
; {
.dbline 12
; //PORTB|=BIT(SS);
; if (tx_counter) //如果发送缓冲区中有待发的数据
lds R2,_tx_counter
tst R2
breq L2
.dbline 13
; {
.dbline 14
; --tx_counter;
mov R24,R2
subi R24,1
sts _tx_counter,R24
.dbline 16
;
; SPDR = SPI_tx_buff[tx_rd_index]; //发送一个字节数据,并调整指针
ldi R24,<_SPI_tx_buff
ldi R25,>_SPI_tx_buff
lds R30,_tx_rd_index
clr R31
add R30,R24
adc R31,R25
ldd R2,z+0
out 0xf,R2
.dbline 17
; SPI_ok=0;
clr R2
sts _SPI_ok,R2
.dbline 18
; if (++tx_rd_index == SIZE) tx_rd_index = 0;
lds R24,_tx_rd_index
subi R24,255 ; addi 1
mov R2,R24
sts _tx_rd_index,R2
cpi R24,100
brne L4
.dbline 18
clr R2
sts _tx_rd_index,R2
L4:
.dbline 19
; }
L2:
.dbline 20
; SPI_rx_buff[rx_wr_index] = SPDR; //从ISP口读出收到的字节
ldi R24,<_SPI_rx_buff
ldi R25,>_SPI_rx_buff
lds R30,_rx_wr_index
clr R31
add R30,R24
adc R31,R25
in R2,0xf
std z+0,R2
.dbline 22
;
; SPI_datain=1;
ldi R24,1
sts _SPI_datain,R24
.dbline 23
; SPI_ok=1;
sts _SPI_ok,R24
.dbline 24
; if (++rx_wr_index == SIZE) rx_wr_index = 0; //放入接收缓冲区,并调整队列指针
lds R24,_rx_wr_index
subi R24,255 ; addi 1
mov R2,R24
sts _rx_wr_index,R2
cpi R24,100
brne L6
.dbline 24
clr R2
sts _rx_wr_index,R2
L6:
.dbline 25
lds R24,_rx_counter
subi R24,255 ; addi 1
mov R2,R24
sts _rx_counter,R2
cpi R24,100
brne L8
.dbline 26
.dbline 27
clr R2
sts _rx_counter,R2
.dbline 28
ldi R24,1
sts _rx_buffer_overflow,R24
.dbline 29
L8:
.dbline -2
L1:
ld R2,y+
out 0x3f,R2
ld R31,y+
ld R30,y+
ld R25,y+
ld R24,y+
ld R2,y+
.dbline 0 ; func end
reti
.dbend
.dbfunc e getSPIchar _getSPIchar fc
; data -> R16
.even
_getSPIchar::
.dbline -1
.dbline 34
; if (++rx_counter == SIZE)
; {
; rx_counter = 0;
; rx_buffer_overflow = 1;
; }
; //PORTB&=~BIT(SS);
; }
;
; unsigned char getSPIchar(void)
; {
L11:
.dbline 36
L12:
.dbline 36
; unsigned char data;
; while (rx_counter == 0); //无接收数据,等待
lds R2,_rx_counter
tst R2
breq L11
.dbline 37
; data = SPI_rx_buff[rx_rd_index]; //从接收缓冲区取出一个SPI收到的数据
ldi R24,<_SPI_rx_buff
ldi R25,>_SPI_rx_buff
lds R30,_rx_rd_index
clr R31
add R30,R24
adc R31,R25
ldd R16,z+0
.dbline 38
; if (++rx_rd_index == SIZE) rx_rd_index = 0; //调整指针
lds R24,_rx_rd_index
subi R24,255 ; addi 1
mov R2,R24
sts _rx_rd_index,R2
cpi R24,100
brne L14
.dbline 38
clr R2
sts _rx_rd_index,R2
L14:
.dbline 39
; CLI();
cli
.dbline 40
; --rx_counter;
lds R24,_rx_counter
subi R24,1
sts _rx_counter,R24
.dbline 41
; SEI();
sei
.dbline 42
; return data;
.dbline -2
L10:
.dbline 0 ; func end
ret
.dbsym r data 16 c
.dbend
.dbfunc e putSPIchar _putSPIchar fV
; c -> R16
.even
_putSPIchar::
.dbline -1
.dbline 46
; }
;
; void putSPIchar(char c)
; {
L17:
.dbline 47
L18:
.dbline 47
; while (tx_counter == SIZE);//发送缓冲区满,等待
lds R24,_tx_counter
cpi R24,100
breq L17
.dbline 48
; CLI();
cli
.dbline 49
; if (tx_counter || (SPI_ok==0))//发送缓冲区已中有待发数据
tst R24
brne L22
lds R2,_SPI_ok
tst R2
brne L20
L22:
.dbline 50
; { //或SPI正在发送数据时
.dbline 51
; SPI_tx_buff[tx_wr_index] = c; //将数据放入发送缓冲区排队
ldi R24,<_SPI_tx_buff
ldi R25,>_SPI_tx_buff
lds R30,_tx_wr_index
clr R31
add R30,R24
adc R31,R25
std z+0,R16
.dbline 52
; if (++tx_wr_index == SIZE) tx_wr_index = 0; //调整指针
lds R24,_tx_wr_index
subi R24,255 ; addi 1
mov R2,R24
sts _tx_wr_index,R2
cpi R24,100
brne L23
.dbline 52
clr R2
sts _tx_wr_index,R2
L23:
.dbline 53
; ++tx_counter;
lds R24,_tx_counter
subi R24,255 ; addi 1
sts _tx_counter,R24
.dbline 54
; }
xjmp L21
L20:
.dbline 56
; else
; {
.dbline 58
; //PORTB&=~BIT(SS);
; SPDR = c; //发送缓冲区中空且SPI口空闲,直接放入SPDR由SIP口发送
out 0xf,R16
.dbline 59
; temp=SPDR;
in R2,0xf
sts _temp,R2
.dbline 60
; SPI_ok=0;
clr R2
sts _SPI_ok,R2
.dbline 61
; }
L21:
.dbline 62
; SEI();
sei
.dbline -2
L16:
.dbline 0 ; func end
ret
.dbsym r c 16 c
.dbend
.dbfunc e spi_init _spi_init fV
.even
_spi_init::
.dbline -1
.dbline 67
; }
;
; //主机模式
; void spi_init(void)
; {
.dbline 68
; DDRB |= BIT(MOSI)|BIT(SCK)|BIT(SS); //MISO=input and MOSI,SCK,SS = output
in R24,0x17
ori R24,176
out 0x17,R24
.dbline 69
; DDRB &=~BIT(MISO);
cbi 0x17,6
.dbline 70
; PORTB|= BIT(SCK)|BIT(MOSI)|BIT(SS); //MISO上拉电阻有效
in R24,0x18
ori R24,176
out 0x18,R24
.dbline 71
; SPCR = 0xD4; //SPI允许,主机模式,MSB,允许SPI中断,极性方式01,1/4系统时钟速率
ldi R24,212
out 0xd,R24
.dbline 72
; SPSR = 0x00;
clr R2
out 0xe,R2
.dbline 73
; temp = SPSR;
in R2,0xe
sts _temp,R2
.dbline 74
; temp = SPDR; //清空SPI,和中断标志,使SPI空闲
in R2,0xf
sts _temp,R2
.dbline 75
; SPI_ok=1;
ldi R24,1
sts _SPI_ok,R24
.dbline 76
; SPI_datain=0;
clr R2
sts _SPI_datain,R2
.dbline -2
L25:
.dbline 0 ; func end
ret
.dbend
.area bss(ram, con, rel)
.dbfile F:\IccAvr_Pro\SPI_master.c
_temp::
.blkb 1
.dbsym e temp _temp c
_SPI_datain::
.blkb 1
.dbsym e SPI_datain _SPI_datain c
_SPI_ok::
.blkb 1
.dbsym e SPI_ok _SPI_ok c
_tx_counter::
.blkb 1
.dbsym e tx_counter _tx_counter c
_tx_rd_index::
.blkb 1
.dbsym e tx_rd_index _tx_rd_index c
_tx_wr_index::
.blkb 1
.dbsym e tx_wr_index _tx_wr_index c
_rx_buffer_overflow::
.blkb 1
.dbsym e rx_buffer_overflow _rx_buffer_overflow c
_rx_counter::
.blkb 1
.dbsym e rx_counter _rx_counter c
_rx_rd_index::
.blkb 1
.dbsym e rx_rd_index _rx_rd_index c
_rx_wr_index::
.blkb 1
.dbsym e rx_wr_index _rx_wr_index c
_SPI_tx_buff::
.blkb 100
.dbsym e SPI_tx_buff _SPI_tx_buff A[100:100]c
_SPI_rx_buff::
.blkb 100
.dbsym e SPI_rx_buff _SPI_rx_buff A[100:100]c
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -