找回密码
 注册会员
更新自动建库工具PCB Footprint Expert 2024.04 Pro / Library Expert 破解版

无时钟芯片的电子钟,带年月日,24小时制,带温度显示(用18b20),液

[复制链接]
admin 发表于 2012-9-2 08:08:03 | 显示全部楼层 |阅读模式

本文包含原理图、PCB、源代码、封装库、中英文PDF等资源

您需要 登录 才可以下载或查看,没有账号?注册会员

×
;数字温度传感器,带日期,带时钟,12M晶体,1602显示。。。
TEMP EQU 30H
NIAN EQU 31H ;32H,33H,34H
YUE EQU 35H;36H
RIRI EQU 37H;38H
SHI EQU 50H;51H
FEN EQU 52H;53H
TEMP1 EQU 40H ;温度高8位 十位
TEMP2 EQU 41H ;温度低8位 ,,个位
TEMP3 EQU 42H ;十分位
RS EQU P2.5;确定具体硬件的连接方式
RW EQU P2.6 ;确定具体硬件的连接方式
E EQU P2.7 ;确定具体硬件的连接方式

ORG 000H
LJMP START
ORG 0BH
LJMP TIM0



START: ;;;;;;;;定时中断初始化
MOV TMOD,#01H ;T0工作在方式1
MOV TH0,#HIGH(65536-10000) ;定时10000微秒
MOV TL0,#LOW(65536-10000)
SETB TR0 ;启动定时
MOV IE,#10000010B ;开中断
MOV R1,#100 ;10000*100=1s
;;;;;;;;;;;;;;;LCD初始化

;;;;;;;;;;;;;;;;;;;;;;;; 时间初始化
MOV 53H ,#39H
MOV 52H,#33H
MOV 51H, #30H
MOV 50H,#32H
MOV 57H,#0

MOV 35H,#30H
MOV 36H,#38H
MOV 37H,#31H
MOV 38H,#38H
MAIN: JB P2.0,LOOP9 ;p2.0为1则转移,否则继续下步
ACALL DELAY10
JB P2.0,LOOP9
JNB P2.0,$
CLR TR0
YYY: JNB P2.0,YYY1 ;P2.0为0则转移,否则继续下步
ACALL DELAY10
JNB P2.0 ,YYY1
;JB P2.0 ,$
JB P2.1,NET
ACALL DELAY10
JB P2.1,NET
JNB P2.1 ,$
INC 53H
NET: JB P2.2 ,NET1
ACALL DELAY10
JB P2.2, NET1
JNB P2.2 ,$
DEC 53H
NET1: JB P2.3,YYY
ACALL DELAY10
JB P2.3,YYY
JNB P2.3,$
SETB TR0
JMP LOOP9

YYY1: /*JNB P2.0,YYY2 ;P2.0为0则转移,否则继续下步
ACALL DELAY10
JNB P2.0 ,YYY2 */



JB P2.1,NET2
ACALL DELAY10
JB P2.1,NET2
JNB P2.1 ,$
INC 52H
NET2: JB P2.2 ,NET3
ACALL DELAY10
JB P2.2, NET3
JNB P2.2 ,$
DEC 52H
NET3: JB P2.3,YYY1
ACALL DELAY10
JB P2.3,YYY1
JNB P2.3,$
SETB TR0
JMP LOOP9

/*YYY2:

JB P2.1,NET4
ACALL DELAY10
JB P2.1,NET4
JNB P2.1 ,$
INC 51H
NET4: JB P2.2 ,NET5
ACALL DELAY10
JB P2.2, NET5
JNB P2.2 ,$
DEC 51H
NET5: JB P2.3,YYY2
ACALL DELAY10
JB P2.3,YYY2
JNB P2.3,$
SETB TR0
JMP LOOP9 */




