📄 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 + -