bokee.net

电子/电气工程师博客

正文 更多文章

实时时钟ds3231 驱动程序

          实时时钟ds3231 驱动程序

           徐丽红  王佰营

      wbymcs51.blog.bokee.net

;宏定义区;
 N_NOP  MACRO
   nop
   nop
   nop
   ENDM

 TRAP  MACRO
   nop
   nop
   nop
   sjmp  $
   ENDM 
 
 TRAP_RET MACRO
   nop
   nop
   nop
   ret
   nop
   nop
   nop
   sjmp  $
   ENDM
  
;===================================================================
;  function: start_sd ;时钟启动 
;  input:  ---------
;  output:  ---------
;  usage:  ---------  
;====================================================================
start_sd: ;时钟启动
  ;clr  bsda
  ;N_NOP
  setb  sda
  N_NOP
  setb  scl
  N_NOP
  jb  sda,  ssd_on
  setb  bsda

ssd_on:  clr  sda
  ;N_NOP
  ;clr  scl
  N_NOP
  ret

;====================================================================
;  function: stop_sd   ;时钟停止  
;  input:  ---------
;  output:  ---------
;  usage:  ---------  
;====================================================================
stop_sd: ;时钟停止
  clr  sda
  N_NOP
  clr  sda
  N_NOP
  setb  scl
  N_NOP
  setb  scl
  N_NOP
  setb  sda
  N_NOP
  ret

;===================================================================
;  function: ack(应答) bsend------发送位
;  input:  ---------
;  output:  ---------
;  usage:  ---------  
;====================================================================
ack:  ;时钟应答
  clr  sda
  N_NOP
  setb  scl
  N_NOP
  clr  scl
  ret

;==================================================================== 
;  function: nack  ;发送非应答位
;  input:  ---------
;  output:  ---------
;  usage:  --------- 
;====================================================================
nack:  ;非应答
  setb  sda
  N_NOP
  setb  scl
  N_NOP
  clr  scl
  ret

;====================================================================
;  function: check_ack ;应答位检查
;  input:  --------- 
;  output:  --------- 
;  usage:  ---------  
;=====================================================================
check_ack: ;检查应答信号;
  clr  scl
  N_NOP
  setb  sda
  N_NOP
  setb  scl
  N_NOP
  mov  r6,  #255
cck_lp:  jnb  sda,  cck_goon
  djnz  r6,  cck_lp
cck_goon: clr  scl
  N_NOP
  ret

;=====================================================================
;  function: out_bit  ;发送一位数给实时时钟  
;  input:  c 
;  output:  ---------
;  usage:  c  
;=====================================================================
out_bit: ;发送一位数给实时时钟
  ;lcall  dog_int_feed
  clr  scl
  N_NOP
  mov  sda,  c
  N_NOP
  setb  scl
  N_NOP
  clr  scl
  N_NOP
  TRAP_RET

;====================================================================
;  function: in_bit  ;从实时时钟接收一位数 
;  input:  --------- 
;  output:  c
;  usage:  c  
;=====================================================================
in_bit:  ;从实时时钟接收一位数
  ;lcall  dog_int_feed
  setb  sda
  N_NOP
  setb  scl
  N_NOP
  mov  c,  sda
  clr  scl
  N_NOP
  clr  sda
  N_NOP
  TRAP_RET

;====================================================================
;  function: sendh_l (高到低);发送一个字节给实时时钟 
;  input:  a-----发送数据 
;  output:  ---------
;  usage:  a,c,r7
;    r7----发送位数(8位)
;====================================================================
send_H_L: ;发送一个字节给实时时钟(高到低) 
  mov  r7,  #08h

send_loop: mov  c,  acc.7
  lcall  out_bit
  rl  a
  djnz  r7,  send_loop
  nop
  nop
  ret

;======================================================================
;  function: receiveh_l(高到低) ;从总线接收一个字节 
;  input:  ---------
;  output:  a---接收数据
;  usage:  a,r3,  
;======================================================================
receive_H_L: ;从总线接收一个字节(高到低)
  mov  r3,  #08h
re_loop: lcall  in_bit
  rlc  a
  djnz  r3,  re_loop
  ret