/*;;;;;;;;;;;;;;;;;;;;;;;时间变化程序
MOV A,53H
CJNE A,#3AH,JJJ ;分钟后位是否到10判断
MOV 53H,#30H ;到10复位置0
INC 52H ;分钟前位加1
MOV A,52H
CJNE A,#36H,JJJ ;分钟前位是否到6判断
MOV 52H,#30H ;到6复位置1
INC 51H ;时后位加1
MOV A,51H
CJNE A,#34H,LOOP3 ;时后位到4判断
MOV A,50H ;到4则判断时前位到2
CJNE A,#32H,JJJ ;时前位到2判断
MOV 50H,#30H ;如果条件满足,时两位同时置0
MOV 51H,#30H
LOOP3: CJNE A,#3AH,JJJ ;时后位是否到9
MOV 51H,#30H ;到则置0
INC 50H ;时前位加1
JMP JJJ */
LOOP9: MOV A,36H
MOV B,#2
DIV AB
MOV A,B
JZ LOOP4 ;等于零,31天,转移

MOV A,38H ;31天程序
CJNE A,#31H,XXX2
MOV A,37H
CJNE A,#33H,JJJ
MOV 37H,#30H
MOV 38H,#31H
INC 36H
MOV A,36H
CJNE A,#33H,XXX1
MOV A,35H
CJNE A,#31H,JJJ
MOV 36H,#31H
MOV 35H,#30H
JMP JJJ
XXX1: CJNE A,#3AH,JJJ
MOV 36H,#30H
INC 35H
JMP JJJ
XXX2:CJNE A,#3AH,JJJ
MOV 38H,#30H
INC 37H
JMP JJJ


LOOP4:
MOV A,38H ;31天程序
CJNE A,#32H,XXX4
MOV A,37H
CJNE A,#33H,JJJ
MOV 37H,#30H
MOV 38H,#31H
INC 36H
MOV A,36H
CJNE A,#33H,XXX3
MOV A,35H
CJNE A,#31H,JJJ
MOV 36H,#31H
MOV 35H,#30H
JMP JJJ
XXX3: CJNE A,#3AH,JJJ
MOV 36H,#30H
INC 35H
JMP JJJ
XXX4:CJNE A,#3AH,JJJ
MOV 38H,#30H
INC 37H




JJJ: LCALL RESET ; ;ds18b20复位
MOV A,#0CCH ;发SKIP ROM命令,忽略64位ROM地址,直接向DS18B20发温度变换命令,适用于单片工作。
LCALL WRITE
MOV A,#44H ;发开始温度转换命令,启动DS18B20进行温度转换,转换时间最长为500MS,(典型为200MS),结果存入内部9字节RAM中。
LCALL WRITE
LCALL DLY1S ; ;延时
LCALL RESET ; ; ds18b20复位
MOV A,#0CCH ;;发SKIP ROM命令
LCALL WRITE
MOV A,#0BEH ;发读存储器命令,读内部RAM中9字节内容。
LCALL WRITE
LCALL READ ;读出温度值1
MOV TEMP2,TEMP ; ;温度低8位存放41H
LCALL READ ;读出温度值2
MOV TEMP1,TEMP ; ;温度高8位存放在40H
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;开始数值转换
MOV A,41H
RR A
RR A
RR A ;;把D3位右移到D0
ANL A,#01H ;;除D0位,其他全部置零
MOV B,#5
MUL AB ;;由于原D3位权值为0.5,故扩大10倍乘5后放十分位
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ANL A,#00111111B ;将要显示的温度值转换成lcd能识别的代码,0到9为0011xxxxB,所以要把高四位转换成0011,两条语句可以搞定。
ORL A,#00110000B
MOV 42H,A ;十分位转换结束,送42H保存
NOP ;设置断点,方便修改和查阅
MOV A, 40H
ANL A, #0FH ;把40H中高四位置零
RL A
RL A
RL A
RL A ; ;40H左移4位
MOV 40H, A ;40H中低四位移到高四位,低四位为零
MOV A, 41H
ANL A, #0F0H ;把41H中小数点后的值全部置零
RR A
RR A
RR A
RR A ; ;41H右移4位
MOV 41H, A ; 把41H中高四位移到低四位,高四位置零
MOV A, 40H
ORL A, 41H ;组成新的带符号无小数点的八位数字温度,最高位为符号位
MOV 43H,A ;暂存温度值,原41H的高4位做43H的低4位,原40H的低4位做43H的高4位

ANL A,#80H ; 除最高位有效,其他置零
RR A
RR A
RR A
RR A
MOV 44H,A ;判断温度值的符号位,把结果放44H,44H中要只有0和8,0为正,8为负
NOP
MOV A,43H ;恢复带符号八位无小数点温度
ANL A,#7FH ;屏蔽符号位
MOV B, #0AH
DIV AB ; ;无符号温度值除以10
MOV 40H, A ; ;商送40H暂存
MOV A, B ; ;余数通过A送41H保存
ANL A,#00111111B;将要显示的温度值转换成lcd能识别的代码,0到9为0011xxxxB,所以要半高四位转换成0011,两条语句可以搞定。
ORL A,#00110000B
MOV TEMP2, A ;存个位十进制温度值
MOV A,40H
MOV B,#0AH
DIV AB ;;商作为被除数再除以10
MOV 39H,A ;商存入39H,存百位十进制温度值
MOV A,B ; ;余数通过A送40H保存
ANL A,#00111111B;将要显示的温度值转换成lcd能识别的代码,0到9为0011xxxxB,所以要半高四位转换成0011,两条语句可以搞定。
ORL A,#00110000B
MOV TEMP1,A ;存十位十进制温度值

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;开始显示程序
LOOP:MOV P0,#00000001B ;;清屏并光标复位
ACALL ENABLE;调用写入命令子程序

MOV P0,#00111000B; ;设置显示模式:8位2行5x7点阵
ACALL ENABLE ;调用写入命令子程序

MOV P0,#00001100B; ;显示器开、光标开、光标允许闪烁
ACALL ENABLE ;调用写入命令子程序

MOV P0,#00000110B; ;文字不动,光标自动右移
ACALL ENABLE ;调用写入命令子程序

;;;;;;;;;;;;;;;;;;;;;;;;;显示扫描程序
;;;;;;;;;;;;;;;;;时间显示

MOV P0,#80H; ;写入显示起始地址
ACALL ENABLE ;调用写入命令子程序
MOV A,#32H;NIAN
MOV P0,A; 温度个位代码写入

SETB RS; ;RS=1
CLR RW; ;RW=0 ;准备写入数据
CLR E; ;E=0 ;执行显示命令
ACALL DELAY ;判断液晶模块是否忙?
SETB E; ;E=1 ;显示完成,程序停车

MOV P0,#81H; ;写入显示起始地址
ACALL ENABLE ;调用写入命令子程序
MOV A,#30H;32H
MOV P0,A; 温度个位代码写入

SETB RS; ;RS=1
CLR RW; ;RW=0 ;准备写入数据
CLR E; ;E=0 ;执行显示命令
ACALL DELAY ;判断液晶模块是否忙?
SETB E; ;E=1 ;显示完成,程序停车

MOV P0,#82H; ;写入显示起始地址
ACALL ENABLE ;调用写入命令子程序
MOV A,#30H;33H
MOV P0,A; 温度个位代码写入

SETB RS; ;RS=1
CLR RW; ;RW=0 ;准备写入数据
CLR E; ;E=0 ;执行显示命令
ACALL DELAY ;判断液晶模块是否忙?
SETB E; ;E=1 ;显示完成,程序停车
;;;;;;;;;;;;;;;;
MOV P0,#83H; ;写入显示起始地址
ACALL ENABLE ;调用写入命令子程序
MOV A,#39H;34H
MOV P0,A; 温度个位代码写入

SETB RS; ;RS=1
CLR RW; ;RW=0 ;准备写入数据
CLR E; ;E=0 ;执行显示命令
ACALL DELAY ;判断液晶模块是否忙?
SETB E; ;E=1 ;显示完成,程序停车

MOV P0,#84H; ;写入显示起始地址
ACALL ENABLE ;调用写入命令子程序
MOV A,#2FH
MOV P0,A; 温度个位代码写入

