STC单片机SPI实现PLC功能扩展单元联接总线
用STC单片机SPI实现PLC功能扩展单元联接总线1,PLC梯形图指令主要是解决算法结构和数据的读写和操作方式。为了实现用有限的梯形图指令实现无限的功能扩展,必须特殊功能放置到功能扩展单元。PLC主机与功能扩展单元的总线连接必须有软件协议栈支撑,必须实现透明实时传输,队列传输,事件触发传输这三种数据传输方式。透明实时传输就是我们熟知基本I/O方式。队列传输要保证一段数据传输的先后次序及数据完整性。事件传输就是每次数据传输有一次完整的应答握手。
2,总线采用32字节加2字节CRC效验固定数据块长度传输方式,也就是不管那种传输方式每次同步双向传输34个字节。因为PLC的可靠性不能允许错误数据,所以必须每次传输进行数据完整性效验。
3,SPI是STC单片机效率和速率非常高的数据传输接口,所以主机采用查询等待方式(关闭中断),也就是必须等待34字节数据双向传输完成,这样就可以与PLC整体输入输出扫描实现数据同步,避开复杂的时序同步算法。
4,由于SPI接口的输入输出同步传输属性,无法给从机等待时间。所以从机采用双缓冲中断传输机制。这样只需一个信号切换量需要数据保护就可以完成从机的快速中断响应。当然双缓冲就使得数据序列,读写完整性保护算法比较复杂。
代码比较复杂,给大家展示部分代码。供参考
;主机部分代码节选
EXB0 equ p4.7
EXB1 equ p5.4
;
SPISS0 equ P1.2 ;SPI slave select, connect to slave' SS(P1.3) pin
SPISS1 equ P1.6 ;SPI slave select, connect to slave' SS(P1.4) pin
;------------
CheckExt0: ;check if Extand 0 is valid
;resault put to Extand0Valid
setb EXB0
mov c,EXB0
jnc chckex0
clr Extand0Valid ;extand modula 0 is not valid
ret
chckex0:setb Extand0Valid ;extand modula 0 is valid
ret
;-----------------------------------------------------------------------
CheckExt1: ;check if Extand 0 is valid
;resault put to Extand0Valid
; clr SPISS1
setb EXB1
mov c,EXB1
jnc chckex1
clr Extand1Valid ;extand modula 0 is not valid
ret
chckex1:setb Extand1Valid ;extand modula 0 is valid
ret
;----------------------------------------------------------------------------------------------------
INIT_SPI: ;Initial SPI to access data
; clr SPISS1
setb SPISS1 ;for STW15W4K
MOV SPDAT,#0 ;initial SPI data
MOV SPSTAT,#(SPIF OR WCOL) ;clear SPI status
;SPDHH EQU 000H ;SPR1=0, SPR0=0, CPU_CLK/4
;SPDH EQU 001H ;SPR0 CPU_CLK/8
;SPDL EQU 002H ;SPR1 CPU_CLK/16
;SPDLL EQU 003H ;SPR1=1, SPR0=1, CPU_CLK/32
MOV SPCTL,#(SSIG OR SPEN OR MSTR OR SPDLL) ;master mode with CPU_CLK/32
anl IE2,#DISPI ;disable interrupt
; orl IE2,#ESPI ;enable SPI interrupt
RET
;--------------------------------------------------------------------------------------------------
ExtCheckByte: ;check ifSPI frame is OK?
;RETURN A ==0 frame OK
; ELSE frame error
mov r2,#SPI_TABLE_SIZE
mov r0,#Spi_In_Table
lcall CheckCRC
ret
;从机部分代码
;-----------------------------------------------------------------
;** SPI Access routine
;-------------------------------------------------------------------
;//#define MASTER //define:master undefine:slave
SPIF EQU 080H ;SPSTAT.7
WCOL EQU 040H ;SPSTAT.6
SSIG EQU 080H ;SPCTL.7
SPEN EQU 040H ;SPCTL.6
DORD EQU 020H ;SPCTL.5
MSTR EQU 010H ;SPCTL.4
CPOL EQU 008H ;SPCTL.3
CPHA EQU 004H ;SPCTL.2
SPDHH EQU 000H ;CPU_CLK/4
SPDH EQU 001H ;CPU_CLK/16
SPDL EQU 002H ;CPU_CLK/64
SPDLL EQU 003H ;CPU_CLK/128
;
SPI_P4 EQU 20h ;SPI bits selector to P4
SPI_S0 equ 04H
SPI_S1 equ 08h ;SPI select
;SPI_S1:SPI_S0
;00 P1.2SS P1.3MOSIP1.4MISO P1.5SCLK
;01 P2.4SS P2.3MOSIP2.2MISO P2.1SCLK
;10 P5.4SS P4.0MOSIP4.1MISO P4.3SCLK
;11 Invalid
ADRJ EQU 04h ;10 bits ready mask
;
;EADC_SPI equ IE.5
ESPI equ 02h ;IE2.1
;
ENEXT equ p4.4
PSSS0 equ p4.0
;
;P4SW equ 0BBh ;port4 switch setting bits
;
;START 0FFh
;END 07Eh
;Change char 05Fh
; 0FFh change it as 05Fh, 05Dh
; 07Eh change it as 05Fh, 05Eh
; 07Fh change it as 05Fh, 05Fh
EX_CHANGE_START equ 0FEh
EX_CHANGE_END equ 7Eh
EX_CHANGE_CG equ 5Fh
EX_CHANGE_CS equ 5Dh
EX_CHANGE_CE equ 5Eh
;
INIT_SPI: ;Initial SPI to access data
; clr ENEXT
anl AUXR1,#(NOT(SPI_S0))
orl AUXR1,#SPI_S1 ;SPI_S1:SPI_S0=10 P5.4SS P4.0MOSIP4.1MISO P4.3SCLK
MOV SPDAT,#02h ;initial SPI data
MOV SPSTAT,#(SPIF OR WCOL) ;clear SPI status
MOV SPCTL,#(SPEN) ; OR SSIG) ; OR MSTR) ;SSIG) ;slave mode for ext
orl IE2,#ESPI
;
; clr ENEXT ;enable MISO
;
clr SpiDataReady
clr SpiInCharChanged ;if change char sent to and secong char is in
clr SpiOutCharChanged ;if change char sent to and secong char is out
clr SpiInFrameEnd
clr SpiOutFrameEnd
clr SpiTraslated
setb PSSS0Check ;PSSS0 not setting
;
mov a,#EX_CHANGE_END
mov r0,#Spi_In_End_Ch1
movx @r0,a
mov r0,#Spi_In_End_Ch2
movx @r0,a
;
RET
;------------------------------------------------------------------------
SpiEnableCheck: ;check PSSS0 wait it to low an enable SPI
jnb PSSS0Check,spienb3 ;PSSS0
mov c,PSSS0 ;get pin signal
jc spienb2
nop
nop
mov c,PSSS0 ;get pin signal
jc spienb2
clr PSSS0Check
orl SPCTL,#(SPEN OR SSIG) ;MSTR) ;SSIG) ;slave mode for ext
orl IE2,#ESPI
setb c
ret
spienb3:mov c,PSSS0 ;get pin signal
jnc spienb2
nop
nop
mov c,PSSS0 ;get pin signal
jnc spienb2
setb PSSS0Check
anl SPCTL,#((NOT(SPEN OR SSIG) AND 0FFh)) ;MSTR) ;SSIG) ;slave mode for ext
anl IE2,#(NOT(ESPI))
spienb2:clr c
ret
;------------------------------------------------------------------------
SPI_SWAP: ;exchange data from SPI
;INPUT: A= byte data to translate
;OUTPUT:A= byte data read from master
MOV SPDAT,A ;trigger SPI send
spiswp1:
MOV A,SPSTAT
JNB ACC.7,spiswp1 ;wait send complete
MOV SPSTAT,#(SPIF OR WCOL) ;clear SPI status
MOV A,SPDAT ;return received SPI data
RET
;-----------------------------------------------------------------------------------------------
页:
[1]