搜索
bottom↓
回复: 17

分享我的M8+DS1302+LCD1602电子钟

[复制链接]

出0入8汤圆

发表于 2009-10-16 11:09:10 | 显示全部楼层 |阅读模式
初次尝试玩DS1302电子钟,经过几天的摸索和调试,终于获得了成功,现上传相关资料和代码,下面是实验板图片:
(原文件名:DSC00235.JPG)
下面是LCD1602的现实效果图片:

(原文件名:DSC00236.JPG)
下面是源代码:
'这是一个M8+DS1302的数字钟程序
'portb.5接DS1302的RST,portb.4接sclk,portb.3接I/O?
'本机采用三键结构,其中pinc.2为选择调试键,pinc.4为数字加键,pinc.3为数字减键,相关数值调整后同步写入DS1302相应的寄存器。

$regfile = "m8def.dat"
$crystal = 8000000
$hwstack = 32                                               ' 设置堆栈大小
$swstack = 10
$framesize = 40
Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7 , E = Portd.3 , Rs = Portd.2
Config Lcd = 16 * 2
Cursor Off
Declare Sub Outbit(a As Byte)                               '发送字节
Declare Sub Inbit(indat As Byte)                            '接收字节
Declare Sub Finish                                          '结束操作
Declare Sub Begin                                           '开始写入
Dim A As Byte
Dim B As Byte
Dim C As Byte
Dim J As Byte
Dim Ax As Byte , Ad As Byte
Dim T(7) As Byte , Ts(7) As String * 2 , Tq As String * 2
Dim Tt As Byte

Call Begin                                                  '充电设定
A = &H90                                                    '地址144
Call Outbit(a )                                             '写入地址
A = &B10101010                                              '允许充电。电阻4K,两个二极管
Call Outbit(a)                                              '写入充电设置
Call Finish                                                 '结束操作
Waitms 10
Cls
Ax = 126
Ad = 127
Tt = 0
B = 0
C = 0
Do
  For J = 1 To 7
      Ad = Ad + 2
      A = Ad
      Call Begin
      Call Outbit(a)                                        '写入读取数据的地址
      Call Inbit(b)                                         '读取数据
      Call Finish                                           '结束操作
      B = Makedec(b)                                        '取数,bcd2dec转换
      Ts(j) = Str(b)
      Ts(j) = Format(ts(j) , "00")
   Next J
      Locate 2 , 9
      Lcd Ts(3) ; ":" ; Ts(2) ; ":" ; Ts(1)
      Locate 1 , 7
      Lcd "20" ; Ts(7) ; "-" ; Ts(5) ; "-" ; Ts(4)
      Ad = 127
     

  If Pinc.2 = 0 Then                                        '选择调试
     Waitms 20
     If Pinc.2 = 0 Then
        Incr Tt
        If Tt > 8 Then Tt = 1
        Bitwait Pinc.2 , Set
     End If
  End If

  If Tt <> 0 Then
     Tq = Ts(tt)
     Ts(tt) = "  "
     Locate 2 , 9
     Lcd Ts(3) ; ":" ; Ts(2) ; ":" ; Ts(1)
     Locate 1 , 7
     Lcd "20" ; Ts(7) ; "-" ; Ts(5) ; "-" ; Ts(4)
     Ts(tt) = Tq
     Waitms 500
   End If

If Pinc.4 = 0 Or Pinc.3 = 0 Then
   Waitms 20
   If Pinc.4 = 0 Then                                       '数字加
      B = Val(ts(tt))
      Incr B
      Bitwait Pinc.4 , Set
   Elseif Pinc.3 = 0 Then                                   '数字减
      B = Val(ts(tt))
      Decr B
      Bitwait Pinc.3 , Set
   End If
      T(tt) = Makebcd(b)
      C = Tt * 2
      Ax = Ax + C
      A = Ax
      Call Begin                                            '写入使能
      Call Outbit(a)                                        '首先写入地址
      A = T(tt)
      Call Outbit(a)                                        '然后写入数据
      Call Finish                                           '写入后结束本次写入
      Ax = 126
