⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stc-spi.asm

📁 STC单片机的SPI通信汇编程序
💻 ASM
字号:
;============================================
;STC12C5410  spi 通信
;单主单从模式
; 
;   2008-06-7
;============================================

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


















⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -