关键字: STC51单片机 SPI接口 通信 汇� �语言
;============================================
;STC12C5410 spi 通信
;单主单从模式
;============================================
;MASTER EQU 1 ;主单片机
MASTER EQU 0 ;从机
;-------------------------------------
;定义COM波特率自动重装常数
;
RELOAD_8BIT_DATA EQU 0F6H; Fosc=18.432 ,4800
;----------------------------------------------------------------------
;定义特殊功能寄存器
AUXR EQU 8EH
; AUXR特殊功能寄存器的BIT3是SPI中断充许控制位ESPI
; IE特殊功能寄存器的BIT5是ADC和SPI两个中断共享的总中断允许控制位EADC_SPI
; 要产生SPI中断,需要ESPI/EADC_SPI/EA都为1
;------------------------------------------------------------------------
;定义SPI特殊功能寄存器
SPCTL EQU 85H;
SPSTAT EQU 84H;
SPDAT EQU 86H;
EADC_SPI EQU IE.5;
;定义SPI引脚
SCLK EQU P1.7;
MISO EQU P1.6;
MOSI EQU P1.5;
SS EQU P1.4;
LED_MCU_START EQU P1.2;-------------TEST
;定义变量
Flags EQU 24H;
SPI_Receive EQU Flags.0;
SPI_buffer EQU 40H; <---------------
;-------------------------------------------------------------------------
ORG 000H
LJMP MAIN;
ORG 002BH;
LJMP ADC_SPI_Interrupt_Routine;
ORG 008H;
MAIN:
CLR LED_MCU_START;点亮灯开始工作
MOV SP,#7FH;
ACALL Init_System; 系统初始化
if MASTER;-------------------------
Check_RS232:
JNB RI,Master_Check_SPI;判断RS232串口是否收到数据
;主单片机RS232已收到数
ACALL Get_Byte_From_RS232;主单片机将收到的数据送A;
ACALL SPI_Send_Byte; 主单片机将A中的数据送到从机SPI
SJMP Check_RS232;
Master_Check_SPI: ; -------------收从机的字发到PC机-----------------------
JNB SPI_Receive,Check_RS232;判收到从SPI发回的数据否
;主单片机已收到新的数据;
MOV A,SPI_buffer; ;将“从SPI发回的数据送A
CLR SPI_Receive ;清0 主单片机SPI端口收到的数据标志位
ACALL RS232_Send_Byte ;将A中的数据发送到PC机;
SJMP Check_RS232;
else
Slave_Check_SPI:
JNB SPI_Receive,Slave_Check_SPI;判收到主SPI发回的数据否
;从单片机SPI端口已收到新的数据
MOV A,SPI_buffer ;取主单片机SPI端口发的数据
CLR SPI_Receive; ; 清0 从单片机SPI端口收到数据标志位
MOV SPDAT,A ;将收到的数据送SPDAT,准备一下次通讯时发回
SJMP Slave_Check_SPI ;
endif
;----------------------------------------------------------------------
ADC_SPI_Interrupt_Routine: ;ADC_SPI中断服务程序
MOV SPSTAT,#11000000B ;0C0H,清0标志位SPIF和WCOL
MOV A,SPDAT ;保存收到的数据
MOV SPI_buffer,A
SETB SPI_Receive ;树立SPI端口收到的数据标志
RETI
;------------------------------------------------------------------------
Init_System:
; ACALL Initial_UART ;初始化串口
ACALL Initial_SPI ;初始化SPI
MOV Flags,#0 ;清标志字
SETB EA ;开总中断
RET
;-------------------------------------------------------------------------
Initial_UART:
;SCON Bit: 7 6 5 4 3 2 1 0
; SM0/FE SM1 SM2 REN TB8 RB8 TI RI
MOV SCON,#50H ;0101,0000 8位可变波特率,无奇偶校验
MOV TMOD,#21H ;T1 为自动重装模式
MOV TH1,#RELOAD_8BIT_DATA
MOV TL1,#RELOAD_8BIT_DATA;
; MOV PCON,#80H; ;取消本行指令注释。波特率加倍
; 以下两行有效,快12倍。即=4800*12=57600
MOV A,#01000000B; ;T1以1T的速度计数, 是普通的12倍
ORL AUXR,A
SETB TR1; ;启动T1开始计数
RET
;---------------------------------------------------------------------------
Initial_SPI: ;初始化SPI
;SPI控制寄存器
; 7 6 5 4 3 2 1 0
;SPCTL SSIG SPEN DORD MSTR CPOL CPHA SPR1 SPR0
if MASTER
MOV SPCTL,#11111100B ;0FCH,忽略SS脚,设为主机
;SSIG=1,忽略SS脚
;SPEN=1,允许SPI工作
;DORD=1,先传低平的LSB
;MSTR=1,设为主机
;CP0L=1,.....
;CPHA=1,.....
;SPR1,SPR0=00,主模式时的SPI时钟源选择为Fosc/4; 01:fosc/16; 10:fosc/64 11:fosc/128
else
MOV SPCTL,#11101100B; ;0ECH,忽略SS脚,设为从机
;SSIG=1,忽略SS脚
;SPEN=1,允许SPI工作
;DORD=1,先传低平的LSB
;MSTR=1,设为主机
;CP0L=1,.....
;CPHA=1,.....
;SPR1,SPR0=00,主模式时的SPI时钟源选择为Fosc/4
endif
MOV SPSTAT,11000000B ;清0标志位SPIF(SPSTAT.7),WCCOL(SPSTAT.6)
;向该两个标志位写1,会将它们清0
MOV A,#00001000B
ORL AUXR,A ;令ESPI(AUXR。3)=1, 充许SPIF(SPSTAT。7)产生中断
SETB EADC_SPI; ;开ADC中断和SPI中断共享的总中断控制位
RET
;----------------------------------------------------------
RS232_Send_Byte: ;RS232串口发送一个字节
CLR TI ;清0串口发送中断标
MOV SBUF,A;
RS232_Send_Wait:
JNB TI,RS232_Send_Wait; ;等待发送完毕,未发完跳回本行
CLR TI ;清0串口发送中断标志
RET
;----------------------------------------------------------
; 此段程序只有主MCU调用
;----------------------------------------------------------
SPI_Send_Byte: ;SPI发送一字节
CLR EADC_SPI; ;关ADC中断和SPI中断共享的总中断控制位
MOV SPDAT,A; ;SPI 发送数据
SPI_Send_Byte_Wait:
MOV A,SPSTAT; ;等待SPIF=1,即等待SPI发送完毕
ANL A,#80H;
JZ SPI_Send_Byte_Wait;
SETB EADC_SPI ;开ADC中断和SPI中断共享的总中断控制位
RET
;------------------------------------------------------------ 附加 不用中断收数,巡检方式
SPI_Receive_Byte:
MOV A,SPSTAT ;是否收到从SPI发回的数据?
ANL A,#80H;
JZ SPI_Receive_Byte; ;未收到数继续等待
MOV A,SPDAT ;已收到数
; .
; .
; .
Get_Byte_From_RS232: ;取RS232串口中收到的数据送A
MOV A,SBUF
CLR RI
RET
;--------------------------------------------------------------
END
;--------------------------------------------------------------