SETB RS; ;RS=1
CLR RW; ;RW=0 ;准备写入数据
CLR E; ;E=0 ;执行显示命令
ACALL DELAY ;判断液晶模块是否忙?
SETB E; ;E=1 ;显示完成,程序停车

MOV P0,#85H; ;写入显示起始地址
ACALL ENABLE ;调用写入命令子程序
MOV A,35H
MOV P0,A; 温度个位代码写入

SETB RS; ;RS=1
CLR RW; ;RW=0 ;准备写入数据
CLR E; ;E=0 ;执行显示命令
ACALL DELAY ;判断液晶模块是否忙?
SETB E; ;E=1 ;显示完成,程序停车

MOV P0,#86H; ;写入显示起始地址
ACALL ENABLE ;调用写入命令子程序
MOV A,36H
MOV P0,A; 温度个位代码写入

SETB RS; ;RS=1
CLR RW; ;RW=0 ;准备写入数据
CLR E; ;E=0 ;执行显示命令
ACALL DELAY ;判断液晶模块是否忙?
SETB E; ;E=1 ;显示完成,程序停车

MOV P0,#87H; ;写入显示起始地址
ACALL ENABLE ;调用写入命令子程序
MOV A,#2FH
MOV P0,A; 温度个位代码写入

SETB RS; ;RS=1
CLR RW; ;RW=0 ;准备写入数据
CLR E; ;E=0 ;执行显示命令
ACALL DELAY ;判断液晶模块是否忙?
SETB E; ;E=1 ;显示完成,程序停车

MOV P0,#88H; ;写入显示起始地址
ACALL ENABLE ;调用写入命令子程序
MOV A,37H
MOV P0,A; 温度个位代码写入

SETB RS; ;RS=1
CLR RW; ;RW=0 ;准备写入数据
CLR E; ;E=0 ;执行显示命令
ACALL DELAY ;判断液晶模块是否忙?
SETB E; ;E=1 ;显示完成,程序停车



MOV P0,#89H; ;写入显示起始地址
ACALL ENABLE ;调用写入命令子程序
MOV A,38H
MOV P0,A; 温度个位代码写入

SETB RS; ;RS=1
CLR RW; ;RW=0 ;
 楼主| admin 发表于 2012-9-2 08:08:08 | 显示全部楼层
准备写入数据
CLR E; ;E=0 ;执行显示命令
ACALL DELAY ;判断液晶模块是否忙?
SETB E; ;E=1 ;显示完成,程序停车

;;;;;;;;;;;;;;;;;;;;温度显示程序

MOV P0,#0C0H; ;写入显示起始地址
ACALL ENABLE ;调用写入命令子程序
MOV A,44h ;调入符号代码
cjne a,#0 ,loopp;如果不等于零,则是负号,跳,等于零为正号,下一步
mov p0,#00101011b;写入正号代码
jmp loopp1;跳使能
loopp: mov p0,#00101101b;写如负号代码,下一步。

loopp1:SETB RS; ;RS=1
CLR RW; ;RW=0 ;准备写入数据
CLR E; ;E=0 ;执行显示命令
ACALL DELAY ;判断液晶模块是否忙?
SETB E; ;E=1 ;显示完成,程序停车

MOV P0,#0C1H; ;写入显示起始地址
ACALL ENABLE ;调用写入命令子程序
MOV A,TEMP1
MOV P0,A; 温度十位的代码写入

SETB RS; ;RS=1
CLR RW; ;RW=0 ;准备写入数据
CLR E; ;E=0 ;执行显示命令
ACALL DELAY ;判断液晶模块是否忙?
SETB E; ;E=1 ;显示完成,程序停车

MOV P0,#0C2H; ;写入显示起始地址
ACALL ENABLE ;调用写入命令子程序
MOV A,TEMP2
MOV P0,A; 温度个位代码写入

SETB RS; ;RS=1
CLR RW; ;RW=0 ;准备写入数据
CLR E; ;E=0 ;执行显示命令
ACALL DELAY ;判断液晶模块是否忙?
SETB E; ;E=1 ;显示完成,程序停车
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MOV P0,#0C3H; ;写入显示起始地址
ACALL ENABLE ;调用写入命令子程序
;MOV A,TEMP2
MOV P0,#00101110B; 小数点代码写入

