中央空调,怎么实现统一管理,只有一个RX485的接口。
希望实现功能如下:
1、可以在上班之前提早控制打开
2、可以在下班之后全部控制关闭
遇到的问题:
1、怎么识别空调是否开启
2、怎么实现控制开关
已解决: 购买第三方网关,信号线接空调信号线。
要实现中央空调的统一管理,只有一个RX485的接口,可以采用以下方法:
1、识别空调是否开启:
可以通过读取空调的状态来判断空调是否开启。通过RX485接口与空调进行通信,发送查询指令获取空调的状态信息,如温度、风速、工作模式等。根据返回的状态信息判断空调是否处于开启状态。
2、实现控制开关:
通过RX485接口与空调进行通信,发送控制指令实现开关控制。可以发送开启指令,将空调设置为制热、制冷、通风等工作模式,并设置相应的温度和风速。可以发送关闭指令,将空调设置为关闭状态。
为了实现上班前提早控制打开和下班后全部控制关闭的功能,可以使用定时任务或者定时器来控制空调的开关。在上班之前提前一段时间,通过定时任务或者定时器发送开启指令,将空调提前打开。在下班之后,通过定时任务或者定时器发送关闭指令,将空调全部关闭。
需要注意的是,为了实现统一管理,可以将所有空调的地址和状态信息保存在一个管理系统中,通过RX485接口与管理系统进行通信,进行查询和控制操作。这样可以实现对多个空调的统一管理和控制。
编程,设置8255C口键盘输入、A口为数码管段码输出。使得在4×4小键盘上每按一个键,8位数码管上显示出相应字符。
电路图:
接线:
汇编代码:
a8255 equ 288H ;8255 A口
c8255 equ 28aH ;8255 C口
k8255 equ 28bH ;8255 控制口
;========================数据定义段data开始=======================;
data segment
table1 dw 0770h,0B70h,0D70h,0E70h,07B0h,0BB0h,0DB0h,0EB0h ;键盘行列码表,对应着si寄存器,用于确定按下按键的位置及按键信息
dw 07D0h,0BD0h,0DD0h,0ED0h,07E0h,0BE0h,0DE0h,0EE0h
LED DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,77H,7CH ;LED段码表,分别代表0~F
DB 39h,5EH,79h,71h,0ffh
char db '0123456789ABCDEF' ;字符表,对应着di寄存器,用于最后在屏幕上输出内容
mes db 0ah,0dh,'PLAY ANY KEY IN THE SMALL KEYBOARD! ',0ah,0dh ;提示信息,用于开始时在屏幕上提示输入
db 'IT WILL BE ON THE SCREEN! END WITH E ',0ah,0dh,'$'
key_in db 0h
data ends
;========================数据定义段data结束=======================;
;=======================堆栈定义段stacks开始======================;
stacks segment stack
db 100 dup (?)
stacks ends
;=======================堆栈定义段stacks结束======================;
code segment
assume cs:code,ds:data,ss:stacks,es:data
start:
cli ;禁止中断发生
mov ax,data ;将data放入通用寄存器ax中,data是伪指令,起到过渡作用
mov ds,ax ;将ax中的data转到ds数据段寄存器中,让数据段指向正确的位置,但内存数不能放入段地址
mov es,ax ;将ax中的data放入通用寄存器es中
mov ax,stacks ;将stack堆栈放入通用寄存器ax中,起到过渡作用
mov ss,ax ;将ax中的stack转到数据段寄存器ss中
mov dx,offset mes ;显示提示信息mes
mov ah,09 ;将功能号09H送入ah
int 21h ;返回DOS,输出需要显示的信息
mov dx,k8255 ;设置8255 (工作方式0;A口输出;C口高四位输出,低四位输入),初始化控制字,将控制字k8255送入端口dx
mov al,81h ;将控制字10000001(81h)送入al中,特征位D7默认置1,A组方式0,D6D5=00,端口A输出,D4=0,PC7~PC4输出,D3=0,B组方式0,D2=0,B端口输出,D1=0,PC3~PC0输入,D0=1
out dx,al ;将al中的控制字送入端口dx中
main_key:
call key ;获取一个输入的字符并显示
call display ;调用显示子程序,显示得到的字符
cmp byte ptr key_in,'E' ;将输入的字符key_in与'E'进行比较,计算key_in-'E'的值,判断是否执行退出操作,按'E'退出程序
jnz main_key ;如果key_in-'E'的值不为0,则跳转至main_key,继续循环
mov ax,4c00h ;如果key_in-'E'的值等于0,则退出
int 21h ;返回DOS,退出
;==========================子程序key开始=========================;
key proc near ;开始定义子程序key的伪指令,NEAR属性为段内近调用,调用程序和子程序在同一代码段中,只能被相同代码段的其他程序调用
key_loop: ;开始定义key_loop循环,等待键盘按键按下
mov ah,1 ;调用DOS的1号功能,没有入口参数,只有出口al
int 16h ;读取键盘缓冲区输入
jnz exit ;若pc键盘有键按下则退出
mov dx,c8255 ;设置端口C,准备读取行3~行0
in al,dx ;进行读行扫描值
and al,0fh ;将al寄存器中的高四位内容清零
cmp al,0fh ;将al中高四位清零后的内容与0fh进行比较,判断是否有键被按下
jz key_loop ;如若未发现有键按下则继续转至key_loop进行循环
call delay ;调用延迟子程序delay
mov ah,al ;设置8255 (工作方式0;A口输出;C口高四位输入,低四位输出),将al内容送入ah暂存
mov dx,k8255 ;初始化控制字,将控制字k8255送入端口dx
mov al,88h ;将控制字10001000(88h)送入al中,特征位D7默认置1,A组方式0,D6D5=00,端口A输出,D4=0,PC7~PC4输出,D3=1,B组方式0,D2=0,B端口输出,D1=0,PC3~PC0输入,D0=0
out dx,al ;将al中的控制字送入端口dx中
mov al,ah ;将ah中的暂存值还给al
mov dx,c8255 ;设置端口C,准备读取列3~列0
in al,dx ;读列扫描值
and al,0f0h ;将al低四位清零
cmp al,0f0h ;将al中低四位清零后的内容与0f0h进行比较,判断是否有键被按下
jz key_loop ;如若未发现有键按下则继续转至key_loop进行循环
mov si,offset table1 ;si为键盘扫描码表table1的首地址
mov di,offset char ;di为字符表char的首地址
mov cx,16 ;cx为待查表的表大小为16,0~F
key_tonext: ;开始定义key_tonext操作,用于查找扫描码,确定按下按键的位置
cmp ax,[si] ;逐个比较键盘扫描码表table1的首地址的值,计算行列差值,进而确定按下的键在键盘上的位置
jz key_findkey ;如果计算结果等于0,则跳转到key_findkey操作
dec cx ;把cx中的值减一
jz key_loop ;未找到对应扫描码,则跳转到key_loop循环中,等待再次按下按键
add si,2 ;源变址寄存器si加2
inc di ;字符表首地址di自增1,di指向字符表char中的下一个字符内容
jmp key_tonext ;跳转至key_tonext操作
key_findkey: ;开始定义key_findkey操作,用于查找键盘码,并在屏幕上显示
mov dl,[di] ;将di中的字符内容送入dl中
mov ah,02 ;调用DOS的2号功能,将功能号02H送入ah
int 21h ;显示查找到的键盘码,进行单字符输出,入口是dl,在屏幕上输出di中的键盘码字符内容
mov byte ptr key_in,dl ;将dl中的键盘码送入key_in中
key_waitup: ;开始定义key_waitup操作,用于进行按键抬起的操作,用于防止抖动
mov dx,k8255 ;初始化控制字,将控制字k8255送入端口dx
mov al,81h ;将控制字10000001(81h)送入al中,特征位D7默认置1,A组方式0,D6D5=00,端口A输出,D4=0,PC7~PC4输出,D3=0,B组方式0,D2=0,B端口输出,D1=0,PC3~PC0输入,D0=1
out dx,al ;将al中的控制字送入端口dx中
mov dx,c8255 ;设置端口C
mov al,0fh ;将00001111(0fh)送入al中,端口C特殊控制方式:特征位D7置0,D6D5D4不使用,位选择为端口C的7位,D3D2D1均为1,置位D0=1
out dx,al ;将al中的控制字送入端口dx中
in al,dx ;进行读行扫描值
and al,0fh ;将al寄存器中的高四位内容清零
cmp al,0fh ;将al中高四位清零后的内容与控制字0fh进行比较,判断是否有键被按下
jnz key_waitup ;若按键未抬起,则继续跳转至key_waitup循环
call delay ;调用延时子程序
ret ;用栈中的数据,修改IP的内容,从而实现近转移
exit: ;子程序key退出
mov byte ptr key_in,'E' ;将'E'字符送入key_in中
ret ;用栈中的数据,修改IP的内容,从而实现近转移
key endp ;结束子程序key伪指令
;==========================子程序key结束=========================;
;=========================子程序delay开始========================;
delay proc near ;开始定义子程序delay的伪指令,NEAR属性为段内近调用,调用程序和子程序在同一代码段中,只能被相同代码段的其他程序调用
push ax ;延迟50ms~100ms
mov ah,0 ;调用DOS0号指令
int 1ah ;返回DOS
mov bx,dx ;将dx中内容送入bx
delay1: ;定义delay1操作
mov ah,0 ;调用DOS0号指令
int 1ah ;返回DOS
cmp bx,dx ;比较bx和dx中值的值是否相等,计算bx-dx的值是否为0
jz delay1 ;若bx-dx的值为0,则继续跳转至delay1
mov bx,dx ;将dx中内容送入bx
delay2: ;定义delay2操作
mov ah,0 ;调用DOS0号指令
int 1ah ;返回DOS
cmp bx,dx ;比较bx和dx中值的值是否相等,计算bx-dx的值是否为0
jz delay2 ;若bx-dx的值为0,则继续跳转至delay2
pop ax ;从栈顶取出数据送入ax
ret ;用栈中的数据,修改IP的内容,从而实现近转移
delay endp ;结束子程序delay伪指令
;=========================子程序delay结束========================;
;========================子程序display开始=======================;
display proc near ;开始定义子程序diaplay的伪指令,NEAR属性为段内近调用,调用程序和子程序在同一代码段中,只能被相同代码段的其他程序调用
push ax ;将寄存器ax中的数据送入栈中
mov bx,offset led ;bx为LED灯段码表led的首地址
mov al,byte ptr key_in ;将key_in中的内容送入al中
sub al,30h ;字符'0-9'所对应的ASCII码值为'30H-39H',故欲得到0~9的数值,只需用其ASCII码值减30H
cmp al,09h ;将al中的值与9进行比较,若等于9时则进行换码跳转dis2
jng dis2 ;跳转至dis2操作进行换码
sub al,07h ;字符'a-f'所对应的ASCII码值为'97H-102H',故欲得到a~f的数值,只需用其ASCII码值减07H
dis2:
xlat ;换码指令,用于改变al中的数据
mov dx,a8255 ;设置端口A,准备输出段码内容显示
out dx,al ;输出显示数据,段码
pop ax ;从栈顶取出数据送入ax
ret ;用栈中的数据,修改IP的内容,从而实现近转移
display endp ;结束子程序display伪指令
;========================子程序display结束=======================;
code ends
end start
运行结果:
运行程序,按下薄膜键盘上的按键,数码管显示按键的值。效果如下图所示: