📄 tlv320aic33 i2c.txt
字号:
.title "i2ctest.asm"
.include "regs.asm"
.include "vectors.asm"
.global _c_int00
.def main ;Must have
stack_len .set 100
sysstack_len .set 100
stack .usect "stack",stack_len ;定义数据堆栈段
sysstack .usect "stack",sysstack_len ;定义系统堆栈段
flag .usect "variable",1
.data
AIC33InitData .word 0x00,0x00,0x02,0x00
;.word 0x04,0x22
;.word 0x06,0x10
.text
main:
bset c54cm ;一种格式表示与54兼容。
.c54cm_off
** INITIALIZE STACK POINTER SP AND SSP **
amov #(stack+stack_len),xsp ;初始化数据堆栈
mov #(sysstack+sysstack_len),ssp ;初始化系统堆栈
;BCLR #ST2 _ AR0LC,ST2-55
;BCLR #ST2 _ AR6LC,ST2-55
bset INTM ;屏蔽可屏蔽中断
nop
nop
mov #00a5h,AC0
nop
nop
mov AC0,mmap(IVPH) ;赋值主中断矢量寄存器
mov AC0,mmap(IVPD) ;赋值中断矢量寄存器
nop
nop
bclr INTM
; rpt #0ffffh
nop
; rpt #0ffffh
nop
** CLOCK **
mov #2192h,AC0
mov AC0,port(#CLKMD) ;200MHz /60
mov #1,*(#flag)
;_c_int00:
; mov #AIC33InitData,AC2
; mov #0x08,AC1
I2C_init:
mov #0000h,port(#I2CMDR) ;复位,配置前先关,否则刚一改就更新会有问题,所有位复位值为1
and #0FEFFh,port(#I2CMDR) ;xa置0,7bit slaverID
and #0FFF8h,port(#I2CMDR) ;数据的位数设定8bit
and #0FFDFh,port(#I2CMDR) ;DLB回环模式关闭
;or #0020h,port(#I2CMDR) ;I2C使能
mov #0000h,port(#I2COAR) ;设定DSP自身I2C模块的地址,区别于其它总线上设备,只有一个主设备,无所谓
mov #0004h,port(#I2CPSC) ;由cpu时钟得到I2C模块时钟 这里200M/(9+1)=20M 60/(4+1)=12M
mov #0037h,port(#I2CCLKL) ;任意分频scl的低电平达到95个I2C模块时钟周期 时钟必须在复位时更新否则不予接受
mov #0037h,port(#I2CCLKH) ;任意分频scl的高电平达到95个I2C模块时钟周期, 这里scl时钟20M/[(95+5)+(95+5)]=100k
rpt #20
nop
or #4000h,port(#I2CMDR) ;FREE模式打开
mov #0ffffh,port(#I2CSTR) ;初始化I2CSTR
;mov port(#I2CSTR),AC0
nop
nop
mov port(#I2CMDR),AC0
mov port(#I2CCLKL),AC1
nop ;----调试时看I2C的外设寄存器有没有写对
I2C_write:
or #0200h,port(#I2CMDR) ;发送模式 TRX=1
mov #0018h,port(#I2CSAR) ;tas5026a的7位I2C地址为0011000
;or #0080h,port(#I2CMDR) ;选择传输格式 RM=1循环发射,RM=0不使用循环发射
or #0400h,port(#I2CMDR) ;主设备MST=1
and #0FFF7h,port(#I2CMDR) ;不使用自由发射模式
or #0020h,port(#I2CMDR) ;取消复位,I2C使能
;or #2000h,port(#I2CMDR)
nop
mov port(#I2CMDR),AC0 ;寄存器是否写正确
nop
rpt #100
nop
;or #0020h,port(#I2CMDR) ;启动I2C
iic_send:
wait_bb: ;判断ICSTR状态寄存器的BB位(bus busy)
mov port(#I2CSTR),AC0
nop
and #1000h,AC0
bcc wait_bb,AC0!=#0
wait_XRDY: ;第4位ICXRDY=1,表明ICDXR传送到ICXSR中并移位到SDA上
mov port(#I2CSTR),AC0
nop
and #0010h,AC0 ;取ICXRDY
bcc wait_XRDY,AC0==#0
*********要读的寄存器地址***************************************
iic_trans:
mov #0x34,port(#I2CDXR)
mov port(#I2CDXR),AC0
;mov AC0,port(#I2CDXR) ;看第一个寄存器默认值为26h
;OR #0002H,port(#I2CSTR)
;NOP
;MOV port(#I2CSTR),AC0
;NOP
and #0F7FFh,port(#I2CMDR) ;STOP=0
or #2000h,port(#I2CMDR) ;开始传输 对于循环发射模式来说一有START,则S-7位slaverID-R/W-A-DXR中数据自动出来
mov port(#I2CMDR),AC0 ;对于一般发射模式来说一有START,则S-7位slaverID-R/W!等待检查A,每送DXR就出一个数据
;mov #0200,port(#I2CDXR)
check_A:
mov port(#I2CSTR),AC0
nop
and #0002h,AC0
bcc iic_send,AC0!=#0 ;检测tas5026a回传的acknowlege
mov port(#I2CMDR),AC0
b I2C_write
;b stop
mov #20000,mmap(CSR) ;cpu的mmr不用声明地址,外设的mmr要声明,单循环寄存器
rpt CSR
nop
nop
nop
******接收第二个数******
and #0FDFFh,port(#I2CMDR)
rpt #10
mov port(#I2CMDR),AC0
nop
;and #0fdffh,port(#I2CMDR) ;接收模式
;mov #0010h,port(#I2CSAR) ;tas5026a的7位I2C地址为0011010
;and #0ff7fh,port(#I2CMDR) ;选择传输格式 rm=0非循环发射
;or #0400h,port(#I2CMDR) ;主设备MST=1
;or #8000h,port(#I2CMDR) ;NACKMOD=1会在下一个确认周期内发送一个NACK
or #2000h,port(#I2CSTR) ;发BB
mov port(#I2CMDR),AC0
wait_bb_2:
mov port(#I2CSTR),AC0
nop
and #1000h,AC0
bcc wait_bb_2,AC0!=#0
and #0F7FFh,port(#I2CMDR) ;STOP=0
or #2000h,port(#I2CMDR) ;开始传输
or #0008h,port(#I2CSTR)
wait_RRDY:
mov port(#I2CSTR),AC0
nop
and #0008h,AC0 ;取RRDY
bcc wait_RRDY,AC0==#0
******寄存器中的内容*********************************************
mov port(#I2CDRR),AC0 ;接收到的数放在AC0中
rpt #10
nop
;mov #20000,mmap(CSR) ;cpu的mmr不用声明地址,外设的mmr要声明
;RPT CSR
;NOP
*******I2C STOP********
stop:
and #0dfffh,port(#I2CMDR) ;STT=0
or #0800h,port(#I2CMDR) ;STP=1
rpt #20
nop
here
nop
b here
no_isr: reti
.end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -