5980|6

446

帖子

0

TA的资源

裸片初长成(高级)

楼主
 

串口资料的无奈 [复制链接]

关于ATMEL51单片机串行通讯中的接收位RB8 余永全的《ATMEL89系列单片机应用技术》描述是:如果在接收前定义了 SM2=1,则接收机在接收到停止位后会对RB8进行检测;如RB8=1,则串行口 向CPU发出中断请求,请求对SBUF中的数据进行处理;如RB8=0,则数据不于 接收;如定义了SM2=0,则收到的数据不管RB8为何值都予以接收处理。 其他参考书中为何在接收串行通讯中还要对数据RB8进行检测。 现在出的单片机书可谓五花八门,没有几本书能例出正确的程序。 既然RB8在定义了SM2=1时有硬件自动对RB8进行检测。在软件中再对 RB8进行检测不是多此一举吗,反而搞得读者糊涂。 这几天搞多机通讯,书倒好几本,没多少写的明白的。实例也不能运行。 自己只能先写地址,再检查应答。再发送数据一步一步试,照书上的。 搞不了
此帖出自单片机论坛

最新回复

;******************************************************** ;************************显视温度************************ ;********************************************************         COUNT        DATA    41H     ;地址计数常数         WENDU   DATA    37H     ;实际温度地址         WENDUD  DATA    38H     ;温度低位地址         WENDUG        DATA    39H     ;温度高位地址         SDWDG        DATA    3aH     ;设定高温度地址         SDWDD        DATA    3bH     ;设定低温度地址         TEMP      EQU  30H         TEMP1     EQU  31H         BUF       EQU  32H         DISBUF    EQU  40H         PLAYFLAG  BIT  22H.0 ;----------------------------------------------------------------         RS      EQU    P2.0        ;         RW      EQU    P2.1        ;         E       EQU    P2.2        ;         PSB     EQU    P2.3        ;         RST     EQU    P2.5        ;         SHUJU   EQU    P3.3        ;         K1      EQU    P1.4        ;按键1,设定温度值减1         K2      EQU    P1.5        ;按键2,设定温度值加1         K3      EQU    P1.6        ;按键3,确定修改和确定退出 ;============================================================                 ORG  0000H                 JMP  MAIN                 ORG  0040H ;============================================================ MAIN:        CLR        P3.7         LCALL   SET_LCD         ;初始化 LCD 12864         LCALL   W18B20          ;初始化18B20         LCALL        CWD ;******************************************************** WANG:   LCALL   W18B20                ;初始化18B20         LCALL   DU18B20         ;读18B20温度         LCALL   S18B20          ;送温度显视         LCALL   ANJIAN          ;按键程序                                 CLR  PLAYFLAG         MOV  TMOD,#20H             ;定时器1工作于8位自动重载模式,用于产生波特率         MOV  TH1,#0FDH               MOV  TL1,#0FDH             ;波特率9600                 MOV  SCON,#50H             ;设定串行口工作方式         ANL  PCON,#00H             ;波特率不倍增         SETB  TR1             ;启动定时器1                 SENDDATA:         MOV  A,WENDU         MOV  SBUF,A         JNB  TI,$      ; 等特数据传送         CLR  TI        ; 清除数据传送标志                                   LJMP    WANG ;============================================================== ;对 LCD12864 做初始化设置 ;============================================================== SET_LCD:         SETB  PSB             ;通讯方式为8位数据并口         MOV A,#34H            ;34H--扩充指令操作         LCALL SEND_I         MOV A,#30H            ;30H--8bit控制界面,基本指令操作         LCALL SEND_I         MOV A,#01H            ;清除显示         LCALL SEND_I         MOV A,#06H            ;指定在资料写入或读取时,光标的移动方向         LCALL SEND_I          ;DDRAM 的地址计数器(AC)加1         MOV A,#0CH            ;开显示,关光标,不闪烁         LCALL SEND_I         RET ;============================================================== ;写指令子程序 ;RS=0,RW=0,E=高脉冲,D0-D7=指令码 ;============================================================== SEND_I: LCALL CHK_BUSY         CLR  RS         CLR  RW         MOV P0,A         SETB  E         NOP         NOP         CLR E         RET ;============================================================== ;测忙碌子程序 ;RS=0,RW=1,E=H,D0-D7=状态字 ;============================================================== CHK_BUSY:         MOV  P0,#0FFH    ;测忙碌子程序         CLR  RS         SETB  RW         SETB E         JB   P0.7,$         CLR  E         RET        ;============================================================== ;把 DS18B20 EEROM 里的温度报警值拷贝回暂存器(暂时用不到) ;============================================================== CWD:        LCALL  W18B20         MOV  A,#0CCH        ;跳过ROM匹配         LCALL  XIEB20         MOV  A,#0B8H        ;把EEROM里的温度报警值拷贝回暂存器         LCALL  XIEB20         RET ;*************************************************** ;DS18B20 复位与检测子程序 ;SHUJU=1 OK, SHUJU=0 ERROR ;****************************************************    W18B20: SETB    SHUJU         NOP         CLR     SHUJU         MOV     R0,#64H         ; 主机发出延时600微秒的复位低脉冲         MOV     R1,#03H W11:        DJNZ    R0,$         MOV     R0,#64H         DJNZ    R1,W11         SETB    SHUJU           ; 然后拉高数据线         NOP         MOV     R0,#25H WW2:        JNB     SHUJU,WW3       ; 等待DS18B20回应         DJNZ    R0,WW2         JMP     WW4             ; 延时 WW3:    SETB    20H.1          ; 置标志位,表示DS1820存在         JMP     WW5 WW4:           CLR     20H.1          ; 清标志位,表示DS1820不存在         JMP     WW6 WW5:           MOV     R0,#064H         DJNZ    R0,$            ; 时序要求延时一段时间 WW6:           SETB    SHUJU         JNB        20H.1,AAAA        ;DS18B20出错         RET ;============================================================== ;DS18B20错误时LCD显示子程序 ;============================================================== AAAA:        MOV  DPTR,#M_ERROR1  ;指针指到显示信息区         MOV COUNT,#10H       ;地址计数器设为16           MOV  A,#80H          ;第一行起始地址         LCALL  SEND_I        ;调用写指令子程序         LCALL  QUSHU         MOV  DPTR,#M_ERROR2  ;指针指到显示信息区         MOV COUNT,#10H       ;地址计数器设为16         MOV  A,#90H          ;第二行起始地址         LCALL  SEND_I        ;调用写指令子程序         LCALL  QUSHU         MOV  DPTR,#M_ERROR3  ;指针指到显示信息区         MOV COUNT,#10H       ;地址计数器设为16         MOV  A,#88H          ;第三行起始地址         LCALL  SEND_I        ;调用写指令子程序         LCALL  QUSHU           MOV  DPTR,#M_ERROR4  ;指针指到显示信息区         MOV COUNT,#10H       ;地址计数器设为16           MOV  A,#98H          ;第四行起始地址         LCALL  SEND_I        ;调用写指令子程序           LCALL  QUSHU           LCALL        MING1          RET ;-------------------------------------------------------------- ;                       读18B20温度 ;*********************************************************** DU18B20:         MOV     A,#0CCH ;         LCALL   XIEB20         MOV     A,#44H  ;发出温度转换命令         LCALL   XIEB20  ;         LCALL   W18B20  ;         MOV     A,#0CCH ;         LCALL   XIEB20  ;写18B20指令         MOV     A,#0BEH ;发出读温度命令         LCALL   XIEB20  ;               LCALL   WDSJ    ;温度数据         RET        ;=========================================================== ;写入18B20指令 ;=========================================================== XIEB20: MOV     R2,#8           ;一共8位数据         CLR     CY XIE:        CLR     SHUJU           ;开始写入DS18B20总线要处于复位(低)状态         MOV     R3,#09         DJNZ    R3,$            ;总线复位保持18微妙以上         RRC     A               ;把一个字节DATA 分成8个BIT环移给C         MOV     SHUJU,C         ;写入一个BIT         MOV     R3,#23         DJNZ    R3,$            ;等待46微妙         SETB    SHUJU           ;重新释放总线         NOP         DJNZ    R2,XIE          ;写入下一个BIT         SETB    SHUJU         RET ;****************************************************** ;读温度子程序 ;从DS18B20中读出温度低位、高位, ;存入33H,34H,35H,36H ;**************************************************** WDSJ:   MOV     R4,#04H         MOV     R1,#WENDUD        ; 存入33H,34H RE00:          MOV     R2,#8 RE01:          CLR     C         SETB    SHUJU         NOP         NOP         CLR     SHUJU            ;读前总线保持为低         NOP         NOP         NOP         SETB    SHUJU            ;开始读总线释放         MOV     R3,#07           ;延时15微妙         DJNZ    R3,$         MOV     C,SHUJU          ;从DS18B20总线读得一个BIT         MOV     R3,#23         DJNZ    R3,$             ;等待46微妙         RRC     A                ;把读得的位值环移给A         DJNZ    R2,RE01          ;读下一个BIT         MOV     @R1,A         INC     R1         DJNZ    R4,RE00         LCALL        WDCZ         RET ;============================================================== ;处理入水口实际水温度 BCD 码子程序(未考虑百位和负温度值) ;整数部分:取出 WENDUD 高四位和 WENDUG 低四位进行重新组合 ;小数部分:取出 TEMPL1 低四位,查小数码表 ;小数部分:73H;个位:74H;十位:75H ;============================================================== WDCZ:          MOV  A,WENDUD          ANL  A,#0FH              ;取出小数部分          MOV  B,#10               ;将TEMP_L的低四位X10/16得小数后一位数.          MUL  AB          MOV  B,#16          DIV  AB          MOV  73H,A               ;小数部分 BCD          MOV  A,WENDUD            ;整数部分          ANL  A,#0F0H             ;取出高四位          SWAP  A          MOV  WENDUD,A          MOV  A,WENDUG            ;取出低四位          ANL  A,#0FH          SWAP  A          ORL  A,WENDUD            ;重新组合温度数据          MOV  WENDU,A           ;重新组合的温度数据存入WENDU          LCALL  HEX2BCD1          MOV  WENDUD,A            ;(A)=十位数和个位数          ANL  A,#0F0H          SWAP  A          MOV  75H,A               ;十位数 BCD          MOV  A,WENDUD          ANL  A,#0FH          MOV  74H,A               ;个位数 BCD                                            RET        ;============================================================== ;单字节十六进制转BCD ;入口:(A)=单字节十六进制的温度值 ;出口:(A)=十位数和个位数 ;============================================================== HEX2BCD1:          MOV  B,#0AH          DIV  AB          SWAP  A          ORL  A,B              ;(A)=个位数和十位数          RET ;********************************************************** ;**********************送显示****************************** ;********************************************************** S18B20:                MOV  DPTR,#M_OK2       ;指针指到显示信息区         MOV COUNT,#10H         ;地址计数器设为16         MOV  A,#80H            ;第一行起始地址         LCALL  SEND_I          ;调用写指令子程序         LCALL  QUSHU         LCALL  SHOW_D         ;显示设定的恒温水温度值         MOV  DPTR,#M_OK1       ;指针指到显示信息区         MOV COUNT,#10H         ;地址计数器设为16         MOV  A,#90H            ;第二行起始地址         LCALL  SEND_I          ;调用写指令子程序         LCALL  QUSHU         LCALL  SHOW_G         ;显示设定的恒温水温度值         MOV  DPTR,#M_OK3       ;指针指到显示信息区         MOV COUNT,#10H         ;地址计数器设为16         MOV  A,#88H            ;第三行起始地址         LCALL  SEND_I          ;调用写指令子程序         LCALL  QUSHU         LCALL  SHOW_S           ;显示实际温度值         MOV  DPTR,#M_OK4        ;指针指到显示信息区         MOV COUNT,#10H          ;地址计数器设为16         MOV  A,#98H             ;第四行起始地址         LCALL  SEND_I           ;调用写指令子程序         LCALL  QUSHU         RET ;============================================================== ;显示恒温水温度值子程序 ;============================================================== SHOW_G:        MOV  A,#86H        ;设置显示位置         LCALL  SEND_I         MOV  A,SDWDG         MOV  B,#0AH         DIV  AB         ADD  A,#30H        ;十位数转换为 ASCII 码         LCALL  SEND_D       ;送显示         MOV  A,B           ;个位数         ADD  A,#30H        ;个位数转换为 ASCII 码         LCALL  SEND_D       ;送显示                    ;显示恒温水温度值子程序         MOV  A,#87H        ;设置显示位置         LCALL SEND_I         MOV  A,#0A1H       ;显示温度标记℃         LCALL SEND_D         MOV  A,#0E6H         LCALL SEND_D SHOW_D:        MOV  A,#96H        ;设置显示位置         LCALL  SEND_I         MOV  A,SDWDD         MOV  B,#0AH         DIV  AB         ADD  A,#30H        ;十位数转换为 ASCII 码         LCALL  SEND_D       ;送显示         MOV  A,B           ;个位数         ADD  A,#30H        ;个位数转换为 ASCII 码         LCALL  SEND_D       ;送显示                    ;显示恒温水温度值子程序         MOV  A,#97H        ;设置显示位置         LCALL SEND_I         MOV  A,#0A1H       ;显示温度标记℃         LCALL SEND_D         MOV  A,#0E6H         LCALL SEND_D         RET        ;============================================================== ; LCD12864 显示实际温度值子程序 ;============================================================== SHOW_S: MOV  A,#8DH        ;设置显示位置         LCALL  SEND_I         MOV  A,75H         ;加载十位数据         CJNE A,#00H,CONV2 CONV1:         MOV  A,#" "        ;十位数等于0显示空格         LCALL  SEND_D      ;送显示         JMP  CONV3 CONV2:  ADD A,#30H         ;十位数转换成ASCII码         LCALL  SEND_D      ;显示数据 CONV3:         MOV  A,74H         ;个位         ADD  A,#30H        ;个位数转换成ASCII码         CALL  SEND_D       ;送显示         MOV  A,#'.'         CALL  SEND_D       ;送显示         MOV  A,73H         ;加载小数位         ADD  A,#30H        ;小数位转换成ASCII码         CALL  SEND_D       ;送显示         MOV  A,#8FH        ;显示温度标记℃         CALL SEND_I         MOV  A,#0A1H         CALL SEND_D         MOV  A,#0E6H         CALL SEND_D                 RET                ;============================================================== ;取数子程序 ;============================================================== QUSHU:        CLR  A         MOVC  A,@A+DPTR       ;查表取数据         LCALL  SEND_D         ;送显示         INC  DPTR         DJNZ  COUNT,QUSHU         RET ;============================================================== ;写数据子程序 ;RS=1,RW=0,E=高脉冲,D0-D7=数据 ;============================================================== SEND_D:        LCALL CHK_BUSY       ;写数据子程序         SETB RS         CLR RW         MOV P0,A         SETB E         NOP         NOP         CLR E         RET        ;-------------------------------------------------------------- MING1:        SETB        P3.7         LCALL        YS         CLR        P3.7         RET YS:            MOV     R5,#8FH YS1:           MOV     R6,#0FFH YS2:           DJNZ    R6,$         DJNZ    R5,YS1         RET        ;************************按键程序*********************** ANJIAN:        JB      K3,ANJIAN_0        ;按键K3确定修改         LCALL   YS                ;防抖动         JB      K3,ANJIAN_0         LCALL        MING1         LCALL   BBBB                         JNB        K3,$ ANJI_1:        JB      K2,JIAN_2        ;按键K2设定值加1         LCALL   YS                ;防抖动         JB      K2,JIAN_2         LCALL        MING1         MOV     A,SDWDG         INC        A         MOV        SDWDG,A         CLR        C         CJNE        A,#63H,JIAN_01         JMP        JIAN_02 JIAN_01:JC        JIAN_02         MOV        SDWDG,#00H JIAN_02:         LCALL        BBBB         JNB        K2,$ JIAN_2:        JB      K1,ANJI_3      ;按键K1设定值减1         LCALL   YS              ;防抖动         JB      K1,ANJI_3         LCALL        MING1         MOV        A,SDWDG         DEC        A         MOV        SDWDG,A         CLR        C         CJNE        A,#63H,JIAN_21 JIAN_21:JC        JIAN_22         MOV        SDWDG,#63H JIAN_22:JNB        K1,$         LCALL        BBBB        ANJI_3:        JB      K3,ANJI_1        ;按键K3确定退出         LCALL   YS                ;防抖动         JB      K3,ANJI_1         LCALL        MING1         LCALL        CCCC         JNB        K3,$         LJMP        ANJI_4 ANJIAN_0:LJMP        ANJIAN_9 ANJI_4:        JB      K2,JIAN_5        ;按键K2设定值加1         LCALL   YS                ;防抖动         JB      K2,JIAN_5         LCALL        MING1         MOV     A,SDWDD         INC        A         MOV        SDWDD,A         CLR        C         CJNE        A,#63H,JIAN_31         JMP        JIAN_32 JIAN_31:JC        JIAN_32         MOV        SDWDD,#00H JIAN_32:LCALL        CCCC         JNB        K2,$ JIAN_5:        JB      K1,ANJI_6      ;按键K1设定值减1         LCALL   YS              ;防抖动         JB      K1,ANJI_6         LCALL        MING1         MOV        A,SDWDD         DEC        A         MOV        SDWDD,A         CLR        C         CJNE        A,#63H,JIAN_41 JIAN_41:JC        JIAN_42         MOV        SDWDD,#63H JIAN_42:JNB        K1,$         LCALL        CCCC        ANJI_6:        JB      K3,ANJI_4        ;按键K3确定退出         LCALL   YS                ;防抖动         JB      K3,ANJI_4         LCALL        MING1         JNB        K3,$ ANJIAN_9:LCALL        CUN         RET ;============================================================== ;重新对 DS18B20 初始化 ;将设定的温度报警值写入 DS18B20 ;============================================================== CUN:    LCALL  W18b20         MOV  A,#0CCH       ;跳过ROM匹配         LCALL  XIEB20         MOV  A,#4EH        ;写暂存寄存器         LCALL  XIEB20         MOV A,SDWDG         LCALL  XIEB20         MOV A,SDWDD         LCALL  XIEB20        ; MOV  A,#7FH        ;12位精确度        ; LCALL  XIEB20         LCALL  W18B20                ;把 DS18B20 暂存器里的温度报警值拷贝到EEROM         MOV  A,#0CCH        ;跳过ROM匹配         LCALL  XIEB20         MOV  A,#48H         ;把暂存器里的温度报警值拷贝到EEROM         LCALL  XIEB20         RET ;-------------------------------------------------------------- show_g1:MOV  A,#93H        ;设置显示位置         LCALL  SEND_I         MOV  A,SDWDG         MOV  B,#0AH         DIV  AB         ADD  A,#30H        ;十位数转换为 ASCII 码         LCALL  SEND_D       ;送显示         MOV  A,B           ;个位数         ADD  A,#30H        ;个位数转换为 ASCII 码         LCALL  SEND_D       ;送显示                    ;显示恒温水温度值子程序         MOV  A,#94H        ;设置显示位置         LCALL SEND_I         MOV  A,#0A1H       ;显示温度标记℃         LCALL SEND_D         MOV  A,#0E6H         LCALL SEND_D         RET        BBBB:           MOV  DPTR,#M_ERRORA  ;指针指到显示信息区           MOV COUNT,#10H       ;地址计数器设为16           MOV  A,#80H          ;第一行起始地址           LCALL  SEND_I        ;调用写指令子程序           LCALL  QUSHU           MOV  DPTR,#M_ERRORB  ;指针指到显示信息区           MOV COUNT,#10H       ;地址计数器设为16           MOV  A,#90H          ;第二行起始地址           LCALL  SEND_I        ;调用写指令子程序           LCALL  QUSHU         lcall        show_g1         LJMP        DDDD CCCC:           MOV  DPTR,#M_ERRORC  ;指针指到显示信息区           MOV COUNT,#10H       ;地址计数器设为16           MOV  A,#80H          ;第一行起始地址           LCALL  SEND_I        ;调用写指令子程序           LCALL  QUSHU           MOV  DPTR,#M_ERRORD  ;指针指到显示信息区           MOV COUNT,#10H       ;地址计数器设为16           MOV  A,#90H          ;第二行起始地址           LCALL  SEND_I        ;调用写指令子程序           LCALL  QUSHU          lcall        show_d DDDD:        MOV  DPTR,#M_ERROR3          ;指针指到显示信息区           MOV COUNT,#10H       ;地址计数器设为16           MOV  A,#88H          ;第三行起始地址           LCALL  SEND_I        ;调用写指令子程序           LCALL  QUSHU           MOV  DPTR,#M_ERROR4  ;指针指到显示信息区           MOV COUNT,#10H       ;地址计数器设为16           MOV  A,#98H          ;第四行起始地址           LCALL  SEND_I        ;调用写指令子程序           LCALL  QUSHU         RET ;-------------------------------------------------------------- M_OK1:                DB   '设定低温度:    '                ;显示在第一行 M_OK2:                DB   '设定高温度:    '                ;显示在第二行 M_OK3:                DB   '实际温度:       '                ;显示在第三行 M_OK4:                DB   '  QQ:80908900  '                ;显示在第四行 M_ERRORA:        DB   '  设定高温度!   '                ;显示在第一行 M_ERRORB:        DB   '                '                ;显示在第二行 M_ERRORC:        DB   '  设定低温度!   '                ;显示在第一行 M_ERRORD:        DB   '                     '                ;显示在第二行 M_ERROR1:        DB   '  温度探头错误!'                ;显示在第一行 M_ERROR2:        DB   '    请检查!    '                ;显示在第二行 M_ERROR3:        DB   '    风也有情    '                ;显示在第三行 M_ERROR4:        DB   '  QQ:80908900  '                ;显示在第四行 ;*************************************************************                END 这是我的51通信,希望对你有用。  详情 回复 发表于 2008-3-18 12:16
点赞 关注
 