End If

Loop
End

Sub Outbit(a As Byte )                                      '发送数据子程序
   Local Temp As Byte , Tempi As Byte , I As Byte
   Ddrb.4 = 1
   Portb.4 = 0
   Ddrb.3 = 1
   Portb.3 = 0
   nop
   For I = 0 To 7
      Portb.4 = 0
      nop
      Temp = 2 ^ I
      Tempi = A And Temp
      If Tempi = 0 Then
         Portb.3 = 0
         Else
         Portb.3 = 1
      End If
      nop
      Portb.4 = 1
      nop
   Next I
   nop
End Sub


Sub Inbit(indat As Byte )                                   '接收数据的子程序
   Local Readtemp As Byte , Temp As Byte , I As Byte

   Ddrb.4 = 1
   Portb.4 = 1
   Indat = 0
   Readtemp = 0
   nop
   Ddrb.3 = 0
   Portb.3 = 1
   nop
   For I = 0 To 7
      Portb.4 = 1                                           '高电位换数据
      nop
      Portb.4 = 0
      nop
      If Pinb.3 = 1 Then
         Temp = 2 ^ I
         Readtemp = Readtemp + Temp
         Elseif Pinb.3 = 0 Then
         Temp = 0
      End If
      nop
   Next I
   Indat = Readtemp
   Portb.4 = 0
End Sub


Sub Finish                                                  '结束操作子程序
   Ddrb.4 = 0
   Portb.4 = 0
   nop
   Ddrb.5 = 1
   Portb.5 = 0
   nop
End Sub

Sub Begin                                                   '开始操作子程序
   nop
   Ddrb.5 = 1
   Portb.5 = 1
   nop
   Ddrb.4 = 1
   Portb.4 = 0
   nop
End Sub

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入8汤圆

 楼主| 发表于 2009-10-16 18:22:10 | 显示全部楼层
下班回来发现此贴竟然没有人顶,没办法自己顶一下

出0入0汤圆

发表于 2009-10-16 21:13:42 | 显示全部楼层

汇编

出0入0汤圆

发表于 2009-10-16 22:41:28 | 显示全部楼层
楼上如何看出是汇编?

出0入0汤圆

发表于 2009-10-16 22:48:34 | 显示全部楼层
basic 的,非汇编

出0入8汤圆

 楼主| 发表于 2009-10-19 14:54:54 | 显示全部楼层
我看了一些论坛内的相关帖子,提到很多DS1302的问题,比如走时精度、晶振还有起振难等问题,我竟然都没有碰到,我使用的DS1302就是花2元在电子商城买的,晶振也是普通的32768的,没有外接电容,电路也是采用标准电路,弄好了竟然工作非常好,走时很准确

出0入8汤圆

 楼主| 发表于 2009-10-22 11:46:21 | 显示全部楼层
在本文的实验中,我再添加了LM35测温电路,利用M8的ADC1测试环境温度,有关LM35的具体参数我不在这里赘述,连接方式是LM35的一脚直接接+5V,3脚接地,2脚直接接M824脚(外接0.1uf电容),测量范围0-99.9度,相关程序如下:
For J = 1 To 30
      W1 = Getadc(1)
      W = W + W1
  Next J
      W = W / 30
      W = W * 2560
      W = W / 1096
      W_adc = Str(w)
      W_adc = Format(w_adc , "00.0")
      Locate 2 , 1
      Lcd W_adc ; "C"
将以上程序添加到主程序DO......LOOP之间的合适位置即可。

出0入8汤圆

 楼主| 发表于 2009-11-1 17:24:38 | 显示全部楼层
本实验再次更新,加入秒表功能,在正常走时中,按下S1键启动秒表,按下S2键停止秒表,再加上前面所述的测温功能,代码如下:
'这是一个M8+DS1302的数字钟程序
'portb.5接DS1302的RST,portb.4接sclk,portb.3接I/O?
'本机采用三键结构,其中pinc.2为选择调试键,pinc.4为数字加键,pinc.3为数字减键,相关数值调整后同步写入DS1302相应的寄存器。

