;============================================
;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 000HLJMP 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中的数据送到从机SPISJMP Check_RS232;Master_Check_SPI: ; -------------收从机的字发到PC机-----------------------JNB SPI_Receive,Check_RS232;判收到从SPI发回的数据否;主单片机已收到新的数据;MOV A,SPI_buffer; ;将“从SPI发回的数据送ACLR SPI_Receive ;清0 主单片机SPI端口收到的数据标志位ACALL RS232_Send_Byte ;将A中的数据发送到PC机;SJMP Check_RS232;elseSlave_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和WCOLMOV A,SPDAT ;保存收到的数据MOV SPI_buffer,ASETB SPI_Receive ;建立SPI端口收到的数据标志RETI;------------------------------------------------------------------------Init_System:; ACALL Initial_UART ;初始化串口ACALL Initial_SPI ;初始化SPIMOV 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 RIMOV SCON,#50H ;0101,0000 8位可变波特率,无奇偶校验MOV TMOD,#21H ;T1 为主动重装形式MOV TH1,#RELOAD_8BIT_DATAMOV TL1,#RELOAD_8BIT_DATA;; MOV PCON,#80H; ;撤销本行指令注释。波特率加倍; 以下两行有用,快12倍。即=4800*12=57600MOV A,#01000000B; ;T1以1T的速度计数, 是一般的12倍ORL AUXR,ASETB TR1; ;发动T1开端计数RET;---------------------------------------------------------------------------Initial_SPI: ;初始化SPI;SPI操控寄存器; 7 6 5 4 3 2 1 0;SPCTL SSIG SPEN DORD MSTR CPOL CPHA SPR1 SPR0if MASTERMOV 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/128else 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 endifMOV SPSTAT,11000000B ;清0标志位SPIF(SPSTAT.7),WCCOL(SPSTAT.6);向该两个标志位写1,会将它们清0MOV A,#00001000BORL 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串口中收到的数据送AMOV A,SBUFCLR RIRET;--------------------------------------------------------------END;--------------------------------------------------------------