由于本人第一次利用单片机进行项目设计,在许多方面都是菜鸟,而且公司里没有一个懂单片机编程的工程师,所以我既进行单片机外围硬件电路的设计又进行软件程序的编写。现在遇到一件非常困惑的问题,苦于公司无人指导,故特来此请教各位高手。
问题大致如下:
MCU与高频头开始串行通信时有一个START的开始信号,然后送被控器(高频头)的地址到总线,然后再送一个控制字数据后,无法收到被控器的ACK应答信号,程序执行到WAITACKW: MOV C,SDA
JC WAITASCW
无法继续下去[见后附程序],在这我能确定被控器的地址无误。
硬件环境如下:
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: ACALL START ;开始信号
;---------------
MOV A,ADBW ;送被控器地址
ACALL SENDDATE
ACALL ACKW
;---------------
MOV A,DB1 ;送控制字1
ACALL SENDDATE
ACALL ACKW
;---------------
MOV A,DB2 ;送控制字2
ACALL SENDDATE
ACALL ACKW
;---------------
MOV A,CB ;送控制字3
ACALL SENDDATE
ACALL ACKW
;---------------
MOV A,PB ;送控制字4
ACALL SENDDATE
ACALL ACKW
;---------------
ACALL STOP ;停止传送
RET
SENDDATE: MOV R2,#8 ;送数据
LOOPW: RLC A
MOV SDA,C
ACALL DELAY
SETB SCL
ACALL DELAY
CLR SCL
ACALL DELAY
DJNZ R2,LOOPW
CLR SDA
RET
ACKW: ACALL DELAY /*写被控器时等待ACK信号*/
SETB SDA
ACALL DELAY
SETB SCL
ACALL DELAY
WAITACKW: MOV C,SDA
JC WAITASCW
CLR SCL
CLR SDA
RET
START: SETB SCL /*启动信号*/
SETB SDA
ACALL DELAY
CLR SDA
ACALL DELAY
CLR SCL
RET
STOP: CLR SCL /*停止信号*/
CLR SDA
ACALL DELAY
SETB SCL
ACALL DELAY
SETB SDA
ACALL DELAY
RET
DELAY: NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
RET
------解决方案--------------------
从你的说明看,是使用普通IO口软件模拟I2C通讯,所以是否设置SCON,PCON与I2C无关。我常写高频头的控制软件,初步看了看你的代码,没有发现什么问题。重点考虑地址,能说说你使用的是哪家公司的什么型号高频头吗?说不定我知道哦!
------解决方案--------------------
其实,这个具体更要看你高频头的接口说明的...
呵呵,是吧?