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

📄 ex8-7.asm

📁 《增强型8051单片机实用开发技术》例程代码
💻 ASM
字号:
$include (STC12C5A.inc)       ;包含STC12C5410AD寄存器定义文件
;定义常量,根据MASTER_SLAVE的值,选择下载不同的程序
MASTER_SLAVE  EQU 0           ;汇编后的程序代码下载到主单片机中
;MASTER_SLAVE  EQU 1          ;汇编后的程序代码下载到从单片机#1中
;MASTER_SLAVE  EQU 2          ;汇编后的程序代码下载到从单片机#2中
;定义变量
Slave1_SS   EQU P5.1
Slave2_SS   EQU P5.2
Flags        EQU 20H
SPI_Receive EQU Flags.0       ;SPI 端口收到数据标志位 
T0_10MS      EQU 30H          ;该变量用于保存 10 毫秒计数(T0 中断次数) 
SPI_buffer  EQU 31H           ;该变量用于保存 SPI 端口收到的数据
	ORG  0000H 
	LJMP MAIN
	ORG   000BH               ;定时器0 中断服务程序入口 
	LJMP  T0_ISR
	ORG  004BH                ;SPI中断服务程序入口
	LJMP SPI_ISR
	ORG  0060H
MAIN:
	MOV    SP, #70H           ;设置堆栈指针
;------------ 初始化串口和定时器0------------------------------
	MOV   SCON, #50H          ;0101,0000 8位可变波特率, 无奇偶校验
	MOV   TMOD, #21H          ;T1为自动重装模式,T0为16位定时器模式
	MOV   TH0, #0C4H
	MOV   TL0, #00H           ;重装数 = 65536-15360 = 50176 = C400H 
                              ;晶振频率=18.432MHz时,每10mS中断1次
	MOV   TH1, #0F6H
	MOV   TL1, #0F6H
	ORL   AUXR, #01000000B    ;T1 以 1T 的速度计数,是普通8051的12倍
	;即波特率 = 4800*12=57600
	SETB  TR1                 ;启动定时器1 开始计数 
	SETB  TR0                 ;启动T0
	SETB  ET0                 ;开T0中断
;----------------初始化SPI-------------------------------- 
IF MASTER_SLAVE == 0          ;主机SPI控制字设置
	MOV   SPCTL,#11111100B    ;0FCH, 忽略 脚, 设为主机 
    ;SSIG=1: 忽略 脚;SPEN=1:允许SPI工作
    ;DORD=1:先传低位LSB;MSTR=1:设为主机
    ;CPOL=1:SPI 空闲时SCLK=1,前跳变沿是下降沿,后跳变沿是上升沿。
    ;CPHA=1:数据由SCLK前跳变沿驱动到SPI口线,SPI模块在后跳变沿采样
    ;SPR1,SPR0=00:主模式时SPI时钟源选择为fosc/4
ELSE    ;从机SPI控制字设置
	MOV   SPCTL,#01101100B    ;6CH, 设为从机, 由 脚决定是否已被选中
    ;SSIG=0:  由 脚决定主模式或从模式;SPEN=1:允许 SPI 工作 
    ;DORD=1:先传低位 LSB;MSTR=0:设为从机 
    ;CPOL=1:SPI 空闲时 SCLK=1,前跳变沿是下降沿,后跳变沿是上升沿。
    ;CPHA=1:数据由SCLK前跳变沿驱动到SPI口线,SPI模块在后跳变沿采样
    ;SPR1,SPR0 = 00:主模式时 SPI 时钟源选择为 fosc/4 
ENDIF
	MOV   SPSTAT,#11000000B   ;清0标志位SPIF和WCOL
	ORL   IE2, #00000010B     ;令ESPI(IE2.1)=1,允许SPIF产生中断
	MOV   Flags, #0           ;清标志字
	SETB  EA                  ;开总中断
	MOV   T0_10MS,#200        ;T0中断计数(10ms×200=2秒)
IF MASTER_SLAVE == 0
	CLR   Slave1_SS           ;选择从单片机 #1 为当前的从单片机
Check_RS232: 
	JNB   RI, Check_SPI       ;判断RS-232串口中收到数据否
	MOV   A, SBUF             ;取RS-232串口中收到的数据累加器A
	CLR   RI
	;主单片机将累加器 A 中的数据发送到从机SPI
	ANL   IE2,#0FDH           ;令ESPI(IE2.1)=0,禁止SPIF产生中断
	MOV   SPDAT, A            ;SPI 发送数据 
SPI_Wait:
	MOV   A, SPSTAT           ;等待SPIF=1, 即等待SPI发送完毕
	ANL   A, #80H 
	JZ    SPI_Wait
	ORL   IE2, #00000010B     ;令ESPI(IE2.1)=1,允许SPIF产生中断
	LJMP  Check_RS232
Check_SPI:
	JNB   SPI_Receive, Check_RS232 ;判是否收到从机SPI发回数据
	;主单片机SPI端口收到新的数据
	MOV    A, SPI_buffer      ;将"从机SPI发回的数据"送到累加器A
	CLR   SPI_Receive         ;清0主单片机SPI端口收到数据标志位
	;将累加器 A 中的数据发送到计算机
	CLR   TI                  ;清零串口发送中断标志 
	MOV   SBUF, A
RS232_Wait:
	JNB   TI, RS232_Wait      ;等待发送完毕
	CLR   TI                  ;清零串口发送中断标志 
	LJMP  Check_RS232
ELSE
Slave_Check_SPI:
	JNB   SPI_Receive, Slave_Check_SPI ;判收到主 SPI 发回的数据否
        ;从单片机SPI端口收到新的数据
	MOV   A, SPI_buffer       ;取 "主单片机 SPI 端口发的数据"
	CLR   SPI_Receive         ;清0 从单片机 SPI 端口收到数据标志位
IF MASTER_SLAVE == 2
	ADD  A, #1                ;如果是从单片机 #2,就把收到的数据加1
ENDIF
	MOV   SPDAT, A            ;将收到数据送 SPDAT, 准备下一次通讯时发回
	SJMP  Slave_Check_SPI
ENDIF
;-------------- T0中断服务程序 --------------------------------
IF MASTER_SLAVE == 0
T0_ISR:
	PUSH   PSW                ;保存断点现场 
	PUSH   ACC
	MOV    TH0, #0C4H         ;重装时间常数
	MOV    TL0, #00H
	DJNZ   T0_10MS,T0_Exit
	MOV    T0_10MS,#200       ;恢复T0中断计数值
	CPL   Slave1_SS           ;改变当前选择的从单片机 
	CPL   Slave2_SS
T0_Exit: 
	POP   ACC                 ;恢复断点现场 
	POP   PSW 
	RETI 
ELSE                          ;从机程序不需要定时器T0
T0_ISR:
	RETI
ENDIF
;---------------- SPI中断服务程序 -------------------------------
SPI_ISR:                      ;SPI中断服务程序 
	MOV   SPSTAT, #11000000B  ;0C0H, 清0标志位SPIF和WCOL
	MOV   A, SPDAT            ;保存收到的数据 
	MOV   SPI_buffer, A 
	SETB  SPI_Receive         ;设置SPI 端口收到数据标志
	RETI
;----------------------------------------------------------- 
	END

⌨️ 快捷键说明

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