bodu.com

电子/电气工程师博客

正文 更多文章

实时时钟SD2303 驱动程序

     实时时钟SD2303 驱动程序

           徐丽红  王佰营

       wbymcs51.blog.bokee.net


   该程序经过使用,免调试。

;===================================================================
;  function: start_sd ;时钟启动 
;  input:  ---------
;  output:  ---------
;  usage:  ---------  
;====================================================================
start_sd: ;时钟启动
  clr  bsda
  nop
  nop
  setb  sda
  nop
  nop
  setb  scl
  nop
  nop
  jb  sda,  ssd_on
  setb  bsda

ssd_on:  clr  sda
  nop
  nop
  clr  scl
  nop
  nop
  ret

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

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

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

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

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

;====================================================================
;  function: in_bit  ;从实时时钟接收一位数 
;  input:  --------- 
;  output:  c
;  usage:  c  
;=====================================================================
in_bit:  ;从实时时钟接收一位数
  ;lcall  dog_int_feed
  setb  sda
  nop
  nop
  setb  scl
  nop
  nop
  mov  c,  sda
  clr  scl
  nop
  nop
  clr  sda
  nop
  nop
  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

  jnb  bdec_data, rh_goon  ;是否写数据

  push  acc
  mov  a,  data_flag
  cjne  a, #18h, rh_not18
  clr  bdec_data
  mov  data_flag, #0ffh
  sjmp  rh_gn
rh_not18: sjmp  $
rh_gn:  pop  acc   
rh_goon:
re_loop1: lcall  in_bit
  rlc  a
  djnz  r3,  re_loop1
  ret

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

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

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

  cjne  a, #10, ws_not10
ws_big:  sjmp  $   ;大于等于十
ws_not10: jnc  ws_big

  setb  bdec_data

  mov  data_flag, #18h

  mov  a,  b
  cjne  a, #10, ws1_not10
ws1_big: sjmp  $   ;大于等于十
ws1_not10: jnc  ws1_big

  setb  bdec_data

  mov  data_flag, #18h

  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,  #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,  #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
  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,  #5 
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
wsd_lp: 
  lcall  write_1_sd
  inc  r0
  inc  r1
  djnz  r2,  wsd_lp
  ret

;=========================================================================
;  fuction: time_int ;时钟初始化程序
;  input:  ------------
;  output:  ------------
;  usage:  a,r0
;=========================================================================
time_int: ;时钟初始化程序
  lcall  start_sd
  mov  a,  #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,  #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
  ret

分享到:

上一篇: X5045 C语言版驱动程序

下一篇: 实时时钟DS1302 驱动

评论 (2条) 发表评论

  • wby
    wby : 我觉得,单片机及DSP的学习应从汇编向C语言过渡;只有对其结构、RAM和FLASH的清晰了解,才可得心应手!要对结构、RAM和FLASH以及工作机理的清晰了解,离开其汇编语言可能是要走弯路的。通过对汇编语言的深入了解,才可了解该智能芯片的设计精髓。也可体会到芯片设计者的良苦用心!不了解汇编至少对调试程序是个损失,当用高级语言调试无法通过时,看看其编译后的汇编程序会豁然开朗。会汇编很快可用C语言编程,但是,会C语言未必就很快能用汇编语言编程;况且,用汇编语言一切均在你的掌控之下,比如你用的是RAM的那个单元,你说了算,用C语言你可能不知道还剩下几个RAM单元没有用,如此等等。有许多人VC用得很好,可是并不深入了解CPU及主板等的工作原理和过程,我就是这样,这样的结果是,我们永远受制于人,决不会有世界一流的有我们中国自己知识产权的操作系统的!

    2010-05-03 16:29

  • 得得 (游客) : 我靠,世界末日了还写汇编,妈的,C++,C干嘛去了

    2010-05-03 07:04

发表评论
验证码