SETB RS; ;RS=1
CLR RW; ;RW=0 ;准备写入数据
CLR E; ;E=0 ;执行显示命令
ACALL DELAY ;判断液晶模块是否忙?
SETB E; ;E=1 ;显示完成,程序停车
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MOV P0,#0C4H; ;写入显示起始地址
ACALL ENABLE ;调用写入命令子程序
MOV A,TEMP3
MOV P0,A; 十分位代码写入

SETB RS; ;RS=1
CLR RW; ;RW=0 ;准备写入数据
CLR E; ;E=0 ;执行显示命令
ACALL DELAY ;判断液晶模块是否忙?
SETB E; ;E=1 ;显示完成,程序停车

MOV P0,#0C6H; ;写入显示起始地址
ACALL ENABLE ;调用写入命令子程序
MOV A,50H
MOV P0,A; 十分位代码写入

SETB RS; ;RS=1
CLR RW; ;RW=0 ;准备写入数据
CLR E; ;E=0 ;执行显示命令
ACALL DELAY ;判断液晶模块是否忙?
SETB E; ;E=1 ;显示完成,程序停车

MOV P0,#0C7H; ;写入显示起始地址
ACALL ENABLE ;调用写入命令子程序
MOV A,51H
MOV P0,A; 十分位代码写入

SETB RS; ;RS=1
CLR RW; ;RW=0 ;准备写入数据
CLR E; ;E=0 ;执行显示命令
ACALL DELAY ;判断液晶模块是否忙?
SETB E; ;E=1 ;显示完成,程序停车

MOV P0,#0C8H; ;写入显示起始地址
ACALL ENABLE ;调用写入命令子程序
MOV A,#3AH
MOV P0,A; 十分位代码写入

SETB RS; ;RS=1
CLR RW; ;RW=0 ;准备写入数据
CLR E; ;E=0 ;执行显示命令
ACALL DELAY ;判断液晶模块是否忙?
SETB E; ;E=1 ;显示完成,程序停车

MOV P0,#0C9H; ;写入显示起始地址
ACALL ENABLE ;调用写入命令子程序
MOV A,52H
MOV P0,A; 十分位代码写入

SETB RS; ;RS=1
CLR RW; ;RW=0 ;准备写入数据
CLR E; ;E=0 ;执行显示命令
ACALL DELAY ;判断液晶模块是否忙?
SETB E; ;E=1 ;显示完成,程序停车

MOV P0,#0CAH; ;写入显示起始地址
ACALL ENABLE ;调用写入命令子程序
MOV A,53H
MOV P0,A; 十分位代码写入

SETB RS; ;RS=1
CLR RW; ;RW=0 ;准备写入数据
CLR E; ;E=0 ;执行显示命令
ACALL DELAY ;判断液晶模块是否忙?
SETB E; ;E=1 ;显示完成,程序停车
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ACALL DLY1S;延时防止显示闪烁
AJMP MAIN ;大循环,返回主主程序头。

/* 主程序结束*/

/*定时中断子程序开始*/
TIM0: PUSH ACC

PUSH B
PUSH PSW