$regfile = "m8def.dat"
$crystal = 8000000
$hwstack = 32                                               ' 设置堆栈大小
$swstack = 10
$framesize = 40
Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7 , E = Portd.3 , Rs = Portd.2
Config Lcd = 16 * 2
Config Adc = Single , Prescaler = Auto , Reference = Internal
Cursor Off
Declare Sub Outbit(a As Byte)                               '发送字节
Declare Sub Inbit(indat As Byte)                            '接收字节
Declare Sub Finish                                          '结束操作
Declare Sub Begin                                           '开始写入
Dim A As Byte
Dim B As Byte
Dim C As Byte
Dim D As Byte
Dim J As Byte
Dim Ax As Byte , Ad As Byte
Dim T(7) As Byte , Ts(7) As String * 2 , Tq As String * 2 , Ta As String * 2
Dim Tt As Byte
Dim W As Long , W1 As Word , W_adc As String * 4
Dim Shi As String * 2 , Fen As String * 2 , Miao As String * 2 , S As Bit , S1 As Byte , S2 As Byte , S3 As Byte , S4 As Byte
Start Adc
Call Begin                                                  '充电设定
A = &H90                                                    '地址144
Call Outbit(a )                                             '写入地址
A = &B10101010                                              '允许充电。电阻4K,两个二极管
Call Outbit(a)                                              '写入充电设置
Call Finish                                                 '结束操作
Waitms 10
Cls
Ax = 126
Ad = 127
Tt = 0
B = 0
C = 0
W = 0
W1 = 0
S = 0
D = 0
Do

      If S = 0 Then
         For J = 1 To 7
             Ad = Ad + 2
             A = Ad
             Call Begin
             Call Outbit(a)                                 '写入读取数据的地址
             Call Inbit(b)                                  '读取数据
             Call Finish                                    '结束操作
             B = Makedec(b)                                 '取数,bcd2dec转换
             Ts(j) = Str(b)
             Ts(j) = Format(ts(j) , "00")
          Next J
          Locate 2 , 1
          Lcd "  " ; Ts(3) ; ":" ; Ts(2) ; ":" ; Ts(1)
          Locate 1 , 1
          Lcd "20" ; Ts(7) ; "-" ; Ts(5) ; "-" ; Ts(4) ; " " ; Ts(6) ; "day"
          Ad = 127
      Elseif S = 1 Then
         Miao = Str(s3)
         Fen = Str(s2)
         Shi = Str(s1)
         Miao = Format(miao , "00")
         Fen = Format(fen , "00")
         Shi = Format(shi , "00")
         Locate 2 , 1
         Lcd Shi ; ":" ; Fen ; ":" ; Miao
         A = 129
         Call Begin
         Call Outbit(a)
         Call Inbit(d)
         Call Finish
         If D <> B Then
            S3 = S3 + 1
            If S3 > 59 Then
               S2 = S2 + 1
               S3 = 0
               If S2 > 59 Then
                  S1 = S1 + 1
                  S2 = 0
                  S3 = 0
               End If
            End If
         End If
            B = D
      End If

  If Pinc.2 = 0 Then                                        '选择调试
     Waitms 20
     If Pinc.2 = 0 Then
        Incr Tt
        If Tt > 7 Then Tt = 0

     End If
  End If

  For J = 1 To 30
      W1 = Getadc(1)
      W = W + W1
  Next J
      W = W / 30
      W = W * 2560
      W = W / 1094
      W_adc = Str(w)
      W_adc = Format(w_adc , "00.0")
      Locate 2 , 12
      Lcd W_adc ; "C"

