⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 m8twi.asm

📁 使用ATMEGA8L单片机做的两线串行接口TWI的功能
💻 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 + -