MOV TH0,#HIGH(65536-10000) ;重置定时初值
MOV TL0,#LOW(65536-10000)
DJNZ R1,LOOP2
MOV R1,#100
INC 57H
MOV A,57H
CJNE A,#59,LOOP2 ;判断定时1s时间到,不到跳出中断,到53H分钟加1后跳出中断。
MOV 57H,#0
INC 53H
;;;;;;;;;;;;;;;;;;;;;;;时间变化程序
MOV A,53H
CJNE A,#3AH,LOOP2 ;分钟后位是否到10判断
MOV 53H,#30H ;到10复位置0
INC 52H ;分钟前位加1
MOV A,52H
CJNE A,#36H,LOOP2 ;分钟前位是否到6判断
MOV 52H,#30H ;到6复位置1
INC 51H ;时后位加1
MOV A,51H
CJNE A,#34H,LOOP3 ;时后位到4判断
MOV A,50H ;到4则判断时前位到2
CJNE A,#32H,LOOP2 ;时前位到2判断
MOV 50H,#30H ;如果条件满足,时两位同时置1
MOV 51H,#30H
INC 38H
JMP LOOP2
LOOP3: CJNE A,#3AH,LOOP2 ;时后位是否到9
MOV 51H,#30H ;到则置0
INC 50H ;时前位加1
LOOP2:
/* MOV A,50H
ANL A,#00111111B;
ORL A,#00110000B
MOV 50H,A

MOV A,51H
ANL A,#00111111B;
ORL A,#00110000B
MOV 51H,A

MOV A,52H
ANL A,#00111111B;
ORL A,#00110000B
MOV 52H,A

MOV A,53H
ANL A,#00111111B;
ORL A,#00110000B
MOV 53H,A */

POP PSW
POP B
POP ACC
RETI
/*定时中断子程序结束 */

/*LCD初始化调用的子程序开始 */
ENABLE:
CLR RS; ;写入控制命令的子程序
CLR RW;
CLR E
ACALL DELAY
SETB E
RET

DELAY:
MOV P0,#0FFH; ;判断液晶显示器是否忙的子程序
CLR RS
SETB RW
CLR E
NOP
SETB E
JB P0.7,DELAY; ;如果P1.7为高电平表示忙就循环等待
RET
/*结束 */

/*18B20 初始化调用的子程序,复位操作*/
RESET:
L0: CLR P1.0
MOV R2, #240 ;
L1: NOP
DJNZ R2,L1
SETB P1.0 ;主机发置位脉冲持续600us
MOV R2,#30 ; ;
L4: DJNZ R2,L4 ;等待60us
CLR C
ORL C, P1.0 ;数据线应变低
JC L0 ;没准备好,重来
MOV R6,#48 ;
L5: ORL C, P1.0
JC L3 ;数据线变高初始化成功
DJNZ R6,L5 ;数据线低电平可持续240us
SJMP L0 ;初始化失败,重来
L3: MOV R2, #250;
L2: DJNZ R2,L2 ;应答过程最少480us
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;把从P1.0口数据读入寄存器
READ: MOV R6,#8
RE1: CLR P1.0
MOV R4, #4
NOP ;低电平持续4us
NOP
NOP
NOP ;
SETB P1.0 ;P1.0改为输入
RE2: DJNZ R4,RE2 ;等待12us
MOV C, P1.0
RRC A ;按位读入
MOV R5, #15
RE3: DJNZ R5, RE3 ;保证读过程持续60us
DJNZ R6, RE1
MOV TEMP, A
SETB P1.0
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;把寄存器数据通过P1.0口送给DS18B20
WRITE: MOV R3, #8
WR1: SETB P1.0
MOV R4, #5
RRC A
CLR P1.0
WR2: DJNZ R4,WR2 ;数据线变低16us
MOV P1.0, C ;命令字按位送
MOV R4, #15
WR3: DJNZ R4,WR3 ;保证整个写过程持续60us
DJNZ R3,WR1
SETB P1.0
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;延时
DLY1S: MOV R7,#255
MOV R6,#0
DLYB: NOP
DJNZ R7,DLYB
DJNZ R6,DLYB
RET
DELAY10: MOV R4,#20 ; 12M晶体,延时10毫秒
D2:MOV R5,#248 ;
DJNZ R5,$ ;
DJNZ R4,D2 ;
RET

END ;;;;;;;;;;;;;;;;;结束
[ 此贴被ylsky在2009-08-25 13:37重新编辑 ]

5_40827_84754e7115f5cf1.jpg 5_40827_4ac617e20a229a4.jpg
*滑块验证:
您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

QQ|手机版|MCU资讯论坛 ( 京ICP备18035221号-2 )|网站地图

GMT+8, 2024-11-24 09:11 , Processed in 0.059834 second(s), 14 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表