If Tt <> 0 Then
     Tq = Ts(tt)
     Ts(tt) = "  "
     Locate 2 , 3
     Lcd Ts(3) ; ":" ; Ts(2) ; ":" ; Ts(1)
     Locate 1 , 1
     Lcd "20" ; Ts(7) ; "-" ; Ts(5) ; "-" ; Ts(4) ; " " ; Ts(6) ; "day"
     Ts(tt) = Tq
     Waitms 800

  If Pinc.4 = 0 Or Pinc.3 = 0 Then
     Waitms 20
     If Pinc.4 = 0 Then                                     '数字加
        B = Val(ts(tt))
        Incr B
     Elseif Pinc.3 = 0 Then                                 '数字减
        B = Val(ts(tt))
        Decr B
     End If
        T(tt) = Makebcd(b)
        C = Tt * 2
        Ax = Ax + C
        A = Ax
        Call Begin                                          '写入使能
        Call Outbit(a)                                      '首先写入地址
        A = T(tt)
        Call Outbit(a)                                      '然后写入数据
        Call Finish                                         '写入后结束本次写入
        Ax = 126
  End If
End If

  If Pinc.4 = 0 And Tt = 0 Then                             '启动秒表程序段
    Waitms 20
    If Pinc.4 = 0 Then
       Shi = "00"
       Fen = "00"
       Miao = "00"
       S1 = 0
       S2 = 0
       S3 = 0
       S = 1
       B = 0
       A = 129
       Bitwait Pinc.4 , Set
       Cls
       Call Begin
       Call Outbit(a)
       Call Inbit(b)
       Call Finish

    End If
  End If

  If Pinc.3 = 0 And S = 1 Then                              '停止秒表
     Waitms 20
     If Pinc.3 = 0 Then
     S = 0
     Cls
     Bitwait Pinc.3 , Set
     End If
  End If
Loop
End

Sub Outbit(a As Byte )                                      '发送数据子程序
   Local Temp As Byte , Tempi As Byte , I As Byte
   Ddrb.4 = 1
   Portb.4 = 0
   Ddrb.3 = 1
   Portb.3 = 0
   For I = 0 To 7
      Portb.4 = 0
      Temp = 2 ^ I
      Tempi = A And Temp
      If Tempi = 0 Then
         Portb.3 = 0
         Else
         Portb.3 = 1
      End If
      Portb.4 = 1
   Next I
End Sub

Sub Inbit(indat As Byte )                                   '接收数据的子程序
   Local Readtemp As Byte , Temp As Byte , I As Byte
   Ddrb.4 = 1
   Portb.4 = 1
   Indat = 0
   Readtemp = 0
   Ddrb.3 = 0
   Portb.3 = 1
   For I = 0 To 7
      Portb.4 = 1                                           '高电位换数据
      Portb.4 = 0
      If Pinb.3 = 1 Then
         Temp = 2 ^ I
         Readtemp = Readtemp + Temp
         Elseif Pinb.3 = 0 Then
         Temp = 0
      End If
   Next I
   Indat = Readtemp
   Portb.4 = 0
End Sub

Sub Finish                                                  '结束操作子程序
   Ddrb.4 = 0
   Portb.4 = 0
   Ddrb.5 = 1
   Portb.5 = 0
End Sub

Sub Begin                                                   '开始操作子程序
   Ddrb.5 = 1
   Portb.5 = 1
   Ddrb.4 = 1
   Portb.4 = 0
End Sub

出0入8汤圆

 楼主| 发表于 2009-11-1 17:24:48 | 显示全部楼层
本实验再次更新,加入秒表功能,在正常走时中,按下S1键启动秒表,按下S2键停止秒表,再加上前面所述的测温功能,代码如下:
'这是一个M8+DS1302的数字钟程序
'portb.5接DS1302的RST,portb.4接sclk,portb.3接I/O?
'本机采用三键结构,其中pinc.2为选择调试键,pinc.4为数字加键,pinc.3为数字减键,相关数值调整后同步写入DS1302相应的寄存器。

