3597|11

72

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

[求助]求高人帮我看下程序 [复制链接]

;--------------------------------------------------------------------------
;[H1+H2]+[ADR]+[CMD]+[CRC]
;[L1+L2]+[ID]+[TEM_1]+[TEM_2]+[TEM_3]+[TEM_4]+[TEM_5]+[DOOR]
;--------------------------------------------------------------------------
;定义通讯相关数据
H1 EQU 5AH
H2 EQU 0A5H
L1 EQU 67H
L2 EQU 76H
ID EQU 34H ;本地地址
LENGTH EQU 5 ;报文长度
BASE EQU 30H ;报文缓冲基址
GET_CMD BIT 00H ;接受到有效命令
;定义温度相关数据
DOT EQU 30H
ZHENGSHU EQU 31H
FLAG1 EQU 38H ;是否检测到DS18B20的标志位
DIS_1 EQU 32H ;符号
DIS_2 EQU 33H ;十位
DIS_3 EQU 34H ;个位
DIS_4 EQU 35H ;小数点后第一位
DIS_5 EQU 36H ;小数点后第二位
WDDATA BIT P3.3 ;定义DS18B20的数据脚为P3.3端口
;定义门磁相关数据
DOOR EQU 00H ;门磁状态
SD BIT 00H ;是否已传送门磁状态
DRDATA BIT P1.4 ;定义门磁开关为P1.4端口
;--------------------------------------------------------------------------
ORG 0000H
AJMP MAIN
ORG 0023H
AJMP SERAIL
;--------------------------------------------------------------------------
MAIN:
MOV TMOD, #20H ;定时器1用于产生波特率
MOV TH1, #0FDH
MOV TL1, #0FDH;波特率9600bps
MOV SCON, #50H ;
MOV PCON, #00H ;波特率不增倍
SETB EA ;允许总中断
SETB ES ;允许串口中断
SETB TR1 ;开计时器1
CLR GET_CMD
CLR SD
LCALL INIT_1820 ;调用复位DS18B20子程序
MAIN1:
LCALL GET_TEMPER;调用读温度子程序
LCALL FORMULA ;通过公式计算,小数点后显示两位
LCALL BCD
LCALL DELAY500 ;延时0.5秒
LCALL DELAY500 ;延时0.5秒
LCALL DELAY500 ;延时0.5秒
AJMP MAIN1
MAIN2:
AJMP MAIN2
LOOP: JBC GET_CMD, RET_PC
AJMP LOOP
;--------------------------------------------------------------------------
;串口中断服务子程序
;--------------------------------------------------------------------------
SERAIL:
JBC TI, ES_EXIT
JNB RI, $
CLR RI

MOV A, SBUF ;将接受到字节存入队列
MOV R0, #BASE
MOV R4, #LENGTH
SHT_LOOP:
XCH A, @R0
INC R0
DJNZ R4, SHT_LOOP
TEST_HEAD: ;测试报文头
MOV R0, #BASE+LENGTH
MOV A, @R0
XRL A, #H1
JNZ ERR_HEAD
DEC R0
MOV A, @R0
XRL A, #H2
JNZ ERR_HEAD
TEST_ADDRESS: ;测试地址
DEC R0
MOV A, @R0
XRL A, #ID
JNZ ERR_ADR
TEST_CRC:
MOV A, BASE
XRL A, BASE+1
XRL A, BASE+2
JNZ ERR_CRC
SETB GET_CMD
ES_EXIT:
RETI
ERR_HEAD:
RETI
ERR_ADR:
RETI
ERR_CRC:
RETI
;--------------------------------------------------------------------------
;命令执行子程序
;--------------------------------------------------------------------------
RET_PC:
CLR ES
MOV A, #L1 ;返回头字节
ACALL TMIT
MOV A, #L2 ;返回头字节
ACALL TMIT
MOV A, #ID
ACALL TMIT
MOV A, DIS_1 ;返回温度符号
ACALL TMIT
MOV A, DIS_2 ;返回温度十位
ACALL TMIT
MOV A, DIS_3 ;返回温度个位
ACALL TMIT
MOV A, #2EH ;返回小数点
ACALL TMIT
MOV A, DIS_4 ;返回小数第一位
ACALL TMIT
MOV A, DIS_5 ;返回小数第二位
ACALL TMIT
MOV A, DOOR
ACALL TMIT
SETB SD
AJMP MAIN