回复
举报

11

帖子

0

TA的资源

一粒金砂(初级)

沙发
 

回复:串口资料的无奈

看单片机的数据手册。
此帖出自单片机论坛
 
 

回复

446

帖子

0

TA的资源

裸片初长成(高级)

板凳
 

回复:串口资料的无奈

多机通讯我肯定是说通讯方式2和3了。 如果其他我好几本书,不可能看不出来。 通讯方式0只能当移位输出
此帖出自单片机论坛
 
 
 

回复

5

帖子

0

TA的资源

一粒金砂(初级)

4
 

回复:串口资料的无奈

硬件自动处理是在SM2=1;而SM2=0时怎么办?当然要软件处理啊.主要用与多机通讯时,判断此次数据是地址帧还是数据帧.一般可以这么做: 开始各端点SM2=0时,全部接受,接受到数据后判断RB8是否为1(地址帧为1数据帧为0),如果RB为1,表示此次接受为地址帧,可以与自己的身份地址比较,如果不是就可以设置SM2=1,这样接下来发送数据帧(TB为0)都被自动丢弃了.
此帖出自单片机论坛
 
 
 

回复

5

帖子

0

TA的资源

一粒金砂(初级)

5
 

回复:串口资料的无奈

lz只要写过通讯协议的估计都能明白.
此帖出自单片机论坛
 
 
 

