STC SPI 调试求助 (汇编语言)
软件环境 uVision4
硬件环境 STC60S2开发板 STC2052开发板各1个
调试目标 STC60S2(主机)发1个字节, STC2052(从机)收到正确信息后亮灯,采用查询模式(非中断模式,仅求实现调试目标)
连接线路 P1.4 P1.5 P1.6 P1.7共4根线,60S2的1.4作为输出,而2052的1.4是SS,SPI传输过程中,60S2拉低电平
目前遇到的问题
1. 貌似每次主机发送,从机都有响应
2. 可是每一次收到的数据都不一样,而且一般都是错误的
3. 我这个项目的本意是和RF射频模块进行通信,由于SPI通信的问题,我无法和RF模块顺利沟通
4. 资料也没少查,STC的手册也认真看过了的,现在比较茫然,实在是不知道问题可能处在哪里了
再次表示感谢!
【代码如下】
STC60S2代码
; 定义寄存器地址
SPCTL EQU 0CEH
SPSTAT EQU 0CDH
SPDAT EQU 0CFH
ORG 0100H
; 初始化SPI
MOV SPCTL #0D4H ; 0D4H = 11010100, 即【忽略SSIG,使能SPI,MSB高位先发,主机模式,默认SPI时钟极性,默认上升沿驱动,SPI速度模式00】
MOV SPSTAT #0C0H ; 0C0H = 11000000, 对SPIF和WCOL进行写1清零
MOV SPDAT #00H ; 清空SPI缓存
;发送数据
MASTER_SEND:
CLR P1.4; 拉低SS
MOV SPDAT, #00AH ; 测试字节为00001010
CALL SPI_CHECK ; 调用子程序等待SPI传输完
SETB P1.4; SPI传输1字节完成,重新拉高SS电平
JB P3.6, $ ;程序会停在这里等我去按按钮, P3.6在开发板上是个按钮,平时=1,按下去以后=0
CALL TREMBLE_FILTER; 按键去抖动代码(略去)
JNB P3.6, $ ;程序在等按钮抬起来
CALL TREMBLE_FILTER; 再次去抖动
JMP MASTER_SEND; 按钮已经被按下和抬起了,重新执行发送代码
;SPI_CHECK子程序,等待SPI传输完成
SPI_CHECK:
MOV A, SPSTAT
JNB ACC.7, SPI_WCOL ; 如果SPIF=0就去判断WCOL
SETB ACC.7; 否则就重置SPIF
MOV SPSTAT, A
RET
SPI_WCOL:
JNB ACC.6, SPI_CHECK; 如果SPIF=0 而且WCOL=0,就说明SPI没有完成传输,所以跳回去重新等待
SETB ACC.6; 否则就说明是SPIF=0 WCOL=1,是写冲突,处理代码略去,这里仅重新写1清零
MOV SPSTAT, A
RET
END
STC2052的代码如下
; 定义寄存器地址
SPCTL EQU 085H
SPSTAT EQU 084H
SPDAT EQU 086H
ORG 0100H
; 初始化SPI
MOV SPCTL #0C4H ; 0C4H = 11000100, 即【忽略SSIG,使能SPI,MSB高位先发,从机模式,默认SPI时钟极性,默认上升沿驱动,SPI速度模式00】
MOV SPSTAT #0C0H ; 0C0H = 11000000, 对SPIF和WCOL进行写1清零
MOV SPDAT #00H ; 清空SPI缓存
; 侦听SPI
SLAVE_LISTEN:
CALL SPI_CHECK
MOV A, SPDAT
MOV P2, A ; 把SPI缓存中接收到的数据在LED灯上显示出来
JB P3.6, $ ;程序会停在这里等我去按按钮, P3.6在开发板上是个按钮,平时=1,按下去以后=0
CALL TREMBLE_FILTER; 按键去抖动代码(略去)
JNB P3.6, $ ;程序在等按钮抬起来
CALL TREMBLE_FILTER; 再次去抖动
JMP SLAVE_LISTEN ;按钮按过了,重新进入侦听状态
SPI_CHECK:
(和60S2的一样,不写了)
END
又郁闷了几天 看了更多的文章
果断抛弃STC的SPI寄存器,改为I/O口模拟SPI模式的通信。行了
我哭啊。SPI_SWAP代码如下,今后如果有人需要用的话,直接拿走吧
SPI_SWAP:
; DATA TO BE SENT MUST BE IN ACC REGISTER
CLR SPI_CLK
MOV R7, #8
SPI_SWAP_BIT:
CALL SPI_SET_PIN_MOSI_FROM_ACC
SETB SPI_CLK
CALL SPI_GET_FROM_PIN_MISO
CLR SPI_CLK
DJNZ R7, SPI_SWAP_BIT
RET
SPI_SET_PIN_MOSI_FROM_ACC:
RLC A ; MOVE MSB INTO BIT CY, CIRCLE MOVING
JC CY_EQU_ONE
CLR SPI_MOSI
RET
CY_EQU_ONE:
SETB SPI_MOSI
RET
SPI_GET_FROM_PIN_MISO:
JB SPI_MISO, SPI_MISO_EQU_ONE
CLR ACC.0
RET
SPI_MISO_EQU_ONE:
SETB ACC.0
RET