用AT89S51(单片机)设计一个电子钟

以AT89S51为核心组成一个电子钟。电路主要由微处理器(AT89S51)、电源电路、键盘电路和显示电路组成。系统运行时,由8个LED数码管分别显示时、分、秒。在任何时候都可以通过键盘来调整时间。系统具有定时功能,当时间走到预定的时间时,系统将启动外设(如闹钟电路等)工作。使得整个系统具有某些智能功能,可以控制某些家电的启动和停止,达到自动控制的目的,具有一定的实用性。
我的邮箱是 [email protected] 好急用的!!! 跪求程序!!!

  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  ;20h.1半点标示位
  ;20H.2闹钟设置中........标示,为了显示区别用
  ;20H.3闹钟设置时间CHECK到,使能标志位
  ;20H.5开/关闹钟设置中........标示;
  ;20H.6闹钟1开关标志位
  ;20H.7闹钟2开关标志位
  ;psw.5用来做显示开关标志位
  ;21,22,23,24这里设置第一个闹钟的时间
  ;25,26,27,28这里设置第二个闹钟的时间
  ;29H
  ;P0口输出数码管段码,
  ;P2口 输出位选信号
  ;
  ;70H存放P1.0--3按钮值,
  ;71H--78H存放当前系统定时时间;
  ;78H 77H 76H 75H 74H 73H 72H 71H
  ; 星期* 小时 分钟 秒钟
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  ts equ 24h ;这里设置`24小时周期制
  trr equ #0bbh ;这个是温度,晶振等的时间补偿值,
  org 0000h ;定时太慢此值调大,定时太快调小;
  jmp main
  ;org 0bh ;定时器0中断入口矢量
  ;jmp bz
  org 1bh ;定时器1中断入口矢量
  jmp t1int
  org 0100h ;主程序
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  ;主程序
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  main:clr p3.0; ;关继电器
  mov sp,#30h
  mov r3,#20
  mov tmod,#10h
  ;mov tl0,#06h ;定时器1,方式1,定时 50 MS;
  ;mov th0,#06h
  mov tl1,#0b0h
  mov th1,#3ch
  mov ie,#88h ;开定时器1中断
  ;mov 65h,#5
  ; mov 66h,#100
  ;mov 64h,#4
  ;clr psw.5
  clr p3.0
  setb pt1 ;设置T1为高优先级中断
  ;setb tr1
  clr tr1 ;开启T1中断
  acall send ;71h--78h 清零;
  acall send1 ;20h--29h 清零;
  dd: acall daa ;进行十进制调整71H-79H
  ;acall compare ;第一闹钟
  ;acall compare1 ;第二闹钟 设置值
  ;acall sound
  acall disp ;数码管显示,78H--71H分别对应着8个数码管显示
  acall key_scanf ;按钮控制
  acall time_adj ;时间调整
  acall lasttime ;调用上一次的设置值为当前定时值
  ;acall alarm1_set ;设置定时开/关闹钟
  ajmp dd

  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  ;调用上次值为设置时间
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  lasttime:push acc
  mov a,70h
  jnb acc.2,return1
  clr p3.0; 紧急暂停按钮,按下后暂停,并把上次设定值恢复.
  clr tr1
  mov 73h,21h
  mov 74h,22h
  wait7:acall disp
  acall key_scanf
  mov a,70h
  jnb acc.0,wait7
  mov 71h,#0
  mov 72h,#0
  mov 79h,#0
  mov tl1,trr
  mov th1,#3ch
  mov r3,#20
  setb tr1
  setb p3.0
  return1:pop acc
  ret

  daa: push acc ;对当前系统时间进行十进制调整
  mov 71h,79h
  mov r1,#71h
  cjne @r1,#10,s2
  mov 71h,#0h
  mov 79h,#0
  inc 72h
  mov r1,#72h
  cjne @r1,#6,s2
  mov 72h,#0h
  dec 73h
  mov r1,#73h
  cjne @r1,#255,s2
  dec 74h
  mov 73h,#9
  s1: pop acc
  ret
  s2: mov r1,#73h
  cjne @r1,#0,s1
  mov r1,#74h
  cjne @r1,#0,s1
  clr p3.0
  clr tr1
  sjmp s1

  h_half: ;半点CHECK
  mov r1,#73h
  mov a,74h
  swap a
  xchd a,@r1
  cjne a,#29h,o25 ;CHECK 当前时间是否为29分钟
  xchd a,@r1
  mov r1,#71h
  mov a,72h
  swap a
  xchd a,@r1
  cjne a,#59h,o25 ;CHECK 当前时间为59秒?
  setb tr0 ;启动T0
  setb 20h.1 ;enable 半点flag bit
  o25: xchd a,@r1
  ret
  compare: ;闹钟1设置时间与当前时间比较
  push acc
  jnb 20h.6,nequ ;闹钟1开/关标志位
  mov a,73h
  cjne a,21h,nequ ;分低位
  mov a,74h
  cjne a,22h,nequ ;分高位
  mov a,75h
  cjne a,23h,nequ ;小时低位
  mov a,76h
  cjne a,24h,nequ ;小时高位
  setb 20h.3 ;到闹钟设置时间,使能闹钟报警标志位
  nequ:pop acc
  ret

  compare1: ;闹钟2设置时间与当前时间比较
  push acc
  jnb 20h.7,nequ33 ;闹钟2开/关标志位
  mov a,73h
  cjne a,25h,nequ33
  mov a,74h
  cjne a,26h,nequ33
  mov a,75h
  cjne a,27h,nequ33
  mov a,76h
  cjne a,28h,nequ33
  setb 20h.3 ;到闹钟设置时间,使能闹钟报警标志位
  nequ33:
  pop acc
  ret

  sound:
  acall h_half ;check 是否半点?
  jb 20h.1,s23 ;半点则返回
  jb 20h.0,s23
  mov r1,#73h
  mov a,74h
  swap a
  xchd a,@r1
  cjne a,#59h,s25
  xchd a,@r1
  mov r1,#71h
  mov a,72h
  swap a
  xchd a,@r1
  s20: cjne a,#56h,s21
  ajmp s26
  s21: cjne a,#58h,s22
  ajmp s26
  s22: cjne a,#59h,s25
  setb tr0
  ajmp s26
  s25: xchd a,@r1
  s23: ret
  s26: jb 20h.0,s25
  setb tr0
  xchd a,@r1
  ret
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  ;T0中断服务程序,报时铃音信号输出
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

  bz: djnz 64h,rrr
  jb 20h.3,alarmsign;闹钟到点报时有效
  jb 20h.1,next ;半点报时
  mov 64h,#4 ;0.5KHZ
  ajmp justh
  alarmsign:
  mov 64h,#1; 2KHZ信号
  justh:
  djnz 66h,ccc
  mov 66h,#100
  djnz 65h,ccc ;产生1000次中断后关中断
  mov 65h,#5 ;响0.5秒
  setb 20h.0
  clr tr0
  reti

  next:mov 64h,#2 ;1KHZ信号,半点报时音
  ccc: jb 20h.3,cc
  cpl p1.4 ;半点报时输出声音信号
  rrr: reti
  cc: cpl p1.4 ;闹钟报时输出声音信号
  reti

  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  ;T1中断服务程序,定时器主时钟;
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

  t1int:
  clr ea
  mov tl1,trr
  mov th1,#3ch
  djnz r3,sd ;20*50MS=1S
  mov r3,#20
  ;cpl p1.4
  inc 79h
  clr 20h.0
  clr 20h.1 ;半点报时标志清零
  jb 20h.3,sdd ;闹钟CHECK有效与否?
  clr tr0 ;关T0
  sd: setb ea
  reti
  sdd: setb tr0 ;开T0,即开闹铃声音
  setb ea
  reti
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  ;显示子函数
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  dispnum1:; 显示
  ajmp disp_num
  disp:
  push acc
  ;jb 20h.5,dispnum1;开/关闹钟设置中界面...........
  ;jb 20h.2,alarmcheck;闹钟设置时间中界面..........
  jb psw.5,closedisp
  mov r2,#01h;位选通信号输出到P2口
  mov r5,#2; 显示的位数循环控制
  mov r0,#73h;分别取出内存76H-71H
  cjne r3,#10,dot1;在小时和分之间闪烁DOT point
  dot1:jnc dsp1
  orl 73h,#10h
  ;dot1:cjne r3,#11,dsp1
  ;anl 73h,#0efh
  dsp1:mov a,r2
  ;cpl a
  mov p2,a
  mov a,@r0
  dsp2:mov dptr,#bcd
  movc a,@a+dptr
  mov p0,a
  acall delay
  mov a,r2
  rl a
  mov r2,a
  inc r0
  djnz r5,dsp1
  anl 73h,#0efh
  pop acc
  ret
  closedisp:; 关显示
  acall delay
  mov p0,#0ffh
  mov p2,#0
  pop acc
  ret

  ;;;;;;;;;;;;;;;;;闹钟的定时设置显示
  alarmcheck:
  mov r2,#01h
  mov r5,#2 ;两位显示22-21H对应定时设置值
  mov r0,#21h
  dsp21:
  mov a,r2
  ;cpl a
  mov p2,a
  mov a,@r0
  mov dptr,#bcd
  movc a,@a+dptr
  mov p0,a
  acall delay
  mov a,r2
  rl a
  mov r2,a
  inc r0
  djnz r5,dsp21
  pop acc
  ret
  bcd:; 共阳接法数码管段码表
  db 0c0h,0f9h,0a4h,0b0h
  db 99h,92h,82h,0f8h
  db 80h,90h,88h,83h
  db 0c6h,0a1h,86h,8eh; 不带小数点七段
  db 40h,79h,24h,30h,19h
  db 12h,02h,78h,00h,10h
  db 0ffh,0bfh,7fh,3fh; 带小数点七段
  delay:mov r6,#4h
  tm: mov r4,#0h
  ee: djnz r4,ee; 延时2048US=2MS
  djnz r6,tm
  ret

  send:mov r7,#9; 初始化设置
  mov r0,#71h
  mov a,#0h
  ss: mov @r0,a
  inc r0
  djnz r7,ss
  mov 78h,#1h
  mov 77h,#01ah
  ;mov 71h,#1
  ;mov 72h,#2
  ;mov 73h,#3
  ;mov 74h,#4
  ret
  send1:; 初始化
  mov r7,#10
  mov r0,#20h
  mov a,#0
  ss1: mov @r0,a
  inc r0
  djnz r7,ss1
  ret

  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  ;;;;;;;;;;;开/关闹钟界面显示
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  disp_num:
  mov p2,#0f7h
  mov a,29h ;当前要操作的闹钟号码
  mov dptr,#bcd
  movc a,@a+dptr
  mov p0,a
  acall delay
  pop acc
  ret
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  key_scanf:; 按钮处理
  push acc
  mov 70h,#0
  orl p1,#0fh
  mov a,p1
  cpl a
  anl a,#07h
  jz nokey1
  acall daa
  acall disp
  mov a,p1
  cpl a
  anl a,#07h
  jz nokey1
  mov 70h,a
  key_wait:; 等按钮放下
  acall daa
  acall disp
  mov a,p1
  cpl a
  anl a,#07h
  jnz key_wait
  mov a,70h
  jnb acc.1,nokey1
  cpl psw.5
  nokey1:; 无按钮
  pop acc
  ret

  a_on_off:
  jnb 29h.0,iii
  cpl 20h.6
  iii: jnb 29h.1,out_2
  cpl 20h.7
  out_2:
  ajmp alarmnum
  alarmnum:
  setb 20h.5
  acall daa
  acall disp
  acall key_scanf
  clr 20h.5
  mov a,70h
  jb acc.0,a_on_off
  jb acc.1,alar_adj_1
  jb acc.2,a_num_inc
  acall numb
  ajmp alarmnum
  alarm1_set:
  push acc
  mov a,70h
  jb acc.1,alarmnum
  alarm1_out:
  clr 20h.2
  pop acc
  ret
  a_num_inc:
  inc 29h
  mov a,29h
  anl a,#0fh
  cjne a,#3,alarmnum
  anl 29h,#0
  ajmp alarmnum
  alar_adj_1:
  setb 20h.2
  acall daa
  orl 21h,#10h
  acall disp
  anl 21h,#0fh
  acall key_scanf
  mov a,70h
  jb acc.1,hadj_1
  jb acc.2,minc_1
  ajmp alar_adj_1
  madj_2:
  acall daa
  orl 25h,#10h
  acall disp
  anl 25h,#0fh
  acall key_scanf
  mov a,70h
  jb acc.1,hadj_2
  jb acc.2,minc_2
  ajmp madj_2
  hadj_1:
  acall daa
  orl 23h,#10h
  acall disp
  anl 23h,#0fh
  acall key_scanf
  mov a,70h
  jb acc.1,madj_2
  jb acc.2,hinc_1
  ajmp hadj_1
  hadj_2:acall daa
  orl 27h,#10h
  acall disp
  anl 27h,#0fh
  acall key_scanf
  mov a,70h
  jb acc.1,alarm1_out
  jb acc.2,hinc_2
  ajmp hadj_2
  minc_1:
  inc 21h
  mov r1,#21h
  cjne @r1,#10,alar_adj_1
  mov 21h,#0
  inc 22h
  mov r1,#22h
  cjne @r1,#6,alar_adj_1
  mov 22h,#0h
  ajmp alar_adj_1
  minc_2:
  inc 25h
  mov r1,#25h
  cjne @r1,#10,madj_2
  mov 25h,#0
  inc 26h
  mov r1,#26h
  cjne @r1,#6,madj_2
  mov 26h,#0
  ajmp madj_2
  hinc_1:
  inc 23h
  mov r1,#23h
  cjne @r1,#10,ss14
  mov 23h,#0
  inc 24h
  ss14:
  mov a,24h
  swap a
  xchd a,@r1
  cjne a,#ts,ss15
  mov 23h,#0
  mov 24h,#0
  ajmp hadj_1
  ss15:xchd a,@r1
  ajmp hadj_1
  hinc_2:
  inc 27h
  mov r1,#27h
  cjne @r1,#10,sss14
  mov 27h,#0
  inc 28h
  sss14:
  mov a,28h
  swap a
  xchd a, @r1
  cjne a,#ts,sss15
  mov 27h,#0
  mov 28h,#0
  ajmp hadj_2
  sss15:
  xchd a,@r1
  ajmp hadj_2

  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  ;时间调整程序
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

  time_adj:;
  clr psw.5
  push acc
  mov a,70h
  jb acc.0,l1;P1.0调时功能键,每按一次切换一位
  ajmp nokeyout
  adj_out:
  mov 21h,73h
  mov 22h,74h
  setb p3.0 ;闭合继电器
  setb tr1
  nokeyout:
  pop acc
  ret
  QQ: anl 73h,#0fh
  anl 74h,#0fh
  ;anl 78h,#0fh
  ret
  l1: clr tr1;acall dab; 分钟调整
  orl 73h,#10h;点亮分右下角的小数点,当前调整位置
  acall disp
  acall QQ
  acall key_scanf
  clr psw.5
  mov a,70h
  jb acc.0,h_adj;切换到小时调整
  jb acc.1,m_inc;P1.2加1按钮
  ajmp l1
  h_adj:; 小时调整
  ;acall dab
  orl 74h,#10h
  acall disp
  acall QQ
  acall key_scanf
  clr psw.5
  mov a,70h
  jb acc.0,out_adj;切换到星期调整
  jb acc.1,h_inc;小时加1
  ajmp h_adj
  w_adj:
  acall daa
  orl 78h,#10h
  acall disp
  acall QQ
  acall key_scanf
  clr psw.5
  mov a,70h
  jb acc.0,out_adj
  jb acc.2,w_inc
  ajmp w_adj
  out_adj:
  ajmp adj_out
  m_inc:;;;;;;;;;;;;;;; 调整分时,对定时复位,初始化
  clr tr1
  mov 71h,#0
  mov 72h,#0
  mov 79h,#0
  mov tl1,trr
  mov th1,#3ch
  mov r3,#20
  inc 73h
  mov r1,#73h
  cjne @r1,#10,s12
  mov 73h,#0
  inc 74h
  mov r1,#74h
  cjne @r1,#10,s12
  mov 74h,#0
  s12: ajmp l1
  ;;;;;;;;;;;;;;;;;;;;;;调整小时位
  h_inc:
  inc 74h
  mov r1,#74h
  cjne @r1,#10,s14
  mov 74h,#0
  ;inc 76h
  s14: ajmp h_adj
  ;mov a,76h
  ;swap a
  ;xchd a,@r1
  ;cjne a,#ts,s15;;;12进制,24进制设置值决定
  ;mov 75h,#0
  ;mov 76h,#0
  ;ajmp h_adj
  ;s15: ;xchd a,@r1
  ;ajmp h_adj
  ;;;;;;;;;;;;;;;;;;;;;;;调整星期位
  w_inc:
  inc 78h
  mov r1,#78h
  cjne @r1,#8,s16
  mov 78h,#1h
  s16: ajmp w_adj

  ;;;;;;;;;;;;;;;;;;;;;;;当前闹钟开/关情况报告位
  numb:clr 29h.4
  jnb 29h.0,iii1
  jnb 20h.6,iii1
  setb 29h.4
  iii1:jnb 29h.1,out_21
  jnb 20h.7,out_21
  setb 29h.4
  out_21:
  jnb 20h.6,out_12
  jnb 20h.7,out_13
  mov 77h,#1dh
  ajmp out_22
  out_12:
  jnb 20h.7,out_14
  mov 77h,#1bh
  ajmp out_22
  out_13:
  mov 77h,#1ch
  ajmp out_22
  out_14:
  mov 77h,#1ah
  out_22:
  ret
  end
温馨提示:答案为网友推荐,仅供参考
第1个回答  2010-12-30
/****************************文件包含************************************/
#include < reg52.h >
#include <absacc.h>
#include <intrins.h>

/*****************************变量预定义*********************************/
#define uchar unsigned char
#define uint unsigned int
uchar data Clock_Timed[13] =
// sec asec minu aminu hour ahour week day mon year cen DS_B DS_c
{ 0x00, 0x00, 0x58, 0x59, 0x16, 0x16, 0x02, 0x26, 0x10, 0x10, 0x20 ,0x2a, 0x0a};
uchar code tab[11]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xff,0xf6,0xee};//0-9,A,??
uchar Temperature=0x25;
sbit DQ=P3^4; //温度输入口
sbit DIN=P2^2; //LED小数点控制
uint h;
uchar code ditab[16]={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09};
uchar data temp_data[2]={0x00,0x00}; // 读出温度暂放
uchar data display_temp[5]={0x00,0x00,0x00,0x00,0x00};//显示单元数据,共4个数据,一个运算暂存用
//--------------------------------------
//单片机晶振采用11.0592MHz
// 频率-半周期数据表 高八位 本软件共保存了四个八度的28个频率数据
code uchar FREQH[] = {
0xF2, 0xF3, 0xF5, 0xF5, 0xF6, 0xF7, 0xF8, //低音1234567
0xF9, 0xF9, 0xFA, 0xFA, 0xFB, 0xFB, 0xFC, 0xFC,//1,2,3,4,5,6,7,i
0xFC, 0xFD, 0xFD, 0xFD, 0xFD, 0xFE, //高音 234567
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF}; //超高音 1234567

// 频率-半周期数据表 低八位
code uchar FREQL[] = {
0x42, 0xC1, 0x17, 0xB6, 0xD0, 0xD1, 0xB6, //低音1234567
0x21, 0xE1, 0x8C, 0xD8, 0x68, 0xE9, 0x5B, 0x8F, //1,2,3,4,5,6,7,i
0xEE, 0x44, 0x6B, 0xB4, 0xF4, 0x2D, //高音 234567
0x47, 0x77, 0xA2, 0xB6, 0xDA, 0xFA, 0x16}; //超高音 1234567
//--------------------------------------
//世上只有妈妈好数据表 要想演奏不同的乐曲, 只需要修改这个数据表
code uchar sszymmh[] = {
6, 2, 3, 5, 2, 1, 3, 2, 2, 5, 2, 2, 1, 3, 2, 6, 2, 1, 5, 2, 1,
//一个音符有三个数字。前为第几个音、中为第几个八度、后为时长(以半拍为单位)。
//6, 2, 3代表:6, 中音, 3个半拍;
//5, 2, 1代表:5, 中音, 1个半拍;
//3, 2, 2代表:3, 中音, 2个半拍;
//5, 2, 2代表:5, 中音, 2个半拍;
//1, 3, 2代表:1, 高音, 2个半拍;
//
6, 2, 4, 3, 2, 2, 5, 2, 1, 6, 2, 1, 5, 2, 2, 3, 2, 2, 1, 2, 1,
6, 1, 1, 5, 2, 1, 3, 2, 1, 2, 2, 4, 2, 2, 3, 3, 2, 1, 5, 2, 2,
5, 2, 1, 6, 2, 1, 3, 2, 2, 2, 2, 2, 1, 2, 4, 5, 2, 3, 3, 2, 1,
2, 2, 1, 1, 2, 1, 6, 1, 1, 1, 2, 1, 5, 1, 6, 0, 0, 0};
//结束标记
//--------------------------------------

uint time,tt;
uchar k, i;
bit Alarm_Sw=0;
sbit WDIO=P3^2;
bit Bjw=0;
sbit L1=P2^1;
sbit L2=P2^2;
/************************** 有关声音报警预定义 **************************/
sbit Speak = P1^7; //蜂鸣器输出口
/**************************有关DS12887预定义*****************************/
#define DS_Seconds XBYTE[0x7f00]
#define DS_Minutes XBYTE[0x7f02]
#define DS_Hours XBYTE[0x7f04]
#define DS_Weeks XBYTE[0x7f06]
#define DS_Days XBYTE[0x7f07]
#define DS_Month XBYTE[0x7f08]
#define DS_Year XBYTE[0x7f09]
#define DS_Century XBYTE[0x7f32]
#define DS_A XBYTE[0x7f0a]
#define DS_B XBYTE[0x7f0b]
#define DS_C XBYTE[0x7f0c]
#define DS_D XBYTE[0x7f0d]
sbit DS12C887_CS=P2^7;//片选低电平有效13
sbit DS12C887_DS=P3^7;//intel模式读允许17
sbit DS12C887_WR=P3^6;//intel模式写允许15
sbit DS12C887_AS=P4^5;//上升沿锁地址、下降沿清地址14

/**************************键值预定义***********************************/
#define Up 0x28
#define Down 0x18
#define Func 0x30
//-----------------------------------
/***********11微秒延时函数**********/

void delay(uint t)
{
for(;t>0;t--);
}
//***********18B20复位函数**********
ow_reset(void)
{
char presence=1;
while(presence)
{
while(presence)
{
DQ=1;_nop_();_nop_();
DQ=0; //
delay(50); // 550us
DQ=1; //
delay(6); // 66us
presence=DQ; // presence=0继续下一步
}
delay(45); //延时500us
presence = ~DQ;
}
DQ=1;
}
//
//
//**********18B20写命令函数*********
//向 1-WIRE 总线上写一个字节
void write_byte(uchar val)
{
uchar i;
for (i=8; i>0; i--) //
{
DQ=1;_nop_();_nop_();
DQ = 0;_nop_();_nop_();_nop_();_nop_();_nop_();//5us
DQ = val&0x01; //最低位移出
delay(6); //66us
val=val/2; //右移一位
}
DQ = 1;
delay(1);
}
//
//*********18B20读1个字节函数********
//从总线上读取一个字节
uchar read_byte(void)
{
uchar i;
uchar value = 0;
for (i=8;i>0;i--)
{
DQ=1;_nop_();_nop_();
value>>=1;
DQ = 0; //
_nop_();_nop_();_nop_();_nop_(); //4us
DQ = 1;_nop_();_nop_();_nop_();_nop_(); //4us
if(DQ)value|=0x80;
delay(6); //66us
}
DQ=1;
return(value);
}
//

//***********读出温度函数**********
read_temp()
{
ow_reset(); //总线复位
write_byte(0xCC); // 发Skip ROM命令
write_byte(0xBE); // 发读命令
temp_data[0]=read_byte(); //温度低8位
temp_data[1]=read_byte(); //温度高8位
ow_reset();
write_byte(0xCC); // Skip ROM
write_byte(0x44); // 发转换命令
}
//
//***********温度数据处理函数**********
work_temp()
{
uchar n=0; //
if(temp_data[1]>127)
{temp_data[1]=(256-temp_data[1]);temp_data[0]=(256-temp_data[0]);n=1;}//负温度求补码
display_temp[4]=temp_data[0]&0x0f;display_temp[0]=ditab[display_temp[4]];
display_temp[4]=((temp_data[0]&0xf0)>>4)|((temp_data[1]&0x0f)<<4);//
display_temp[3]=display_temp[4]/100;
display_temp[1]=display_temp[4]%100;
display_temp[2]=display_temp[1]/10;
display_temp[1]=display_temp[1]%10;
if(!display_temp[3]){display_temp[3]=0x0A;if(!display_temp[2]){display_temp[2]=0x0A;}}//最高位为0时都不显示
if(n){display_temp[3]=0x0B;}//负温度时最高位显示"-"

Temperature=(display_temp[2]<<4)|(display_temp[1]&0x0f);
}

/*void Delay5us(int j)//delay TIMER1*1 us for 12MHz
{
uchar data i;
for(i=0;i<=j;i++)
{
_nop_();
_nop_();
}
}*/
void Delayms( uint m ) // 11.0592MHz 时为1mS
{
uint j;
uint i;
for(i=0; i<m; i++)
for(j=0; j<210; j++)
{
_nop_();
}
}
//读某地址的数据
uchar DS12C887_Read(uchar _address)
{
uint tmpData;
DS12C887_CS=0;
DS12C887_DS=1;
DS12C887_WR=1;
P0=_address;
DS12C887_AS=1;
DS12C887_AS=0;
DS12C887_DS=0;
P0=0xff;//单片机从I/O口读取数据之前先给I/O口赋个高。
tmpData=P0;
DS12C887_DS=1;
DS12C887_AS=1;
DS12C887_CS=1;
return(tmpData);
}

void Display_Set_Clock(uchar temp)
{
static uchar ii=0;
static bit flag=1;
if ( Clock_Timed[11]==0x2a) L1=1;
else L1=0;
if( ii<30)ii++;
else
{
flag=~flag;
ii=0;
}
switch (temp)
{
case 0: //闹钟开关
{
if (flag)P1=0x04;
else P1=0x7f;
SBUF=tab[Clock_Timed[3]&0x0f];
while(TI==0);
TI=0;
Delayms(1);
if (flag)P1=0x05;
else P1=0x7f;
SBUF=tab[Clock_Timed[3]>>4];
while(TI==0);
TI=0;
Delayms(1);
if (flag)P1=0x06;
else P1=0x7f;
SBUF=tab[Clock_Timed[5]&0x0f];
while(TI==0);
TI=0;
Delayms(1);
if (flag)P1=0x07;
else P1=0x7f;
SBUF=tab[Clock_Timed[5]>>4];
while(TI==0);
TI=0;
Delayms(1);
if (flag)P1=0x00;
else P1=0x7f;
SBUF=tab[Clock_Timed[2]&0x0f];
while(TI==0);
TI=0;
Delayms(1);
if (flag)P1=0x01;
else P1=0x7f;
SBUF=tab[Clock_Timed[2]>>4];
while(TI==0);
TI=0;
Delayms(1);
if (flag)P1=0x02;
else P1=0x7f;
SBUF=tab[Clock_Timed[4]&0x0f];
while(TI==0);
TI=0;
Delayms(1);
if (flag)P1=0x03;
else P1=0x7f;
SBUF=tab[Clock_Timed[4]>>4];
while(TI==0);
TI=0;
Delayms(1);
}
break;
case 1: //闹分
{
P1=0x00;
SBUF=tab[Clock_Timed[2]&0x0f];
while(TI==0);
TI=0;
Delayms(1);
P1=0x01;
SBUF=tab[Clock_Timed[2]>>4];
while(TI==0);
TI=0;
Delayms(1);
P1=0x02;
SBUF=tab[Clock_Timed[4]&0x0f];
while(TI==0);
TI=0;
Delayms(1);
P1=0x03;
SBUF=tab[Clock_Timed[4]>>4];
while(TI==0);
TI=0;
Delayms(1);
if (flag)P1=0x04;
else P1=0x7f;
SBUF=tab[Clock_Timed[3]&0x0f];
while(TI==0);
TI=0;
Delayms(1);
if (flag)P1=0x05;
else P1=0x7f;
SBUF=tab[Clock_Timed[3]>>4];
while(TI==0);
TI=0;
Delayms(1);
P1=0x06;
SBUF=tab[Clock_Timed[5]&0x0f];
while(TI==0);
TI=0;
Delayms(1);
P1=0x07;
SBUF=tab[Clock_Timed[5]>>4];
while(TI==0);
TI=0;
Delayms(1);
}
break;

case 2: //闹时
{
P1=0x00;
SBUF=tab[Clock_Timed[2]&0x0f];
while(TI==0);
TI=0;
Delayms(1);
P1=0x01;
SBUF=tab[Clock_Timed[2]>>4];
while(TI==0);
TI=0;
Delayms(1);
P1=0x02;
SBUF=tab[Clock_Timed[4]&0x0f];
while(TI==0);
TI=0;
Delayms(1);
P1=0x03;
SBUF=tab[Clock_Timed[4]>>4];
while(TI==0);
TI=0;
Delayms(1);
P1=0x04;
SBUF=tab[Clock_Timed[3]&0x0f];
while(TI==0);
TI=0;
Delayms(1);
P1=0x05;
SBUF=tab[Clock_Timed[3]>>4];
while(TI==0);
TI=0;
Delayms(1);
if (flag)P1=0x06;
else P1=0x7f;
SBUF=tab[Clock_Timed[5]&0x0f];
while(TI==0);
TI=0;
Delayms(1);
if (flag)P1=0x07;
else P1=0x7f;
SBUF=tab[Clock_Timed[5]>>4];
while(TI==0);
TI=0;
Delayms(1);
}
break;

case 3: //实分
{

if (flag)P1=0x00;
else P1=0x7f;
SBUF=tab[Clock_Timed[2]&0x0f];
while(TI==0);
TI=0;
Delayms(1);
if (flag)P1=0x01;
else P1=0x7f;
SBUF=tab[Clock_Timed[2]>>4];
while(TI==0);
TI=0;
Delayms(1);
P1=0x02;
SBUF=tab[Clock_Timed[4]&0x0f];
while(TI==0);
TI=0;
Delayms(1);
P1=0x03;
SBUF=tab[Clock_Timed[4]>>4];
while(TI==0);
TI=0;
Delayms(1);
P1=0x04;
SBUF=tab[Clock_Timed[3]&0x0f];
while(TI==0);
TI=0;
Delayms(1);
P1=0x05;
SBUF=tab[Clock_Timed[3]>>4];
while(TI==0);
TI=0;
Delayms(1);
P1=0x06;
SBUF=tab[Clock_Timed[5]&0x0f];
while(TI==0);
TI=0;
Delayms(1);
P1=0x07;
SBUF=tab[Clock_Timed[5]>>4];
while(TI==0);
TI=0;
Delayms(1);
}
break;
case 4: //实时
{

P1=0x00;
SBUF=tab[Clock_Timed[2]&0x0f];
while(TI==0);
TI=0;
Delayms(1);
P1=0x01;
SBUF=tab[Clock_Timed[2]>>4];
while(TI==0);
TI=0;
Delayms(1);
if (flag)P1=0x02;
else P1=0x7f;
SBUF=tab[Clock_Timed[4]&0x0f];
while(TI==0);
TI=0;
Delayms(1);
if (flag)P1=0x03;
else P1=0x7f;
SBUF=tab[Clock_Timed[4]>>4];
while(TI==0);
TI=0;
Delayms(1);
P1=0x04;
SBUF=tab[Clock_Timed[3]&0x0f];
while(TI==0);
TI=0;
Delayms(1);
P1=0x05;
SBUF=tab[Clock_Timed[3]>>4];
while(TI==0);
TI=0;
Delayms(1);
P1=0x06;
SBUF=tab[Clock_Timed[5]&0x0f];
while(TI==0);
TI=0;
Delayms(1);
P1=0x07;
SBUF=tab[Clock_Timed[5]>>4];
while(TI==0);
TI=0;
Delayms(1);
}
break;

}
}
QQ123751574
第2个回答  2010-12-29
记得我们做设计的时候是有现成的,呵呵,到单片机网站上下载吧。
相似回答