TMIT:
MOV SBUF, A
JNB TI, $
CLR TI
RET

;--------------------------------------------------------------------------
; DS18B20复位初始化子程序
;--------------------------------------------------------------------------
INIT_1820:
SETB WDDATA
NOP
CLR WDDATA
;主机发出延时540微秒的复位低脉冲
MOV R0, #36
LCALL DELAY
SETB WDDATA;然后拉高数据线
NOP
NOP
MOV R0, #36
TSR2:
JNB WDDATA,TSR3;等待DS18B20回应
DJNZ R0, TSR2
LJMP TSR4 ; 延时
TSR3:
SETB FLAG1 ; 置标志位,表示DS18B20存在
LJMP TSR5
TSR4:
CLR FLAG1 ; 清标志位,表示DS182B0不存在
LJMP TSR7
TSR5:
MOV R0, #06BH
TSR6:
DJNZ R0, TSR6 ;复位成功!时序要求延时一段时间
TSR7:
SETB WDDATA
RET

;--------------------------------------------------------------------------
;写DS18B20的子程序
;--------------------------------------------------------------------------
WRITE_1820:
MOV R2, #8 ;一共8位数据
CLR C
WR1:
CLR WDDATA
MOV R3, #6
DJNZ R3, $
RRC A
MOV WDDATA, C
MOV R3, #24
DJNZ R3, $
SETB WDDATA
NOP
DJNZ R2, WR1
SETB WDDATA
RET

;--------------------------------------------------------------------------
; 读DS18B20的程序,从DS18B20中读出九个字节的数据
;--------------------------------------------------------------------------
READ_18200:
MOV R4, #9
MOV R1, #60H ; 存入60H开始的九个单元
RE00:
MOV R2, #8
RE01:
CLR C
SETB WDDATA
NOP
NOP
CLR WDDATA
NOP
NOP
NOP
SETB WDDATA
MOV R3, #09
RE10:
DJNZ R3, RE10
MOV C, WDDATA
MOV R3, #23
RE20:
DJNZ R3, RE20
RRC A
DJNZ R2, RE01
MOV @R1, A
INC R1
DJNZ R4, RE00
RET

;--------------------------------------------------------------------------
;读出转换后的温度值
;--------------------------------------------------------------------------
GET_TEMPER:
SETB WDDATA ;定时入口
LCALL INIT_1820 ;先复位DS18B20
JB FLAG1, TSS2
RET ;判断DS1820是否存在?若DS18B20不存在则返回
TSS2:
MOV A, #0CCH ;跳过ROM匹配
LCALL WRITE_1820
MOV A, #44H ;发出温度转换命令
LCALL WRITE_1820

MOV R0, #50 ;等待AD转换结束,12位的话750微秒.
LCALL DELAY
LCALL INIT_1820 ;准备读温度前先复位
MOV A, #0CCH ;跳过ROM匹配
LCALL WRITE_1820
MOV A, #0BEH ;发出读温度命令
LCALL WRITE_1820
LCALL READ_18200 ;将读出的九个字节数据保存到60H-68H
RET


;--------------------------------------------------------------------------
;温度计算子程序
; 按公式:T实际=(T整数-0.25)+( M每度-M剩余)/ M每度
;计算出实际温度,整数部分和小数部分分别存于ZHENGSHU单元和DOT单元

;--------------------------------------------------------------------------
FORMULA:
;将61H中的低4位移入60H中的高4位,得到温度的整数部分,并存于ZHENGSHU单元
MOV 29H, 61H
MOV A, 60H
MOV C, 48H
RRC A
MOV C, 49H
RRC A
MOV C, 4AH
RRC A
MOV C, 4BH
RRC A
MOV ZHENGSHU, A

; (M每度-M剩余)/M每度,小数值存于A中
MOV A, 67H
SUBB A, 66H
MOV B, #64H
MUL AB
MOV R4, B
MOV R5, A
MOV R7, 67H
LCALL DIV457
MOV A, R3