回复

43

帖子

0

TA的资源

一粒金砂(初级)

6
 

回复:串口资料的无奈

1、先搞清楚硬件过滤和软件过滤的区别,2、你自己设计的话怎么做? 别人的程序不一致时就别去看程序,自己先把方法想好,想周全,自然就会编了
此帖出自单片机论坛
 
 
 

回复

399

帖子

0

TA的资源

裸片初长成(初级)

7
 

回复:串口资料的无奈

;******************************************************** ;************************显视温度************************ ;******************************************************** COUNT DATA 41H ;地址计数常数 WENDU DATA 37H ;实际温度地址 WENDUD DATA 38H ;温度低位地址 WENDUG DATA 39H ;温度高位地址 SDWDG DATA 3aH ;设定高温度地址 SDWDD DATA 3bH ;设定低温度地址 TEMP EQU 30H TEMP1 EQU 31H BUF EQU 32H DISBUF EQU 40H PLAYFLAG BIT 22H.0 ;---------------------------------------------------------------- RS EQU P2.0 ; RW EQU P2.1 ; E EQU P2.2 ; PSB EQU P2.3 ; RST EQU P2.5 ; SHUJU EQU P3.3 ; K1 EQU P1.4 ;按键1,设定温度值减1 K2 EQU P1.5 ;按键2,设定温度值加1 K3 EQU P1.6 ;按键3,确定修改和确定退出 ;============================================================ ORG 0000H JMP MAIN ORG 0040H ;============================================================ MAIN: CLR P3.7 LCALL SET_LCD ;初始化 LCD 12864 LCALL W18B20 ;初始化18B20 LCALL CWD ;******************************************************** WANG: LCALL W18B20 ;初始化18B20 LCALL DU18B20 ;读18B20温度 LCALL S18B20 ;送温度显视 LCALL ANJIAN ;按键程序 CLR PLAYFLAG MOV TMOD,#20H ;定时器1工作于8位自动重载模式,用于产生波特率 MOV TH1,#0FDH MOV TL1,#0FDH ;波特率9600 MOV SCON,#50H ;设定串行口工作方式 ANL PCON,#00H ;波特率不倍增 SETB TR1 ;启动定时器1 SENDDATA: MOV A,WENDU MOV SBUF,A JNB TI,$ ; 等特数据传送 CLR TI ; 清除数据传送标志 LJMP WANG ;============================================================== ;对 LCD12864 做初始化设置 ;============================================================== SET_LCD: SETB PSB ;通讯方式为8位数据并口 MOV A,#34H ;34H--扩充指令操作 LCALL SEND_I MOV A,#30H ;30H--8bit控制界面,基本指令操作 LCALL SEND_I MOV A,#01H ;清除显示 LCALL SEND_I MOV A,#06H ;指定在资料写入或读取时,光标的移动方向 LCALL SEND_I ;DDRAM 的地址计数器(AC)加1 MOV A,#0CH ;开显示,关光标,不闪烁 LCALL SEND_I RET ;============================================================== ;写指令子程序 ;RS=0,RW=0,E=高脉冲,D0-D7=指令码 ;============================================================== SEND_I: LCALL CHK_BUSY CLR RS CLR RW MOV P0,A SETB E NOP NOP CLR E RET ;============================================================== ;测忙碌子程序 ;RS=0,RW=1,E=H,D0-D7=状态字 ;============================================================== CHK_BUSY: MOV P0,#0FFH ;测忙碌子程序 CLR RS SETB RW SETB E JB P0.7,$ CLR E RET ;============================================================== ;把 DS18B20 EEROM 里的温度报警值拷贝回暂存器(暂时用不到) ;============================================================== CWD: LCALL W18B20 MOV A,#0CCH ;跳过ROM匹配 LCALL XIEB20 MOV A,#0B8H ;把EEROM里的温度报警值拷贝回暂存器 LCALL XIEB20 RET ;*************************************************** ;DS18B20 复位与检测子程序 ;SHUJU=1 OK, SHUJU=0 ERROR ;**************************************************** W18B20: SETB SHUJU NOP CLR SHUJU MOV R0,#64H ; 主机发出延时600微秒的复位低脉冲 MOV R1,#03H W11: DJNZ R0,$ MOV R0,#64H DJNZ R1,W11 SETB SHUJU ; 然后拉高数据线 NOP MOV R0,#25H WW2: JNB SHUJU,WW3 ; 等待DS18B20回应 DJNZ R0,WW2 JMP WW4 ; 延时 WW3: SETB 20H.1 ; 置标志位,表示DS1820存在 JMP WW5 WW4: CLR 20H.1 ; 清标志位,表示DS1820不存在 JMP WW6 WW5: MOV R0,#064H DJNZ R0,$ ; 时序要求延时一段时间 WW6: SETB SHUJU JNB 20H.1,AAAA ;DS18B20出错 RET ;============================================================== ;DS18B20错误时LCD显示子程序 ;============================================================== AAAA: MOV DPTR,#M_ERROR1 ;指针指到显示信息区 MOV COUNT,#10H ;地址计数器设为16 MOV A,#80H ;第一行起始地址 LCALL SEND_I ;调用写指令子程序 LCALL QUSHU MOV DPTR,#M_ERROR2 ;指针指到显示信息区 MOV COUNT,#10H ;地址计数器设为16 MOV A,#90H ;第二行起始地址 LCALL SEND_I ;调用写指令子程序 LCALL QUSHU MOV DPTR,#M_ERROR3 ;指针指到显示信息区 MOV COUNT,#10H ;地址计数器设为16 MOV A,#88H ;第三行起始地址 LCALL SEND_I ;调用写指令子程序 LCALL QUSHU MOV DPTR,#M_ERROR4 ;指针指到显示信息区 MOV COUNT,#10H ;地址计数器设为16 MOV A,#98H ;第四行起始地址 LCALL SEND_I ;调用写指令子程序 LCALL QUSHU LCALL MING1 RET ;-------------------------------------------------------------- ; 读18B20温度 ;*********************************************************** DU18B20: MOV A,#0CCH ; LCALL XIEB20 MOV A,#44H ;发出温度转换命令 LCALL XIEB20 ; LCALL W18B20 ; MOV A,#0CCH ; LCALL XIEB20 ;写18B20指令 MOV A,#0BEH ;发出读温度命令 LCALL XIEB20 ; LCALL WDSJ ;温度数据 RET ;=========================================================== ;写入18B20指令 ;=========================================================== XIEB20: MOV R2,#8 ;一共8位数据 CLR CY XIE: CLR SHUJU ;开始写入DS18B20总线要处于复位(低)状态 MOV R3,#09 DJNZ R3,$ ;总线复位保持18微妙以上 RRC A ;把一个字节DATA 分成8个BIT环移给C MOV SHUJU,C ;写入一个BIT MOV R3,#23 DJNZ R3,$ ;等待46微妙 SETB SHUJU ;重新释放总线 NOP DJNZ R2,XIE ;写入下一个BIT SETB SHUJU RET ;****************************************************** ;读温度子程序 ;从DS18B20中读出温度低位、高位, ;存入33H,34H,35H,36H ;**************************************************** WDSJ: MOV R4,#04H MOV R1,#WENDUD ; 存入33H,34H RE00: MOV R2,#8 RE01: CLR C SETB SHUJU NOP NOP CLR SHUJU ;读前总线保持为低 NOP NOP NOP SETB SHUJU ;开始读总线释放 MOV R3,#07 ;延时15微妙 DJNZ R3,$ MOV C,SHUJU ;从DS18B20总线读得一个BIT MOV R3,#23 DJNZ R3,$ ;等待46微妙 RRC A ;把读得的位值环移给A DJNZ R2,RE01 ;读下一个BIT MOV @R1,A INC R1 DJNZ R4,RE00 LCALL WDCZ RET ;============================================================== ;处理入水口实际水温度 BCD 码子程序(未考虑百位和负温度值) ;整数部分:取出 WENDUD 高四位和 WENDUG 低四位进行重新组合 ;小数部分:取出 TEMPL1 低四位,查小数码表 ;小数部分:73H;个位:74H;十位:75H ;============================================================== WDCZ: MOV A,WENDUD ANL A,#0FH ;取出小数部分 MOV B,#10 ;将TEMP_L的低四位X10/16得小数后一位数. MUL AB MOV B,#16 DIV AB MOV 73H,A ;小数部分 BCD MOV A,WENDUD ;整数部分 ANL A,#0F0H ;取出高四位 SWAP A MOV WENDUD,A MOV A,WENDUG ;取出低四位 ANL A,#0FH SWAP A ORL A,WENDUD ;重新组合温度数据 MOV WENDU,A ;重新组合的温度数据存入WENDU LCALL HEX2BCD1 MOV WENDUD,A ;(A)=十位数和个位数 ANL A,#0F0H SWAP A MOV 75H,A ;十位数 BCD MOV A,WENDUD ANL A,#0FH MOV 74H,A ;个位数 BCD RET ;============================================================== ;单字节十六进制转BCD ;入口:(A)=单字节十六进制的温度值 ;出口:(A)=十位数和个位数 ;============================================================== HEX2BCD1: MOV B,#0AH DIV AB SWAP A ORL A,B ;(A)=个位数和十位数 RET ;********************************************************** ;**********************送显示****************************** ;********************************************************** S18B20: MOV DPTR,#M_OK2 ;指针指到显示信息区 MOV COUNT,#10H ;地址计数器设为16 MOV A,#80H ;第一行起始地址 LCALL SEND_I ;调用写指令子程序 LCALL QUSHU LCALL SHOW_D ;显示设定的恒温水温度值 MOV DPTR,#M_OK1 ;指针指到显示信息区 MOV COUNT,#10H ;地址计数器设为16 MOV A,#90H ;第二行起始地址 LCALL SEND_I ;调用写指令子程序 LCALL QUSHU LCALL SHOW_G ;显示设定的恒温水温度值 MOV DPTR,#M_OK3 ;指针指到显示信息区 MOV COUNT,#10H ;地址计数器设为16 MOV A,#88H ;第三行起始地址 LCALL SEND_I ;调用写指令子程序 LCALL QUSHU LCALL SHOW_S ;显示实际温度值 MOV DPTR,#M_OK4 ;指针指到显示信息区 MOV COUNT,#10H ;地址计数器设为16 MOV A,#98H ;第四行起始地址 LCALL SEND_I ;调用写指令子程序 LCALL QUSHU RET ;============================================================== ;显示恒温水温度值子程序 ;============================================================== SHOW_G: MOV A,#86H ;设置显示位置 LCALL SEND_I MOV A,SDWDG MOV B,#0AH DIV AB ADD A,#30H ;十位数转换为 ASCII 码 LCALL SEND_D ;送显示 MOV A,B ;个位数 ADD A,#30H ;个位数转换为 ASCII 码 LCALL SEND_D ;送显示 ;显示恒温水温度值子程序 MOV A,#87H ;设置显示位置 LCALL SEND_I MOV A,#0A1H ;显示温度标记℃ LCALL SEND_D MOV A,#0E6H LCALL SEND_D SHOW_D: MOV A,#96H ;设置显示位置 LCALL SEND_I MOV A,SDWDD MOV B,#0AH DIV AB ADD A,#30H ;十位数转换为 ASCII 码 LCALL SEND_D ;送显示 MOV A,B ;个位数 ADD A,#30H ;个位数转换为 ASCII 码 LCALL SEND_D ;送显示 ;显示恒温水温度值子程序 MOV A,#97H ;设置显示位置 LCALL SEND_I MOV A,#0A1H ;显示温度标记℃ LCALL SEND_D MOV A,#0E6H LCALL SEND_D RET ;============================================================== ; LCD12864 显示实际温度值子程序 ;============================================================== SHOW_S: MOV A,#8DH ;设置显示位置 LCALL SEND_I MOV A,75H ;加载十位数据 CJNE A,#00H,CONV2 CONV1: MOV A,#" " ;十位数等于0显示空格 LCALL SEND_D ;送显示 JMP CONV3 CONV2: ADD A,#30H ;十位数转换成ASCII码 LCALL SEND_D ;显示数据 CONV3: MOV A,74H ;个位 ADD A,#30H ;个位数转换成ASCII码 CALL SEND_D ;送显示 MOV A,#'.' CALL SEND_D ;送显示 MOV A,73H ;加载小数位 ADD A,#30H ;小数位转换成ASCII码 CALL SEND_D ;送显示 MOV A,#8FH ;显示温度标记℃ CALL SEND_I MOV A,#0A1H CALL SEND_D MOV A,#0E6H CALL SEND_D RET ;============================================================== ;取数子程序 ;============================================================== QUSHU: CLR A MOVC A,@A+DPTR ;查表取数据 LCALL SEND_D ;送显示 INC DPTR DJNZ COUNT,QUSHU RET ;============================================================== ;写数据子程序 ;RS=1,RW=0,E=高脉冲,D0-D7=数据 ;============================================================== SEND_D: LCALL CHK_BUSY ;写数据子程序 SETB RS CLR RW MOV P0,A SETB E NOP NOP CLR E RET ;-------------------------------------------------------------- MING1: SETB P3.7 LCALL YS CLR P3.7 RET YS: MOV R5,#8FH YS1: MOV R6,#0FFH YS2: DJNZ R6,$ DJNZ R5,YS1 RET ;************************按键程序*********************** ANJIAN: JB K3,ANJIAN_0 ;按键K3确定修改 LCALL YS ;防抖动 JB K3,ANJIAN_0 LCALL MING1 LCALL BBBB JNB K3,$ ANJI_1: JB K2,JIAN_2 ;按键K2设定值加1 LCALL YS ;防抖动 JB K2,JIAN_2 LCALL MING1 MOV A,SDWDG INC A MOV SDWDG,A CLR C CJNE A,#63H,JIAN_01 JMP JIAN_02 JIAN_01:JC JIAN_02 MOV SDWDG,#00H JIAN_02: LCALL BBBB JNB K2,$ JIAN_2: JB K1,ANJI_3 ;按键K1设定值减1 LCALL YS ;防抖动 JB K1,ANJI_3 LCALL MING1 MOV A,SDWDG DEC A MOV SDWDG,A CLR C CJNE A,#63H,JIAN_21 JIAN_21:JC JIAN_22 MOV SDWDG,#63H JIAN_22:JNB K1,$ LCALL BBBB ANJI_3: JB K3,ANJI_1 ;按键K3确定退出 LCALL YS ;防抖动 JB K3,ANJI_1 LCALL MING1 LCALL CCCC JNB K3,$ LJMP ANJI_4 ANJIAN_0:LJMP ANJIAN_9 ANJI_4: JB K2,JIAN_5 ;按键K2设定值加1 LCALL YS ;防抖动 JB K2,JIAN_5 LCALL MING1 MOV A,SDWDD INC A MOV SDWDD,A CLR C CJNE A,#63H,JIAN_31 JMP JIAN_32 JIAN_31:JC JIAN_32 MOV SDWDD,#00H JIAN_32:LCALL CCCC JNB K2,$ JIAN_5: JB K1,ANJI_6 ;按键K1设定值减1 LCALL YS ;防抖动 JB K1,ANJI_6 LCALL MING1 MOV A,SDWDD DEC A MOV SDWDD,A CLR C CJNE A,#63H,JIAN_41 JIAN_41:JC JIAN_42 MOV SDWDD,#63H JIAN_42:JNB K1,$ LCALL CCCC ANJI_6: JB K3,ANJI_4 ;按键K3确定退出 LCALL YS ;防抖动 JB K3,ANJI_4 LCALL MING1 JNB K3,$ ANJIAN_9:LCALL CUN RET ;============================================================== ;重新对 DS18B20 初始化 ;将设定的温度报警值写入 DS18B20 ;============================================================== CUN: LCALL W18b20 MOV A,#0CCH ;跳过ROM匹配 LCALL XIEB20 MOV A,#4EH ;写暂存寄存器 LCALL XIEB20 MOV A,SDWDG LCALL XIEB20 MOV A,SDWDD LCALL XIEB20 ; MOV A,#7FH ;12位精确度 ; LCALL XIEB20 LCALL W18B20 ;把 DS18B20 暂存器里的温度报警值拷贝到EEROM MOV A,#0CCH ;跳过ROM匹配 LCALL XIEB20 MOV A,#48H ;把暂存器里的温度报警值拷贝到EEROM LCALL XIEB20 RET ;-------------------------------------------------------------- show_g1:MOV A,#93H ;设置显示位置 LCALL SEND_I MOV A,SDWDG MOV B,#0AH DIV AB ADD A,#30H ;十位数转换为 ASCII 码 LCALL SEND_D ;送显示 MOV A,B ;个位数 ADD A,#30H ;个位数转换为 ASCII 码 LCALL SEND_D ;送显示 ;显示恒温水温度值子程序 MOV A,#94H ;设置显示位置 LCALL SEND_I MOV A,#0A1H ;显示温度标记℃ LCALL SEND_D MOV A,#0E6H LCALL SEND_D RET BBBB: MOV DPTR,#M_ERRORA ;指针指到显示信息区 MOV COUNT,#10H ;地址计数器设为16 MOV A,#80H ;第一行起始地址 LCALL SEND_I ;调用写指令子程序 LCALL QUSHU MOV DPTR,#M_ERRORB ;指针指到显示信息区 MOV COUNT,#10H ;地址计数器设为16 MOV A,#90H ;第二行起始地址 LCALL SEND_I ;调用写指令子程序 LCALL QUSHU lcall show_g1 LJMP DDDD CCCC: MOV DPTR,#M_ERRORC ;指针指到显示信息区 MOV COUNT,#10H ;地址计数器设为16 MOV A,#80H ;第一行起始地址 LCALL SEND_I ;调用写指令子程序 LCALL QUSHU MOV DPTR,#M_ERRORD ;指针指到显示信息区 MOV COUNT,#10H ;地址计数器设为16 MOV A,#90H ;第二行起始地址 LCALL SEND_I ;调用写指令子程序 LCALL QUSHU lcall show_d DDDD: MOV DPTR,#M_ERROR3 ;指针指到显示信息区 MOV COUNT,#10H ;地址计数器设为16 MOV A,#88H ;第三行起始地址 LCALL SEND_I ;调用写指令子程序 LCALL QUSHU MOV DPTR,#M_ERROR4 ;指针指到显示信息区 MOV COUNT,#10H ;地址计数器设为16 MOV A,#98H ;第四行起始地址 LCALL SEND_I ;调用写指令子程序 LCALL QUSHU RET ;-------------------------------------------------------------- M_OK1: DB '设定低温度: ' ;显示在第一行 M_OK2: DB '设定高温度: ' ;显示在第二行 M_OK3: DB '实际温度: ' ;显示在第三行 M_OK4: DB ' QQ:80908900 ' ;显示在第四行 M_ERRORA: DB ' 设定高温度! ' ;显示在第一行 M_ERRORB: DB ' ' ;显示在第二行 M_ERRORC: DB ' 设定低温度! ' ;显示在第一行 M_ERRORD: DB ' ' ;显示在第二行 M_ERROR1: DB ' 温度探头错误!' ;显示在第一行 M_ERROR2: DB ' 请检查! ' ;显示在第二行 M_ERROR3: DB ' 风也有情 ' ;显示在第三行 M_ERROR4: DB ' QQ:80908900 ' ;显示在第四行 ;************************************************************* END 这是我的51通信,希望对你有用。
此帖出自单片机论坛
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

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

 
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
快速回复 返回顶部 返回列表