I2C总线通信时为什么收不到应答信号[高分求解,如能解决可付RMB]
由于本人第一次利用单片机进行项目设计,在许多方面都是菜鸟,而且公司里没有一个懂单片机编程的工程师,所以我既进行单片机外围硬件电路的设计又进行软件程序的编写。现在遇到一件非常困惑的问题,苦于公司无人指导,故特来此请教各位高手。
问题大致如下:
MCU与高频头开始串行通信时有一个START的开始信号,然后送被控器(高频头)的地址到总线,然后再送一个控制字数据后,无法收到被控器的ACK应答信号,程序执行到WAITACKW:MOVC,SDA
JCWAITASCW
无法继续下去[见后附程序],在这我能确定被控器的地址无误。
硬件环境如下:
1、我用的MCU是AT89S51,目的是为实现利用MCU与被控器进行I2C总线串行通信。
2、定义P3.0与P3.1为SCL与SDA两条总线,MCU的SCL与SDA直接与被控器直连,之间无其他电阻电容元件,然后在两条总线上分别外接4.7K上拉电阻后与+5V连接。
3、晶振频率为11.0952MHZ
目前我分析此问题如下:
1、是否为时序问题或时间延时的问题
2、硬件部分即上拉电阻阻值不对
并有几点疑问:
1、可否用P3口定义SCL与SDA
2、如何确定上拉电阻阻值
3、利用I2C总线进行串行通信前是否需要进行SCON,PCON等寄存器的初始化
附上部分程序代码:
WRITE_TUNER:ACALLSTART ;开始信号
;---------------
MOVA,ADBW ;送被控器地址
ACALLSENDDATE
ACALLACKW
;---------------
MOVA,DB1 ;送控制字1
ACALLSENDDATE
ACALLACKW
;---------------
MOVA,DB2 ;送控制字2
ACALLSENDDATE
ACALLACKW
;---------------
MOVA,CB ;送控制字3
ACALLSENDDATE
ACALLACKW
;---------------
MOVA,PB ;送控制字4
ACALLSENDDATE
ACALLACKW
;---------------
ACALLSTOP ;停止传送
RET
SENDDATE:MOVR2,#8 ;送数据
LOOPW:RLC A
MOVSDA,C
ACALLDELAY
SETBSCL
ACALLDELAY
CLR SCL
ACALLDELAY
DJNZR2,LOOPW
CLR SDA
RET
ACKW:ACALLDELAY /*写被控器时等待ACK信号*/
SETBSDA
ACALLDELAY
SETBSCL
ACALLDELAY
WAITACKW:MOVC,SDA
JCWAITASCW
CLRSCL
CLRSDA
RET
START:SETBSCL /*启动信号*/
SETBSDA
ACALLDELAY
CLR SDA
ACALLDELAY
CLR SCL
RET
STOP:CLR SCL /*停止信号*/
CLR SDA
ACALLDELAY
SETBSCL
ACALLDELAY
SETBSDA
ACALLDELAY
RET
DELAY:NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
RET
[解决办法]
从你的说明看,是使用普通IO口软件模拟I2C通讯,所以是否设置SCON,PCON与I2C无关。我常写高频头的控制软件,初步看了看你的代码,没有发现什么问题。重点考虑地址,能说说你使用的是哪家公司的什么型号高频头吗?说不定我知道哦!
[解决办法]
其实,这个具体更要看你高频头的接口说明的...
呵呵,是吧?
现在是高频头不响应,即使你的通信信道接口没问题,但是,如果高频头的程序里拿不到相应的协议它也会丢包,看看你的高频头的协议要求吧
[解决办法]
俺前几天对付一个32k i2c存储器一直没通,后来发现是SDA、SCL弄反了。。。
[解决办法]
I2C总线协议仔细研究一下,一定会对你有启发!
[解决办法]
1、确定高频头AS引脚内部是否悬空?有些高频头内部有电阻到低哦,保险的做法是你外部直接把AS接地,地址选择0xC0。
2、确定高频头供电是否正常?主要是看1677是否有电,也可以另换一只高频头试试。
3、确定SCL、SDA是否正确?你可以把高频头打开自己对比1677的DataSheet测试一下。
4、看高频头内部SCLSDA上是否已经接了上拉了,一般外部接上来,接10k就可以了。
5、关于软件部分:延时应该够了,Start和Stop也应该是对的