;再减去0.25,实际应用中减去25
SUBB A, #19H
MOV DOT, A ;小数部分存于DOT中
MOV A, ZHENGSHU
SUBB A, #00H ;整数部分减去来自小数部分的借位
MOV ZHENGSHU, A
MOV C, 4BH
JNC ZHENG ;是否为负数
CPL A
INC A
MOV DIS_1, #2DH ;零度以下时,第一位显示"-"号
MOV ZHENGSHU, A
ZHENG:
MOV DIS_1, #2BH ;零度以上时,第一位显示"+"号
RET
;--------------------------------------------------------------------------
;双字节除以单字节子程序
;--------------------------------------------------------------------------
DIV457:
CLR C
MOV A, R4
SUBB A, R7
JC DV50
SETB OV ;商溢出
RET
DV50:
MOV R6, #8 ;求平均值(R4R5/R7-→R3)
DV51:
MOV A, R5
RLC A
MOV R5, A
MOV A, R4
RLC A
MOV R4, A
MOV F0, C
CLR C
SUBB A, R7
ANL C, /F0
JC DV52
MOV R4, A
DV52:
CPL C
MOV A, R3
RLC A
MOV R3, A
DJNZ R6, DV51
MOV A, R4 ;四舍五入
ADD A, R4
JC DV53
SUBB A, R7
JC DV54
DV53:
INC R3
DV54:
CLR OV
RET
;--------------------------------------------------------------------------
;转换成非压缩的BCD码
;--------------------------------------------------------------------------
BCD:
MOV A, ZHENGSHU
MOV B, #0AH
DIV AB
ORL A, #00110000B ;转换成ASCII码
MOV DIS_2, A
MOV DIS_3, B
MOV A, DIS_3
ORL A, #00110000B ;转换成ASCII码
MOV DIS_3, A
MOV A, DOT
MOV B, #0AH
DIV AB
ORL A, #00110000B ;转换成ASCII码
MOV DIS_4, A
MOV DIS_5, B
MOV A, DIS_5
ORL A, #00110000B ;转换成ASCII码
MOV DIS_5, A
RET

;--------------------------------------------------------------------------
;延时子程序
;--------------------------------------------------------------------------
DELAY:
D_LOOP:
MOV R1, #50H
D_LOOP1:
DJNZ R1, D_LOOP1
DJNZ R0, D_LOOP
RET
;500毫秒延时子程序,占用R4、R5
DELAY500:
MOV R4, #248
DA222:
MOV R5, #248
DJNZ R5, $
DJNZ R4, DA222
RET

END




最新回复

忠告:论坛不是万能的,这么长的帖子估计没人会仔细度。  详情 回复 发表于 2007-7-3 16:31
点赞 关注

回复
举报

87

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
我的毕业设计啊!下载到实验板上去没点反应,我刚接触单片机,汇编也忘记的差不多没写过什么。
程序肯定有错,请哪位能帮我看看啊!挑下错啊
 
 

回复

72

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
UP

不小心多发了个,请高人指点。
 
 
 

回复

68

帖子

0

TA的资源

一粒金砂(初级)

4
 
LZ大哥哈...

其实,代码这东西什么都不是...

你的平台,我不知道,你的工具,我也不知道,你的设备,器件.都不知道

谁知道哪有错哈?

 
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

5
 
调东西的时候分块调,比如:串口,温度传感器,电磁阀.啥的,慢慢来...
 
 
 

回复

69

帖子

0

TA的资源

一粒金砂(初级)

6
 
一步一步慢慢来:
1.先确定你的硬件没有问题!写一个简单的测试程序来测试一下你的硬件!
2.你的子程序,分开调试,确定没有问题了,在加入到Main程序中去,进行统调!
 
 
 

回复

60

帖子

0

TA的资源

一粒金砂(初级)

7
 
硬件当然没问题,买的试验箱。难道还要把电路图发上来?
p3.3脚是接的DS18B20,P1.4本来打算接个门磁,现在暂时没做。
 
 
 

回复

66

帖子

0

TA的资源

一粒金砂(初级)

8
 
既然如此,看看这个吧!纯串口程序,有问题没?

;--------------------------------------
;  [S1,S2]+[ADR]+[CMD]+[CRC]
;  [RE1,RE2]
;--------------------------------------

        S1      EQU     5AH
        S2      EQU     0A5H
        RE1     EQU     67H
        RE2     EQU     76H
        ID      EQU     34H             ;本地地址
        LENGTH  EQU     5               ;报文长度
        BASE    EQU     30H             ;报文缓冲基址
        GET_CMD BIT     00H             ;接受到有效命令