$regfile = "m8def.dat"
$crystal = 8000000
$hwstack = 32                                               ' 设置堆栈大小
$swstack = 10
$framesize = 40
Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7 , E = Portd.3 , Rs = Portd.2
Config Lcd = 16 * 2
Config Adc = Single , Prescaler = Auto , Reference = Internal
Cursor Off
Declare Sub Outbit(a As Byte)                               '发送字节
Declare Sub Inbit(indat As Byte)                            '接收字节
Declare Sub Finish                                          '结束操作
Declare Sub Begin                                           '开始写入
Dim A As Byte
Dim B As Byte
Dim C As Byte
Dim D As Byte
Dim J As Byte
Dim Ax As Byte , Ad As Byte
Dim T(7) As Byte , Ts(7) As String * 2 , Tq As String * 2 , Ta As String * 2
Dim Tt As Byte
Dim W As Long , W1 As Word , W_adc As String * 4
Dim Shi As String * 2 , Fen As String * 2 , Miao As String * 2 , S As Bit , S1 As Byte , S2 As Byte , S3 As Byte , S4 As Byte
Start Adc
Call Begin                                                  '充电设定
A = &H90                                                    '地址144
Call Outbit(a )                                             '写入地址
A = &B10101010                                              '允许充电。电阻4K,两个二极管
Call Outbit(a)                                              '写入充电设置
Call Finish                                                 '结束操作
Waitms 10
Cls
Ax = 126
Ad = 127
Tt = 0
B = 0
C = 0
W = 0
W1 = 0
S = 0
D = 0
Do

      If S = 0 Then
         For J = 1 To 7
             Ad = Ad + 2
             A = Ad
             Call Begin
             Call Outbit(a)                                 '写入读取数据的地址
             Call Inbit(b)                                  '读取数据
             Call Finish                                    '结束操作
             B = Makedec(b)                                 '取数,bcd2dec转换
             Ts(j) = Str(b)
             Ts(j) = Format(ts(j) , "00")
          Next J
          Locate 2 , 1
          Lcd "  " ; Ts(3) ; ":" ; Ts(2) ; ":" ; Ts(1)
          Locate 1 , 1
          Lcd "20" ; Ts(7) ; "-" ; Ts(5) ; "-" ; Ts(4) ; " " ; Ts(6) ; "day"
          Ad = 127
      Elseif S = 1 Then
         Miao = Str(s3)
         Fen = Str(s2)
         Shi = Str(s1)
         Miao = Format(miao , "00")
         Fen = Format(fen , "00")
         Shi = Format(shi , "00")
         Locate 2 , 1
         Lcd Shi ; ":" ; Fen ; ":" ; Miao
         A = 129
         Call Begin
         Call Outbit(a)
         Call Inbit(d)
         Call Finish
         If D <> B Then
            S3 = S3 + 1
            If S3 > 59 Then
               S2 = S2 + 1
               S3 = 0
               If S2 > 59 Then
                  S1 = S1 + 1
                  S2 = 0
                  S3 = 0
               End If
            End If
         End If
            B = D
      End If

  If Pinc.2 = 0 Then                                        '选择调试
     Waitms 20
     If Pinc.2 = 0 Then
        Incr Tt
        If Tt > 7 Then Tt = 0

     End If
  End If

  For J = 1 To 30
      W1 = Getadc(1)
      W = W + W1
  Next J
      W = W / 30
      W = W * 2560
      W = W / 1094
      W_adc = Str(w)
      W_adc = Format(w_adc , "00.0")
      Locate 2 , 12
      Lcd W_adc ; "C"

