?? m16-spi.asm
字號:
//程序目的:熟悉SPI通訊方式
//程序內容:兩個M16之間SPI交換數據。SPI中斷方式
//實現功能:把各自SRAM中$100,$101,$102,$103這4個字節傳送給對方,并把對方傳來的4字節數據送到SRAM的$110,$111,$112,$113中
;沒有按鍵時,顯示0,每復制完一個字節,就加1顯示,
//日期:2008-5-22
//版本:Ver.1
//主控程序
.include"m16def.inc"
.def spi_rd_temp=r2 ;暫存從機交換來的數據
.def temp=r16
.def counter=r17 ;顯示數字暫存器
.def led_ce=r18 ;LED片選暫存器
.def cnt=r19 ;數據塊字節計數
.def spi_td_temp=r20 ;發送數據塊暫存器
.equ block_td=$0100
.equ block_rd=$0110
.org $000
rjmp reset
.org $014
rjmp SPI_STC ;SPI串行中斷
.org $026
reset:
ldi temp,low(RAMEND)
out SPL,temp
ldi temp,high(RAMEND)
out SPH,temp
clr counter
ser temp
out ddra,temp ;PA口作輸出
clr temp ;PA口關閉上拉
out porta,temp
ldi temp,$7f ;PC口高位作輸入,低7位作輸出
out ddrc,temp
ldi temp,$00 ;PC口高位上位,7位關閉上拉
out portc,temp
ldi temp,$a0
out ddrb,temp ;PB口除PB7(SCK),PB5(MOSI)為輸出外,其它(如SS)設為輸入
ldi temp,$d1 ;開SPI中斷,開啟SPI,高位先傳輸,主機方式,空閑時為低電平, 傳輸速率為fosc/16
out spcr,temp
sei ;開總中斷
;******************************
ldi xl,low(block_td) ;設置發送數據塊的起始地址$0100
ldi xh,high(block_td)
ldi cnt,4 ;數據塊的字節為4(即4個字節)
ldi temp,5 ;要發送的數據是5,6,7,8
sts $0100,temp
ldi temp,6
sts $0101,temp
ldi temp,7
sts $0102,temp
ldi temp,8
sts $0103,temp
ldi yl,low(block_rd) ;設置接收數據塊的起始地址$0110
ldi yh,low(block_rd)
ldi temp,0 ;設接收塊地址中的數據清0
sts $0110,temp
sts $0111,temp
sts $0112,temp
sts $0113,temp
//*********主程序**************
main:
scan_key: ;按鍵掃描
in temp,pinc ;讀PC口的狀態到寄存器
sbrc temp,7 ;判斷第7位是否為0
rjmp display_0 ;不為0則跳到顯示0
rjmp spi_tx_d ;為0則啟動SPI,發送數據
spi_tx_d: ;發送數據塊
ld spi_td_temp,x+ ;讀數據塊的第一個字節
out spdr,spi_td_temp ;發送第一個字節
here:rjmp here ;等待中斷
spi_in_d:
in spi_rd_temp,spdr ;讀從機交換過來的數據
st y+,spi_rd_temp ;保存到SRAM的以地址$0110為首的地方
dec cnt ;判斷4個字節是否接收完畢
brne go_on ;如沒有,則繼續接收
clr temp ;接收完,SPI停止運行
out spcr,temp
rjmp main
go_on: ;繼續發送和接收
rjmp main
ret
//*************************
SPI_STC: ;SPI中斷程序
in temp,sreg
push temp ;保存狀態
inc counter ;計數加1
rcall display ;顯示發送字節的次數
SPI_STC_RET: ;中斷返回
pop temp
out sreg,temp
reti
//********通訊時顯示************
TAB: ;0 1 2 3 4 5 6 7 8 9 o u t - _ F;共陽極
.DB 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x00,0xc6,0x40,0x86,0x8e
display:
ldi led_ce,0
out portc,led_ce ;清LED
ldi led_ce,$08
out portc,led_ce ;片選第4個LED
ldi zh,high(TAB*2)
ldi zl,low(TAB*2)
add zl,counter
lpm
out porta,r0
rcall delay ;顯示延時
ret
;*******在沒有通訊時候,顯示0************
display_0:
ldi led_ce,0
out portc,led_ce ;清LED
ldi led_ce,$08
out portc,led_ce ;片選第4個LED
ldi temp,$c0
out porta,temp ;顯示0
rcall delay ;顯示延時
rjmp scan_key
//******延時**************
delay:
ldi temp,$30
push temp
m1: push temp
m2: push temp
brne m3
m3: dec temp
pop temp
dec temp
brne m2
pop temp
dec temp
brne m1
pop temp
dec temp
brne delay
ret
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -