📄 m8twi.asm
字号:
.include "m8def.inc"
.def data=r20 ;数据寄存
.def sub_addr=r19 ;片内子地址
.def status=r18 ;校验特征字
;****************中断入口****************************
reset:
rjmp begin
reti ; Addr $01
reti ; Addr $02
reti ; Addr $03
reti ; Addr $04
reti ; Addr $05
reti ; Addr $06
reti ; Addr $07
reti ; Addr $08
reti ; Addr $09
reti ; Addr $0A
reti ; Addr $0B
reti ; Addr $0C
reti ; Addr $0D
reti ; Addr $0E
reti ; Addr $0F
reti ; Addr $10
;*********************测试程序*****************************
begin:
ldi r16,low(ramend) ;设置堆栈
out spl,r16
ldi r16,high(ramend)
out sph,r16
ldi r16,0x30 ;初始化portd,设置为输出,带上拉
out portc,r16
ldi r16,0xcf
out ddrc,r16
sbi portc,2 ;使led0亮,测试用。表示即将写数据
ldi r16,0x32 ;配置twi的比特率
out twbr,r16
ldi sub_addr,0x00 ;置子地址为0x00
next: mov data,sub_addr ;置数据=子地址
rcall i2c_write ;写入一字节
rcall delay ;延时,等待写周期的完成
inc sub_addr ;子地址加一
cpi sub_addr,0x00 ;判断地址是否为0x00,即是否写完256字节?
brne next ;没,则继续
cbi portc,2 ;全部写完,使led0灭,表示写完256字节
ldi sub_addr,0x00 ;置子地址为0x00
kk: rcall i2c_read ;读一字节
cp data,sub_addr ;判断读出的数据是否等于子地址,即是否等于写入的数据?
brne here ;不等,停止读出
inc sub_addr ;等,地址加一
cpi sub_addr,0x00 ;是否读满256字节?
brne kk ;没有,继续
sbi portc,1 ;已全读出,且全正确,则置led3亮,表示校验正确
here: rjmp here ;完成测试
;*************I2C写子程序*******************
i2c_write:
ldi status,0x08
rcall start ;start
ldi r17,0xa0
ldi status,0x18
rcall tx_data ;device address
mov r17,sub_addr
ldi status,0x28
rcall tx_data ;sub_address
mov r17,data
rcall tx_data ;data to be written
rcall stop ;stop
ret
;*************I2c读子程序*******************
i2c_read:
ldi status,0x08
rcall start ;start
ldi r17,0xa0
ldi status,0x18
rcall tx_data ;device address
mov r17,sub_addr
ldi status,0x28
rcall tx_data ;sub_address
ldi status,0x10
rcall start ;repeat start
ldi status,0x40
ldi r17,0xa1
rcall tx_data ;sla+r
rcall rx_data ;read one byte
rcall stop ;stop
ldi r16,(0<<twen);close TWI
out twcr,r16
ret
;*************I2C_START***********************
start:
ldi r16,(1<<twint)|(1<<twsta)|(1<<twen)
out twcr,r16
nop
nop
wait1: nop
in r16,twcr
sbrs r16,twint ;sbis twcr,twint
rjmp wait1
in r16,twsr
andi r16,0xf8
cp r16,status ;start?
brne error1
ret
;*************I2C发送************************
tx_data:
out twdr,r17
nop
nop
ldi r16,(1<<twint)|(1<<twen)
out twcr,r16
nop
nop
wait3: nop
in r16,twcr
sbrs r16,twint
rjmp wait3
in r16,twsr
andi r16,0xf8
cp r16,status
brne error3
ret
;*************I2C接收*******************
rx_data:
ldi r16, (1<<TWINT) | (1<<TWEN)
out TWCR, r16
nop
nop
wait4: in r16, TWCR
sbrs r16, TWINT
rjmp wait4
in r16, TWSR
andi r16,0xf8
cpi r16, 0x58 ; MR_DATA_NACK
brne error4
in data, TWDR
ret
;**************I2C_STOP***********************
stop:
ldi r16,(1<<twint)|(1<<twen)|(1<<twsto)
out twcr,r16
nop
nop
ret
;***************校验应答出错*****************
error1: nop
error2: nop
error3: nop
error4:
sbi portc,3 ;置led1亮,表示应答出错
ret
;****************延时5ms**********************
delay: ldi r17,0xff
dy: ldi r16,0xff
dly: dec r16
brne dly
dec r17
brne dy
ret
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -