📄 mymax512_1.asm
字号:
/*自定义 MAX512协议一 接收端程序*/
/*最多控制254台灯具,256级变色 */
/*Author:wangbin Data:2006-09-30*/
$NOMOD51
#include "STC12C2052.H"
//常量定义-------------------------------
LED_R EQU P1_7
LED_G EQU P1_6
LED_B EQU P1_5
EEPROM_ADDH EQU 0x10 //ADDRESS EEPROM中存放地址:0x1000 适用于STC12C2052系列
EEPROM_ADDL EQU 0x00
GLOBE_CHANGE_PASS EQU 0x55 //全球变化的确认码
ADDRESS_CHANGE_PASS1 EQU 0xAA //地址变化的确认码1
ADDRESS_CHANGE_PASS2 EQU 0xBB //地址变化的确认码1
//变量定义-------------------------------
ADDRESS DATA 0x30 //保存 EEPROM 中读出的数据
DATA_R DATA 0x31 //R色分级码
DATA_G DATA 0x32
DATA_B DATA 0x33
DATA_R_TEMP DATA 0x34 //R色分级码暂存
DATA_G_TEMP DATA 0x35
DATA_B_TEMP DATA 0x36
SINGLE_CHANGE_COUNT DATA 0x37
GLOBE_CHANGE_COUNT DATA 0x38
ADDRESS_CHANGE_COUNT DATA 0x39
RECEIVE_G_TEMP DATA 0x3A //接收暂存
RECEIVE_R_TEMP DATA 0x3B
ADDRESS_FLAG BIT 0x00 //EEPROM中地址是否有效(1-254)
SINGLE_CHANGE_FLAG BIT 0x01 //是否在接收单个灯体变化数据
GLOBE_CHANGE_FLAG BIT 0x02 //是否在接收全球灯体变化数据
ADDRESS_CHANGE_FLAG BIT 0x03 //是否在接收地址变化数据
ADDRESS_HAS_CHANGED_FLAG BIT 0x04 //地址已经改变,系统要从新检测地址码
ORG 0000H
JMP START
ORG 0003H
JMP INT0_INT
ORG 000BH
JMP TIM0_INT
ORG 0013H
JMP INT1_INT
ORG 001BH
JMP TIM1_INT
ORG 0023H
JMP UART_INT
ORG 002BH
JMP ADC_SPI_INT
ORG 0033H
JMP PCA_LVD_INT
ORG 003BH
START:
//MOV WDT_CONTR,#00111101B
CALL DELAY
MOV SP,#0x50 //32级堆栈
//RAM Initial---------------------------
MOV ADDRESS,#0
MOV DATA_R,#0
MOV DATA_G,#0
MOV DATA_B,#0
MOV DATA_R_TEMP,#0
MOV DATA_G_TEMP,#0
MOV DATA_B_TEMP,#0
MOV SINGLE_CHANGE_COUNT,#0
MOV GLOBE_CHANGE_COUNT,#0
MOV ADDRESS_CHANGE_COUNT,#0
MOV RECEIVE_G_TEMP,#0
MOV RECEIVE_R_TEMP,#0
CLR ADDRESS_FLAG
CLR SINGLE_CHANGE_FLAG
CLR GLOBE_CHANGE_FLAG
CLR ADDRESS_CHANGE_FLAG
CLR ADDRESS_HAS_CHANGED_FLAG
//--------------------------------------
CLR LED_R
CLR LED_G
CLR LED_B
/* 清除EEPROM
MOV ISP_ADDRH,#EEPROM_ADDH
MOV ISP_ADDRL,#EEPROM_ADDL
MOV ISP_CMD,#3 //读EEPROM
CALL ISP_ACTION
JMP $ */
//串口初始化并且开中断------------------------
CALL INITIAL_UART
//开看门狗
//MOV WDT_CONTR,#00111101B //约1S
ADDRESS_BEGIN:
CALL ADDRESS_MOVEANDCHACK
//MOV ADDRESS,#0x11 //测试
//SETB ADDRESS_FLAG //测试
JNB ADDRESS_FLAG,FAIL_LOOP
MAIN_LOOP: //主循环,不断显示颜色
//MOV DATA_R,#5 //测试
/*MOV A,ADDRESS //测试读出的数据是否是0x11
CJNE A,#0x11,CONTINUE_GO
JMP FAIL_LOOP
CONTINUE_GO: */
MOV DATA_R_TEMP,DATA_R
MOV DATA_G_TEMP,DATA_G
MOV DATA_B_TEMP,DATA_B
DISPLAY_LOOP:
MOV R0,#0
RGB_CHECK:
MOV A,DATA_R_TEMP
JZ R_NOT_LIGHT
SETB LED_R
DEC DATA_R_TEMP
JMP R_END
R_NOT_LIGHT:
CLR LED_R
R_END:
MOV A,DATA_G_TEMP
JZ G_NOT_LIGHT
SETB LED_G
DEC DATA_G_TEMP
JMP G_END
G_NOT_LIGHT:
CLR LED_G
G_END:
MOV A,DATA_B_TEMP
JZ B_NOT_LIGHT
SETB LED_B
DEC DATA_B_TEMP
JMP B_END
B_NOT_LIGHT:
CLR LED_B
B_END:
NOP //短暂延时
NOP
NOP
NOP
NOP
DJNZ R0,RGB_CHECK
//MOV WDT_CONTR,#00111101B //喂狗
JBC ADDRESS_HAS_CHANGED_FLAG,ADDRESS_BEGIN
JMP MAIN_LOOP
FAIL_LOOP: //没有地址码的自控程序,单闪红色警告!
CPL LED_R
CLR LED_G
CLR LED_B
CALL DELAY
JBC ADDRESS_HAS_CHANGED_FLAG,ADDRESS_BEGIN
//MOV WDT_CONTR,#00111101B //喂狗
JMP FAIL_LOOP
//子程序区 -----------------------------------------
ADDRESS_MOVEANDCHACK: //注意结果开了EA
MOV ISP_ADDRH,#EEPROM_ADDH
MOV ISP_ADDRL,#EEPROM_ADDL
MOV ISP_CMD,#1 //读EEPROM
CALL ISP_ACTION
MOV ADDRESS,ISP_DATA
MOV A,ADDRESS
JZ ADDRESS_FAIL
INC A
JZ ADDRESS_FAIL
SETB ADDRESS_FLAG
JMP ADDRESS_CHACK_END
ADDRESS_FAIL:
CLR ADDRESS_FLAG
ADDRESS_CHACK_END:
RET
ISP_ACTION: //ISP功能动作,前提是先写入ISP_CMD,确定是读、写还是擦除操作,ISP_ADDRH ISP_ADDRL为地址,ISP_DATA为数据
MOV ISP_CONTR,#10000010B //20MHz以下
CLR IE_EA
MOV ISP_TRIG,#0x46
MOV ISP_TRIG,#0xB9
NOP
SETB IE_EA
MOV ISP_CONTR,#0
RET
INITIAL_UART: //串口初始化,可用Timer1和Timer2(若有)工作在模式3做BaudRate发生器
//SCON: SM0 SM1 SM2 REN TB8 RB8 TI RI
//TMOD: GATE1 C/T1 M11 M10 GATE0 C/T0 M01 M00
//AUXR: T0x12 T1x12 M0x6 EADCI ESPI ELVDI -- -- 0000 00xx
MOV SCON,#11110000B
MOV TMOD,#0x20
ORL PCON,#0x80 //可选
MOV TH1,#0xF7 //16M 9600 BaudRate
MOV TL1,#0xF7
//ORL AUXR,#01000000B //可选
//ANL AUXR,#10111111B //可选
SETB IE_ES
SETB IE_EA
SETB TCON_TR1
RET
//延时程序区 ---------------------------------------
DELAY: //1s
CLR A
MOV R0,A
MOV R1,A
MOV R2,#5
DELAY_LOOP:
DJNZ R0,DELAY_LOOP
DJNZ R1,DELAY_LOOP
DJNZ R2,DELAY_LOOP
RET
//中断程序区 ---------------------------------------
INT0_INT:
RETI
TIM0_INT:
RETI
INT1_INT:
RETI
TIM1_INT:
RETI
UART_INT:
//判断是否是接收中断
JB SCON_RI,IS_UART_RECEIVE
CLR SCON_TI
RETI
IS_UART_RECEIVE:
CLR SCON_RI
PUSH ACC //保存现场
JB SCON_RB8,ADDRESS_CHECK
JB SINGLE_CHANGE_FLAG,SINGLE_CHANGE
JB GLOBE_CHANGE_FLAG,GLOBE_CHANGE
JB ADDRESS_CHANGE_FLAG,ADDRESS_CHANGE_GO
JMP UART_INT_END1
ADDRESS_CHECK:
MOV A,SBUF
//MOV A,#0x11 //测试
//MOV A,#0xFF //测试
JZ IS_ADDRESS_CHANGE //00为写地址
INC A
JZ IS_GLOBAL_CHANGE //FF为全局变换
MOV A,SBUF
//MOV A,#0x11 //测试
CJNE A,ADDRESS,UART_INT_END1
CLR SCON_SM2 //准备接收数据
SETB SINGLE_CHANGE_FLAG
CLR GLOBE_CHANGE_FLAG
CLR ADDRESS_CHANGE_FLAG
MOV SINGLE_CHANGE_COUNT,#0
MOV GLOBE_CHANGE_COUNT,#0
MOV ADDRESS_CHANGE_COUNT,#0
UART_INT_END1:
POP ACC
RETI
IS_ADDRESS_CHANGE:
CLR SCON_SM2
SETB ADDRESS_CHANGE_FLAG
CLR SINGLE_CHANGE_FLAG
CLR GLOBE_CHANGE_FLAG
MOV SINGLE_CHANGE_COUNT,#0
MOV GLOBE_CHANGE_COUNT,#0
MOV ADDRESS_CHANGE_COUNT,#0
UART_INT_END2:
POP ACC
RETI
IS_GLOBAL_CHANGE:
CLR SCON_SM2
SETB GLOBE_CHANGE_FLAG
CLR SINGLE_CHANGE_FLAG
CLR ADDRESS_CHANGE_FLAG
MOV SINGLE_CHANGE_COUNT,#0
MOV GLOBE_CHANGE_COUNT,#0
MOV ADDRESS_CHANGE_COUNT,#0
UART_INT_END3:
POP ACC
RETI
//单个变化-------------------------------------------------------
SINGLE_CHANGE:
INC SINGLE_CHANGE_COUNT
MOV A,SINGLE_CHANGE_COUNT
DEC A
JZ SINGLE_R_RECEIVE
DEC A
JZ SINGLE_G_RECEIVE
MOV DATA_B,SBUF
MOV DATA_G,RECEIVE_G_TEMP
MOV DATA_R,RECEIVE_R_TEMP
CLR SINGLE_CHANGE_FLAG
MOV SINGLE_CHANGE_COUNT,#0
SETB SCON_SM2
JMP UART_INT_END4
SINGLE_R_RECEIVE:
MOV RECEIVE_R_TEMP,SBUF
JMP UART_INT_END4
SINGLE_G_RECEIVE:
MOV RECEIVE_G_TEMP,SBUF
UART_INT_END4:
POP ACC
RETI
//跳转太远,要接一下
ADDRESS_CHANGE_GO:
JMP ADDRESS_CHANGE
//全体变化-------------------------------------------------------
GLOBE_CHANGE:
INC GLOBE_CHANGE_COUNT
MOV A,GLOBE_CHANGE_COUNT
DEC A
JZ GLOBE_CHANGE_AFFIRM
DEC A
JZ GLOBE_R_RECEIVE
DEC A
JZ GLOBE_G_RECEIVE
MOV DATA_B,SBUF
MOV DATA_G,RECEIVE_G_TEMP
MOV DATA_R,RECEIVE_R_TEMP
GLOBE_CHANGE_END:
CLR GLOBE_CHANGE_FLAG
MOV GLOBE_CHANGE_COUNT,#0
SETB SCON_SM2
JMP UART_INT_END5
GLOBE_R_RECEIVE:
MOV RECEIVE_R_TEMP,SBUF
JMP UART_INT_END5
GLOBE_G_RECEIVE:
MOV RECEIVE_G_TEMP,SBUF
JMP UART_INT_END5
GLOBE_CHANGE_AFFIRM:
MOV A,SBUF
//MOV A,#0x55 //测试
CJNE A,#GLOBE_CHANGE_PASS,GLOBE_CHANGE_END
UART_INT_END5:
POP ACC
RETI
//地址变化-------------------------------------------------------
ADDRESS_CHANGE:
INC ADDRESS_CHANGE_COUNT
MOV A,ADDRESS_CHANGE_COUNT
DEC A
JZ ADDRESS_CHANGE_AFFIRM1
DEC A
JZ ADDRESS_CHANGE_AFFIRM2
//通过了验证------------------------
CLR IE_EA
MOV ISP_ADDRH,#EEPROM_ADDH
MOV ISP_ADDRL,#EEPROM_ADDL
MOV ISP_CMD,#3 //擦除EEPROM
MOV ISP_CONTR,#10000010B //20MHz以下
MOV ISP_TRIG,#0x46
MOV ISP_TRIG,#0xB9
NOP
NOP
MOV ISP_ADDRH,#EEPROM_ADDH
MOV ISP_ADDRL,#EEPROM_ADDL
MOV ISP_DATA,SBUF
MOV ISP_CMD,#2 //写EEPROM
MOV ISP_CONTR,#10000010B //20MHz以下
MOV ISP_TRIG,#0x46
MOV ISP_TRIG,#0xB9
NOP
MOV ISP_CONTR,#0
SETB ADDRESS_HAS_CHANGED_FLAG
CLR SCON_RI
SETB IE_EA
ADDRESS_CHANGE_END:
CLR ADDRESS_CHANGE_FLAG
MOV ADDRESS_CHANGE_COUNT,#0
SETB SCON_SM2
JMP UART_INT_END
ADDRESS_CHANGE_AFFIRM1:
MOV A,SBUF
CJNE A,#ADDRESS_CHANGE_PASS1,ADDRESS_CHANGE_END
JMP UART_INT_END
ADDRESS_CHANGE_AFFIRM2:
MOV A,SBUF
CJNE A,#ADDRESS_CHANGE_PASS2,ADDRESS_CHANGE_END
//串口中断结束---------------------------------------------------
UART_INT_END:
POP ACC
RETI
ADC_SPI_INT:
RETI
PCA_LVD_INT:
RETI
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -