;============================================;STC12C5410 spi 通信;單主單從模式;============================================;MASTER EQU 1 ;主單片機MASTER EQU 0 ;從機;-------------------------------------;定義COM波特率自動重裝常數(shù);RELOAD_8BIT_DATA EQU 0F6H; Fosc=18.432 ,4800;----------------------------------------------------------------------;定義特殊功能寄存器AUXR EQU 8EH; AUXR特殊功能寄存器的BIT3是SPI中斷充許控制位ESPI; IE特殊功能寄存器的BIT5是ADC和SPI兩個中斷共享的總中斷允許控制位EADC_SPI; 要產(chǎn)生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; 系統(tǒng)初始化if MASTER;-------------------------Check_RS232:JNB RI,Master_Check_SPI;判斷RS232串口是否收到數(shù)據(jù);主單片機RS232已收到數(shù)ACALL Get_Byte_From_RS232;主單片機將收到的數(shù)據(jù)送A;ACALL SPI_Send_Byte; 主單片機將A中的數(shù)據(jù)送到從機SPISJMP Check_RS232;Master_Check_SPI: ; -------------收從機的字發(fā)到PC機-----------------------JNB SPI_Receive,Check_RS232;判收到從SPI發(fā)回的數(shù)據(jù)否;主單片機已收到新的數(shù)據(jù);MOV A,SPI_buffer; ;將“從SPI發(fā)回的數(shù)據(jù)送ACLR SPI_Receive ;清0 主單片機SPI端口收到的數(shù)據(jù)標(biāo)志位ACALL RS232_Send_Byte ;將A中的數(shù)據(jù)發(fā)送到PC機;SJMP Check_RS232;elseSlave_Check_SPI:JNB SPI_Receive,Slave_Check_SPI;判收到主SPI發(fā)回的數(shù)據(jù)否;從單片機SPI端口已收到新的數(shù)據(jù)MOV A,SPI_buffer ;取主單片機SPI端口發(fā)的數(shù)據(jù)CLR SPI_Receive; ; 清0 從單片機SPI端口收到數(shù)據(jù)標(biāo)志位MOV SPDAT,A ;將收到的數(shù)據(jù)送SPDAT,準(zhǔn)備一下次通訊時發(fā)回SJMP Slave_Check_SPI ;endif;----------------------------------------------------------------------ADC_SPI_Interrupt_Routine: ;ADC_SPI中斷服務(wù)程序MOV SPSTAT,#11000000B ;0C0H,清0標(biāo)志位SPIF和WCOLMOV A,SPDAT ;保存收到的數(shù)據(jù)MOV SPI_buffer,ASETB SPI_Receive ;樹立SPI端口收到的數(shù)據(jù)標(biāo)志RETI;------------------------------------------------------------------------Init_System:; ACALL Initial_UART ;初始化串口ACALL Initial_SPI ;初始化SPIMOV Flags,#0 ;清標(biāo)志字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的速度計數(shù), 是普通的12倍ORL AUXR,ASETB TR1; ;啟動T1開始計數(shù)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腳,設(shè)為主機;SSIG=1,忽略SS腳 ;SPEN=1,允許SPI工作 ;DORD=1,先傳低平的LSB ;MSTR=1,設(shè)為主機;CP0L=1,.....;CPHA=1,.....;SPR1,SPR0=00,主模式時的SPI時鐘源選擇為Fosc/4; 01:fosc/16; 10:fosc/64 11:fosc/128else MOV SPCTL,#11101100B; ;0ECH,忽略SS腳,設(shè)為從機 ;SSIG=1,忽略SS腳 ;SPEN=1,允許SPI工作 ;DORD=1,先傳低平的LSB ;MSTR=1,設(shè)為主機;CP0L=1,.....;CPHA=1,.....;SPR1,SPR0=00,主模式時的SPI時鐘源選擇為Fosc/4 endifMOV SPSTAT,11000000B ;清0標(biāo)志位SPIF(SPSTAT.7),WCCOL(SPSTAT.6);向該兩個標(biāo)志位寫1,會將它們清0MOV A,#00001000BORL AUXR,A ;令ESPI(AUXR。3)=1, 充許SPIF(SPSTAT。7)產(chǎn)生中斷SETB EADC_SPI; ;開ADC中斷和SPI中斷共享的總中斷控制位RET;----------------------------------------------------------RS232_Send_Byte: ;RS232串口發(fā)送一個字節(jié)CLR TI ;清0串口發(fā)送中斷標(biāo)MOV SBUF,A;RS232_Send_Wait:JNB TI,RS232_Send_Wait; ;等待發(fā)送完畢,未發(fā)完跳回本行CLR TI ;清0串口發(fā)送中斷標(biāo)志RET;----------------------------------------------------------; 此段程序只有主MCU調(diào)用;----------------------------------------------------------SPI_Send_Byte: ;SPI發(fā)送一字節(jié)CLR EADC_SPI; ;關(guān)ADC中斷和SPI中斷共享的總中斷控制位MOV SPDAT,A; ;SPI 發(fā)送數(shù)據(jù)SPI_Send_Byte_Wait:MOV A,SPSTAT; ;等待SPIF=1,即等待SPI發(fā)送完畢ANL A,#80H;JZ SPI_Send_Byte_Wait;SETB EADC_SPI ;開ADC中斷和SPI中斷共享的總中斷控制位RET;------------------------------------------------------------ 附加 不用中斷收數(shù),巡檢方式SPI_Receive_Byte:MOV A,SPSTAT ;是否收到從SPI發(fā)回的數(shù)據(jù)?ANL A,#80H;JZ SPI_Receive_Byte; ;未收到數(shù)繼續(xù)等待MOV A,SPDAT ;已收到數(shù); .; .; .Get_Byte_From_RS232: ;取RS232串口中收到的數(shù)據(jù)送AMOV A,SBUFCLR RIRET;--------------------------------------------------------------END;--------------------------------------------------------------
評論