;============================================ ;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 ;--------------------------------------------------------------