;======================================================================
;  function: write_1_sd ;向I2C总线发送1个字节数据 
;  input:  r0-----欲发送缓冲区地址
;    r1-----器件地址
;  output:  ----------
;  usage:  a,r0,r1
;=======================================================================
write_1_sd: ;向I2C总线发送1个字节数据
  lcall  start_sd
  jb  bsda,  w1sd_end
  mov  a,  #0d0h;#64h ;写命令字
  lcall  send_H_L
  lcall  check_ack

  mov  a,  r1 ;写器件地址
  ;anl  a,  #0fh
  ;swap  a
  lcall  send_H_L
  lcall  check_ack

  mov  a,  @r0 ;写发送的数据
  lcall  send_H_L
  lcall  check_ack

  lcall  ack   ;应答
w1sd_end: lcall  stop_sd
  ret

;======================================================================
;  function: read_1_sd ;从I2C总线接收1个字节数据 
;  input:  ---------
;    r0----器件地址
;    r1----欲接收数据存放缓冲区地址
;  output:  year,month...(时间寄存器)
;  usage:  a,r1
;======================================================================
read_1_sd: ;从I2C总线接收1个字节数据
  lcall  start_sd
  jb  bsda,  r1sd_end

  mov  a,  #0d0h;#64h ;写命令字
  lcall  send_H_L
  lcall  check_ack

  mov  a,  r0 ;写器件地址
  ;anl  a,  #0fh
  ;swap  a
  lcall  send_H_L
  lcall  check_ack

  lcall  start_sd
  jb  bsda,  r1sd_end

  mov  a,  #0d1h;#65h
  lcall  send_H_L
  lcall  check_ack

  lcall  receive_H_L  ;读数据放于时间寄存器
  mov  @r1,  a

  lcall  nack
  lcall  stop_sd

  ret

r1sd_end: lcall  stop_sd
  TRAP_RET

;=======================================================================
;  fuction: read_sd   ;读实时时钟
;  input:  ------------
;  output:  year,month...(时间寄存器)
;  usage:  a,r0,r1
;========================================================================
read_sd: ;读实时时钟
  ;--------------------------------------------------------
  ;function: read_1_sd ;从I2C总线接收1个字节数据 
  ;input:  ---------
  ;  r0----器件地址
  ;  r1----欲接收数据存放缓冲区地址
  ;output: year,month...(时间寄存器)时间寄存器)
  ;usage:  a,r0,r1,r2---循环次数
  ;--------------------------------------------------------
  mov  r0,  #0 
  mov  r1,  #second 
  mov  r2,  #3 
rsd_lp:  lcall  read_1_sd
  inc  r1
  inc  r0
  djnz  r2,  rsd_lp
  ret

;=========================================================================
;  fuction: write_sd ;写实时时钟
;  input:  date_set
;  output:  ------------
;  usage:  a,r0,r1,r2
;=========================================================================
write_sd: ;写实时时钟
  ;--------------------------------------------------------
  ;function: write_1_sd ;向I2C总线发送1个字节数据 
  ;input:  r0-----欲发送缓冲区地址
  ;  r1-----器件地址
  ;output: ----------
  ;usage:  a,r0,r1,r2---循环次数
  ;--------------------------------------------------------
  mov  r0,  #date_set
  mov  r1,  #0
  mov  r2,  #3
  ;zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
  jb  brun,  ws_ret
  jb  bstop,  ws_ret
  jb  bset,  ws_ret
  jb  bset1,  ws_ret
  jnb  bset2,  ws_ret
  mov  a,  in_code
  cjne  a, #53, ws_ret
  ;zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
wsd_lp:  jnb  bsaveT,  ws_ret
  lcall  write_1_sd
  inc  r0
  inc  r1
  djnz  r2,  wsd_lp
ws_ret:  clr  bsaveT
  ret

;=========================================================================
;  fuction: time_int ;时钟初始化程序
;  input:  ------------
;  output:  ------------
;  usage:  a,r0
;=========================================================================
time_int: ;时钟初始化程序
  lcall  start_sd
  mov  a,  #0d0h;#64h
  lcall  send_H_L
  lcall  check_ack

  mov  a,  #0f0h
  lcall  send_H_L
  lcall  check_ack 

  mov  a,  #20h
  lcall  send_H_L
  lcall  check_ack

  lcall  stop_sd

  lcall  start_sd
  mov  a,  #0d0h;#64h
  lcall  send_H_L
  lcall  check_ack

  mov  a,  #70h
  lcall  send_H_L
  lcall  check_ack 

  mov  a,  #00h
  lcall  send_H_L
  lcall  check_ack

  lcall  stop_sd
  TRAP_RET

关键词:单片机 MCS51 实时时钟 ds3231 驱动程序

分享到:

上一篇: 实时时钟DS1302 驱动

下一篇:MAX7219汇编语言版驱动程序

评论 (1条) 发表评论

发表评论
验证码