DSP.IOPB5—— SCL
WP接地,你说那么简单的一个程序,就是把数据往总线上丢,我怎么都弄不出来呢
用示波器看波形,发现在2407发送数据给铁电时,可以发送A0H,00H,和存放在310H的数据,铁电都给应答,但是到发送311H数据时,铁电就不给应答了
然后读程序时,每次读出来的均为FFH,都不知道哪里错了?
恳请哪位了解该程序的人士能与我一起讨论一下
万分感谢!
QQ:15074535
特把程序粘下面,如调试出来,和大家共享!
.include "240x.h"
.def _c_int0
.text
;-------------------主程序,将0310h开始的RAM的4个数据写入24cl的00h
;----------------------然后将00h的4个数据读出存放在0315h开始的RAM中
_c_int0
CALL SYSYINTEE
CALL LOADDATA ;预先在制定区域写入需写入24CL的数据4个
MAR *,AR1
LAR AR1,#300H ;AR1指向堆栈
SPLK #310H,*+ ;待写数据存放空间的首地址
SPLK #00H,*+ ;24CL的块内地址字节
SPLK #0A0H,*+ ;控制字(R/W=0)
SPLK #4H,* ;待写数据字节数
CALL EEPROM
READ: ;读数据至24LC
CALL SYSYINTEE
LAR AR1,#305H ;AR1指向堆栈
SPLK #315H,*+ ;待读数据存放空间的首地址
SPLK #00H,*+ ;24CL的块内地址字节
SPLK #0A1H,*+ ;控制字(R/W=1)
SPLK #4H,* ;待读数据字节数
CALL EEPROM
BCND READ,NEQ
LOOP:
B LOOP ; 空循环
EEPROM: LDP #225
LAR AR0, *-, AR0 ; AR0:读写的字节数,AR1:指向控制字节
; ARP= AR0
SBRK #1
MAR *, AR1
EEPROM1: CALL I2CStart ;设置I2C总线的开始状态
LACL *+ ;AR1:临时单元
AND #0FEH ;清楚控制字的第0位
SACL *
CALL I2CSendByte ;送出控制字(R/W=0)
CALL I2CRecAck ;检查应答位
BCND EEPROM2, EQ
LACL #1 ;出错
B EEPROMRET
EEPROM2: SBRK #2 ;AR1:24CL的块内地址低字节
;(在此之前AR1指向临时单元,比控制字
;adress多1)
CALL I2CSendByte ; 送出24CL的块内地址字节
CALL I2CRecAck ; 检查应答位
BCND EEPROM3, EQ
LACL #1 ; 出错
B EEPROMRET
EEPROM3: ADRK #1 ;AR1控制字节
BIT *, 15 ;读、写操作判断
BCND EEPROM4, TC
SBRK #2
LAR AR1, * ;AR1:输出数据缓冲区
EEPROM31: CALL I2CSendByte ;写出一个字节数据
CALL I2CRecAck ; 检查应答位
BCND EEPROM30, EQ
LACL #1 ; 出错
B EEPROMRET
EEPROM30: ADRK #1 ;指向下一个字节待写数据
MAR *,AR0
BANZ EEPROM31,AR1
B EEPROM5
EEPROM4: ;读操作
CALL I2CStart ;设置I2C总线开始状态
CALL I2CSendByte ;送出控制字(R/W=1)
CALL I2CRecAck ; 检查应答位
BCND EEPROM40, EQ
LACL #1 ; 出错
B EEPROMRET
EEPROM40:
SBRK #2
LAR AR1,*,AR0 ;AR1:输入数据缓冲区
EEPROM43:
BANZ EEPROM41, AR1
B EEPROM42
EEPROM41:
CALL I2CRecByte ;接受一个字节数据
CALL I2CAck ;产生应答信号
MAR *, AR0
B EEPROM43
EEPROM42:
CALL I2CRecByte ;接受最后一个字节数据
CALL I2CNoAck ;产生应答信号
EEPROM5:
CALL I2CStop ;设置结束状态
LACL #0 ;成功标志ACC=0
EEPROMRET:
RET ;返回
;--------------启动I2C总线――――――――――――――――
I2CStart: CLRC XF ;SCL=0
SBIT1 PBDATDIR, B12_MSK ;设置IOPB4为输出 口
SBIT1 PBDATDIR, B4_MSK ;SDA=1
SETC XF ; SCL=1
RPT #14
NOP ;600ns
SBIT0 PBDATDIR, B4_MSK ; SDA=0
RPT #14
NOP
CLRC XF ;SCL=0
SBIT1 PBDATDIR, B4_MSK ;SDA=1
RET
;------------------------停止I2C总线―――――――――――――
I2CStop: CLRC XF ;SCL=0
SBIT1 PBDATDIR,B12_MSK ;设置IOPB4为输出 口
SBIT0 PBDATDIR, B4_MSK ; SDA=0
SETC XF ; SCL=1
RPT #14
NOP
SBIT1 PBDATDIR, B4_MSK ;SDA=1
RPT #14
NOP
CLRC XF ;SCL=0
RET
;-------------------------------------检查应答位--------------
I2CRecAck:
CLRC XF ;SCL=0
RPT #20H
NOP
SETC XF ; SCL=1
RPT #20H
NOP
SBIT0 PBDATDIR, B12_MSK ;设置IOPB4为输入口
RPT #20H
NOP
LACL PBDATDIR
AND #10H ;返回在ACC中
CLRC XF ;SCL=0
;----------对I2C总线产生应答--------------
I2CAck:
SBIT1 PBDATDIR, B12_MSK ;设置IOPB4为输出 口
SBIT0 PBDATDIR, B4_MSK ; SDA=0
SETC XF ; SCL=1
RPT #14
NOP
CLRC XF ;SCL=0
NOP
SBIT1 PBDATDIR, B4_MSK ;SDA=1
RET
;----------------不对I2C总线产生应答―――――――――――
I2CNoAck:
SBIT1 PBDATDIR, B12_MSK ;设置IOPB4为输出口
SBIT1 PBDATDIR, B4_MSK ;SDA=1
SETC XF ; SCL=1
RPT #14
NOP
CLRC XF ;SCL=0
RET
;----------向I2C总线写入数据------------------
I2CSendByte:
LAR AR2, #7 ;位计数器:8位
LACL * ;AR1:指向待写数据
RPT #7
SFL
SACL *
SBIT1 PBDATDIR, B12_MSK ;;设置IOPB4为输出 口
I2CS3:
CLRC XF ;SCL=0
LACC *, 16
SFL
SACH *, AR2
BCND I2CS1, C
SBIT0 PBDATDIR, B4_MSK ;SDA=0
B I2CS2
I2CS1:
SBIT1 PBDATDIR, B4_MSK ;SDA=1
I2CS2:
SETC XF ; SCL=1
BANZ I2CS3, AR1
CLRC XF ;SCL=0
RET
;――――――――――从I2C总线读取数据――――
I2CRecByte: LAR AR2, #7 ;位计数器:8位
SBIT0 PBDATDIR, B12_MSK ;设置IOPB4为输入口
CLRC XF
RPT #20H
NOP
SPLK #0, *
I2CR1: LACL *
SFL
SACL *
SETC XF ; SCL=1
RPT #3
NOP
LACL PBDATDIR
AND #10H ;返回在ACC中
RPT #3
SFR
OR *
SACL *, AR2
CLRC XF ;SCL=0
NOP
BANZ I2CR1, AR1
ADRK #1 ;AR1:指向下一个存储单元
RET
SYSYINTEE:
SETC INTM
CLRC SXM
CLRC OVM
CLRC CNF ;B0口被配置为数据存储空间
LDP #0E0H
SPLK #8186H,SCSR1 ;CLKIN=10M,CLKOUT=40M
SPLK #0E8H,WDCR ;不使能WDT
LDP #0
SPLK #0000H,IMR ;不使能,中断都被屏蔽
SPLK #0FFFFH,IFR ;清全部中断标志
LDP #225
SBIT0 MCRA,B12_MSK ;设置IOPB4为I/O
RET
LOADDATA:
LDP #6 ;写入4个数据至数据存储区
SPLK #11H,10H
SPLK #22H,11H
SPLK #3H,12H
SPLK #4H,13H
RET