;--------------------------------------
        ORG     0
        AJMP    BEGIN
;--------------------------------------        
        ORG     23H
        JBC     TI,     ES_EXIT
        JNB     RI,     $
        CLR     RI
        
        MOV     A,      SBUF            ;将接受到字节存入队列
        MOV     R0,     #BASE
        MOV     R4,     #LENGTH
SHT_LOOP:
        XCH     A,      @R0
        INC     R0
        DJNZ    R4,     SHT_LOOP
        
TEST_HEAD:
        MOV     R0,     #BASE+LENGTH
        MOV     A,      @R0        
        XRL     A,      #S1
        JNZ     ERR_HEAD        
        DEC     R0
        MOV     A,      @R0
        XRL     A,      #S2
        JNZ     ERR_HEAD
                                        ;通过头检测
TEST_ADDRESS:
        DEC     R0
        MOV     A,      @R0
        XRL     A,      #ID
        JNZ     ERR_ADR   

TEST_CRC:
        MOV     A,      BASE
        XRL     A,      BASE+1
        XRL     A,      BASE+2
        JNZ     ERR_CRC
        
        SETB    GET_CMD                 ;接受到有效命令
ES_EXIT:
        RETI
        
ERR_HEAD:                               ;头字节错误
ERR_ADR:
ERR_CRC:
        RETI
;--------------------------------------        
BEGIN:  NOP
        ACALL   INIT_SFR
        ACALL   INIT_VAR
;        ACALL   INIT_IO
MAIN:
        SETB    ES        
        SETB    EA
        
LOOP:   JBC     GET_CMD,        PROCESS
        NOP
        NOP
        ORL     PCON,   #1
        NOP
        NOP
        AJMP    LOOP
        
PROCESS:
        CLR     ES
        MOV     DPTR,   #CMD_LIST
        MOV     A,      BASE+1
        ANL     A,      #11B
        RL      A
        JMP     @A+DPTR
CMD_LIST:
        AJMP    FUN_00
        AJMP    FUN_01
        AJMP    FUN_02
        AJMP    FUN_03
;-------------------------------------        
FUN_00:
        NOP
;        ACALL   READ_TEMPER
        AJMP    RET_PC
      
FUN_01:
        NOP
        AJMP    RET_PC
FUN_02:
        NOP
        AJMP    RET_PC
FUN_03:
        NOP
        AJMP    RET_PC


RET_PC:
        ;算校验先! 放到一个变量里 VAR

        MOV     A,      #RE1    ;返回头字节
        ACALL   TMIT
        MOV     A,      #RE2
        ACALL   TMIT
        
        MOV     A,      #ID
        ACALL   TMIT
        
;        MOV     A,      VAR1   ;返回变量

        AJMP    MAIN    ;!!!!!
;--------------------------------------        
INIT_SFR:
        MOV     TMOD,   #21H
        MOV     PCON,   #80H
        MOV     TH1,    #250    ;9600bps
        MOV     TL1,    #250
        MOV     SCON,   #50H
        CLR     ES
        SETB    TR1
        RET
        
INIT_VAR:
        CLR     GET_CMD
        RET
        
INIT_IO:
        RET

TMIT:      
        MOV     SBUF,   A
        JNB     TI,     $
        CLR     TI
        RET
 
 
 

回复

62

帖子

0

TA的资源

一粒金砂(初级)

9
 
自己写测试代码,一个一个的模块测试啊!
 
 
 

回复

77

帖子

0

TA的资源

一粒金砂(初级)

10
 
单片机编程不像pc机编程呀
单片机的程序都是根据硬件电路和各芯片的接线来做的
你把逻辑电路图和逻辑接线图发出来我们才能知道你的代码到底有什么瑕疵呀
 
 
 

回复

62

帖子

0

TA的资源

一粒金砂(初级)

11
 
C的还可以帮你看看,汇编的看起来头痛啊
 
 
 

回复

73

帖子

0

TA的资源

一粒金砂(初级)

12
 
忠告:论坛不是万能的,这么长的帖子估计没人会仔细度。
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表