If Tt <> 0 Then
     Tq = Ts(tt)
     Ts(tt) = "  "
     Locate 2 , 3
     Lcd Ts(3) ; ":" ; Ts(2) ; ":" ; Ts(1)
     Locate 1 , 1
     Lcd "20" ; Ts(7) ; "-" ; Ts(5) ; "-" ; Ts(4) ; " " ; Ts(6) ; "day"
     Ts(tt) = Tq
     Waitms 800

  If Pinc.4 = 0 Or Pinc.3 = 0 Then
     Waitms 20
     If Pinc.4 = 0 Then                                     '数字加
        B = Val(ts(tt))
        Incr B
     Elseif Pinc.3 = 0 Then                                 '数字减
        B = Val(ts(tt))
        Decr B
     End If
        T(tt) = Makebcd(b)
        C = Tt * 2
        Ax = Ax + C
        A = Ax
        Call Begin                                          '写入使能
        Call Outbit(a)                                      '首先写入地址
        A = T(tt)
        Call Outbit(a)                                      '然后写入数据
        Call Finish                                         '写入后结束本次写入
        Ax = 126
  End If
End If

  If Pinc.4 = 0 And Tt = 0 Then                             '启动秒表程序段
    Waitms 20
    If Pinc.4 = 0 Then
       Shi = "00"
       Fen = "00"
       Miao = "00"
       S1 = 0
       S2 = 0
       S3 = 0
       S = 1
       B = 0
       A = 129
       Bitwait Pinc.4 , Set
       Cls
       Call Begin
       Call Outbit(a)
       Call Inbit(b)
       Call Finish

    End If
  End If

  If Pinc.3 = 0 And S = 1 Then                              '停止秒表
     Waitms 20
     If Pinc.3 = 0 Then
     S = 0
     Cls
     Bitwait Pinc.3 , Set
     End If
  End If
Loop
End

Sub Outbit(a As Byte )                                      '发送数据子程序
   Local Temp As Byte , Tempi As Byte , I As Byte
   Ddrb.4 = 1
   Portb.4 = 0
   Ddrb.3 = 1
   Portb.3 = 0
   For I = 0 To 7
      Portb.4 = 0
      Temp = 2 ^ I
      Tempi = A And Temp
      If Tempi = 0 Then
         Portb.3 = 0
         Else
         Portb.3 = 1
      End If
      Portb.4 = 1
   Next I
End Sub

Sub Inbit(indat As Byte )                                   '接收数据的子程序
   Local Readtemp As Byte , Temp As Byte , I As Byte
   Ddrb.4 = 1
   Portb.4 = 1
   Indat = 0
   Readtemp = 0
   Ddrb.3 = 0
   Portb.3 = 1
   For I = 0 To 7
      Portb.4 = 1                                           '高电位换数据
      Portb.4 = 0
      If Pinb.3 = 1 Then
         Temp = 2 ^ I
         Readtemp = Readtemp + Temp
         Elseif Pinb.3 = 0 Then
         Temp = 0
      End If
   Next I
   Indat = Readtemp
   Portb.4 = 0
End Sub

Sub Finish                                                  '结束操作子程序
   Ddrb.4 = 0
   Portb.4 = 0
   Ddrb.5 = 1
   Portb.5 = 0
End Sub

Sub Begin                                                   '开始操作子程序
   Ddrb.5 = 1
   Portb.5 = 1
   Ddrb.4 = 1
   Portb.4 = 0
End Sub

出0入0汤圆

发表于 2009-11-2 18:48:38 | 显示全部楼层
DS1302一天相差1s能不能修正

出0入8汤圆

 楼主| 发表于 2009-11-3 10:35:07 | 显示全部楼层
选择精度较高的32768KHZ的晶振和通过调整晶振外接电容容量可以微调定时精度

出0入0汤圆

发表于 2010-5-1 23:29:23 | 显示全部楼层
有营养

出0入0汤圆

发表于 2010-7-7 10:09:05 | 显示全部楼层
有没有用ICC编的?

出0入0汤圆

发表于 2010-7-7 14:27:57 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-10-31 01:21:30 | 显示全部楼层
强人

出0入0汤圆

发表于 2010-10-31 09:20:22 | 显示全部楼层
支持,我看不懂

出0入0汤圆

发表于 2010-11-21 13:35:08 | 显示全部楼层
强!

出0入0汤圆

发表于 2015-3-9 15:06:17 | 显示全部楼层
支持,我看不懂
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-23 12:37

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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