Stolpklok met stappenmotor

Gepost door Jeroen Vreuls op dinsdag 14 februari 2023

De software

We gaan nu naar de software kijken. Het programma is gemaakt in Proton Basic, zoals ik altijd doe.

'*  Name    : BESTURING ZELFBOUW KLOK MET DS1307.                                     
'*  Author  : H. van Zwieten                                    
'*  Notice  : Copyright (c) 2022 H.v.Z.                         
'*          : All Rights Reserved                               
'*  Date    : 5-2-2022                                          
'*  Version : 1.0                                              
'*  Notes   :                                                   

Device 16F887                     ; Processor type

Xtal 10                           ; Crystal 10Mhz

Asm                               ; Config settings
CONFIG_REQ            
__CONFIG _CONFIG1, HS_OSC & WDT_OFF & DEBUG_OFF & FCMEN_OFF & LVP_OFF & IESO_OFF & BOR_OFF & CPD_OFF & CP_OFF & MCLRE_OFF & PWRTE_ON 
__CONFIG _CONFIG2, WRT_OFF & BOR40V 
EndAsm
   
All_Digital true                  ; Alle poorten digitaal

Declare LCD_RSPin PORTD.2         ; Reset display poort D.2
Declare LCD_ENPin PORTD.3         ; Enable display poort D.3
Declare LCD_DTPin PORTD.4         ; Data display poort D.4 t/m D.7
Declare LCD_Lines 4               ; Vier lijns display

Declare SCL_Pin PORTC.3           ; I2C klok pin
Declare SDA_Pin PORTC.4           ; I2C data pin
Declare I2C_SLOW_BUS 1            ; I2C bus op 100KHz

Symbol FREQUENTIE = 200           ; Stap frequentie min 200 
Symbol FREQ_GELIJK_ZETTEN = 50    ; Stap frequentie klok gelijk zetten

Symbol STAP_WAARDE = 3200         ; Aantal micro stappen 3200

Symbol DIR_DRIVER = PORTB.3       ; Uitgang richting stappenmotor driver
Symbol PULS_DRIVER = PORTB.4      ; Uitgang puls voor stappenmotor driver
Symbol ENABLE_DRIVER = PORTB.5    ; Uitgang enable stappenmotor driver

Symbol SECONDE_LED = PORTC.2      ; Uitgang seconde led

Symbol MODE_KNOP  = PORTA.0       ; Ingang select uur, minuut, seconde
Symbol KNOP_OP    = PORTA.1       ; Ingang optellen uur, minuut, seconde
Symbol KNOP_NEER  = PORTA.2       ; Ingang aftellen uur, minuut, seconde

Symbol GELIJK_ZETTEN = PORTA.3    ; Ingang klok gelijk zetten

Dim SECONDE As Byte               ; Variabele seconde
Dim MINUUT As Byte                ; Variabele minuut
Dim UUR As Byte                   ; Variabele uur

Dim WEEKDAG As Byte               ; Variabele weekdag
Dim DAG As Byte                   ; Variabele dag
Dim MAAND As Byte                 ; Variabele maand
Dim JAAR As Byte                  ; Variabele jaar

Dim DUMMY As Byte                 ; Variabele dummy

Dim MODE As Byte                  ; Variabele mode

Dim X As Word                     ; Variabele puls teller

Cls                               ; Wis display

DelayMS 500                       ; Pauze 0.5 sec 

Clear                             ; Wis geheugen

         ;543210                  ; Hulpregel poort A
PORTA  = %000000                  ; Maak poort A laag
TRISA  = %111111                  ; Poort_A I/O

         ;543210                  ; Hulpregel poort B
PORTB  = %000000                  ; Maak poort B laag
TRISB  = %000000                  ; Poort_B I/O

         ;76543210                ; Hulpregel poort C
PORTC  = %00000000                ; Maak poort C laag
TRISC  = %00000000                ; Poort_C I/O

         ;76543210                ; Hulpregel poort D
PORTD  = %00000000                ; Maak poort D laag
TRISD  = %00000000                ; Poort_D I/O

         ;210                     ; Hulpregel poort E 
PORTE  = %000                     ; Maak poort E laag
TRISE  = %000                     ; Poort_E I/O

;------------------------------------
; LEZEN EN SCHRIJVEN NAAR DE DS1307.
;------------------------------------

BStart                            ; Bus start
BusIn %11010001,0,[SECONDE]       ; Lees seconde + bit7 (is osc. aan/uit)
DelayMS 10                        ; Wacht 10ms
Clear SECONDE.7                   ; Zet oscillator aan
BusOut %11010000,[SECONDE]        ; Schrijf naar rtc
DelayMS 10                        ; Wacht 10ms
BusIn %11010001,2,[UUR]           ; Lees uur
DelayMS 10                        ; Wacht 10ms
Clear UUR.6                       ; Select 24 uur klok
BusOut %11010000,2,[UUR]          ; Schrijf naar rtc
BStop                             ; Bus stop

;-----------------------------------------------
; PROGRAMMA BESTURING ZELFBOUW KLOK MET DS1307.
;-----------------------------------------------

ENABLE_DRIVER = 1
PULS_DRIVER = 0
DIR_DRIVER = 1

;-------------------------
; LEES RTC ALS MODE 0 IS.
;-------------------------

RUN:

  If MODE = 0 Then
    BStart                 
    BusIn %11010001,0,[SECONDE,MINUUT,UUR,WEEKDAG,DAG,MAAND,JAAR]
    BStop
       
    DUMMY = SECONDE & %01110000                 
    GoSub BEREKEN_WAARDE
    SECONDE = SECONDE & %00001111
    SECONDE = SECONDE + DUMMY
    
    DUMMY = MINUUT & %11110000
    GoSub BEREKEN_WAARDE
    MINUUT = MINUUT & %00001111
    MINUUT = MINUUT + DUMMY
    
    DUMMY = UUR & %00110000
    GoSub BEREKEN_WAARDE
    UUR = UUR & %00001111
    UUR = UUR + DUMMY
      
    DUMMY = DAG & %11110000 
    GoSub BEREKEN_WAARDE
    DAG = DAG & %00001111 
    DAG = DAG + DUMMY  
 
    DUMMY = MAAND & %11110000 
    GoSub BEREKEN_WAARDE      
    MAAND = MAAND & %00001111 
    MAAND = MAAND + DUMMY     
      
    DUMMY = JAAR & %11110000
    GoSub BEREKEN_WAARDE
    JAAR = JAAR & %00001111
    JAAR = JAAR + DUMMY  
  End If

;--------------------------------------------------------
; PRINT TEKST, UUR, MINUUT, SECONDE, DAG, MAAND EN JAAR.
;--------------------------------------------------------

  Print At 1,1,"STOLPKLOK"
  Print At 2,1,"H.v.Z. PRODUCT"
  Print At 3,1,"TIJD:",Dec2 UUR,":",Dec2 MINUUT,":",Dec2 SECONDE
  Print At 4,1,"DATUM:",Dec2 DAG,"-",Dec2 MAAND,"-20",Dec2 JAAR 

;-----------------------------------------------------------
; UREN, MINUTEN, SECONDEN, DAG, MAAND EN JAAR GELIJKZETTEN.
;-----------------------------------------------------------

  If MODE_KNOP = 1 Then
    DelayMS 10
    Inc MODE
    If MODE > 6 Then  
      MODE = 0
      GoSub SCHRIJF_RTC          
    End If 
    Repeat                          
    Until MODE_KNOP = 0 
  End If

;-------------------- 
; DAG GELIJK ZETTEN.   
;--------------------

  If MODE > 0 Then
    DelayMS 300
     
    Select Case MODE
      
      Case 1
        Print At 4,7,"  "
        DelayMS 300
        
        If KNOP_OP = 1 Then
          DelayMS 10
          Inc DAG
          If DAG > 31 Then
            DAG = 1
          EndIf
        EndIf
        
        If KNOP_NEER = 1 Then
          DelayMS 10
          Dec DAG
          If DAG < 1 Then
            DAG = 31
          EndIf
        EndIf
        
;----------------------
; MAAND GELIJK ZETTEN.
;----------------------
            
      Case 2
        Print At 4,10,"  "    
        DelayMS 300
        
        If KNOP_OP = 1 Then
          DelayMS 10
          Inc MAAND
          If MAAND > 12 Then
            MAAND = 1
          EndIf
        EndIf

        
        If KNOP_NEER = 1 Then
          DelayMS 10
          Dec MAAND
          If MAAND < 1 Then
            MAAND = 12
          EndIf
        EndIf
        
;---------------------
; JAAR GELIJK ZETTEN.
;---------------------
        
      Case 3
        Print At 4,15,"  "      
        DelayMS 300
        
        If KNOP_OP = 1 Then
          DelayMS 10
          Inc JAAR
          If JAAR > 99 Then
            JAAR = 0
          EndIf
        EndIf
        
        If KNOP_NEER = 1 Then
          DelayMS 10
          Dec JAAR
          If JAAR < 1 Then
            JAAR = 99
          EndIf
        EndIf

;--------------------
; UUR GELIJK ZETTEN.
;--------------------
       
      Case 4
        Print At 3,6,"  "   
        DelayMS 300
        
        If KNOP_OP = 1 Then
          DelayMS 10
          Inc UUR
          If UUR > 23 Then
            UUR = 0
          End If
        End If
       
        If KNOP_NEER = 1 Then
          DelayMS 10
          Dec UUR
          If UUR > 254 Then            
            UUR = 23
          End If
        End If
              
;-----------------------
; MINUUT GELIJK ZETTEN.
;-----------------------
       
      Case 5
        Print At 3,9,"  "   
        DelayMS 300
        
        If KNOP_OP = 1 Then
          DelayMS 10
          Inc MINUUT
          If MINUUT > 59 Then
            MINUUT = 0
          End If
        End If
       
        If KNOP_NEER = 1 Then
          DelayMS 10
          Dec MINUUT
          If MINUUT > 254 Then             
            MINUUT = 59
          End If
        End If
           
;------------------------
; SECONDE OP NUL ZETTEN.
;------------------------

      Case 6
        Print At 3,12,"  "   
        DelayMS 300
         
        If KNOP_OP = 1 Or KNOP_NEER = 1 Then
          DelayMS 10
          SECONDE = 0
        End If 
               
    End Select
  End If 
    
;##################################    
;--------------------------------
; HIER DE REST VAN HET PROGRAMMA.
;--------------------------------
;##################################

;-----------------------------------------
; ALS WAAR GA DAN NAAR WIJZER VERDRAAIEN.
; ALS WAAR GA DAN NAAR KLOK GELIJKZETTEN.
; IEDERE SECONDEN KNIPPERT DE LED.
;-----------------------------------------

  ENABLE_DRIVER = 1 
     
  If SECONDE = 59 Then
    GoSub VERDRAAIEN
  EndIf
    
  If GELIJK_ZETTEN = 1 Then
    GoSub KLOK_GELIJK_ZETTEN
  EndIf
    
  SECONDE_LED = ~SECONDE
     
GoTo RUN

;----------------------------
; WAARDE BEREKENEN VOOR RTC.
;----------------------------

BEREKEN_WAARDE:

  DUMMY = (DUMMY/16)*10                                                           
  Return
    
;--------------------------
; SCHRIJF WAARDE NAAR RTC.
;--------------------------

SCHRIJF_RTC:

  DUMMY = SECONDE / 10                 
  DUMMY = DUMMY * 16                
  SECONDE = SECONDE // 10                 
  SECONDE = SECONDE | DUMMY            

  DUMMY = MINUUT / 10
  DUMMY = DUMMY * 16
  MINUUT = MINUUT // 10
  MINUUT = MINUUT | DUMMY

  DUMMY = UUR / 10
  DUMMY = DUMMY * 16
  UUR = UUR // 10
  UUR = UUR | DUMMY
    
  DUMMY = DAG / 10
  DUMMY = DUMMY * 16
  DAG = DAG // 10
  DAG = DAG | DUMMY
    
  DUMMY = MAAND / 10 
  DUMMY = DUMMY * 16  
  MAAND = MAAND // 10
  MAAND = MAAND | DUMMY 
    
  DUMMY = JAAR / 10
  DUMMY = DUMMY * 16 
  JAAR = JAAR // 10
  JAAR = JAAR | DUMMY 
  
  BStart
  BusOut %11010000,0,[SECONDE,MINUUT,UUR,WEEKDAG,DAG,MAAND,JAAR]  
  BStop
  Return
    
;-----------------------------
; WIJZER 1 MINUUT VERDRAAIEN.
;-----------------------------
    
VERDRAAIEN:

  ENABLE_DRIVER = 0
  DIR_DRIVER = 1
     
  For X = 1 To STAP_WAARDE Step 1
    PULS_DRIVER = 1
    DelayUS FREQUENTIE
    PULS_DRIVER = 0
    DelayUS FREQUENTIE     
  Next X
     
  Return
    
GoTo VERDRAAIEN 
   
;------------------------------
; KLOK HANDMATIG GELIJKZETTEN.
;------------------------------
     
KLOK_GELIJK_ZETTEN:

  ENABLE_DRIVER = 0
  DIR_DRIVER = 1

  If GELIJK_ZETTEN = 1 Then
    PULS_DRIVER = 1
    DelayUS FREQ_GELIJK_ZETTEN
    PULS_DRIVER = 0
    DelayUS FREQ_GELIJK_ZETTEN
  EndIf
    
  If GELIJK_ZETTEN = 0 Then
    Return
  EndIf 
    
GoTo KLOK_GELIJK_ZETTEN    
     
End

Zoals je boven in het programma kunt zien staat de stapwaarde op 3200 stappen per minuut, zoals we uitgerekend hadden in het begin. De RTC werkt via het I²C protocol.

Daaronder staat hoe de klok gelijk gezet kan worden, dat staat onder Case 1 tot en met Case 6. Dan krijgen we het stukje waar iedere seconde de wijzer één minuut moet verdraaien.

Dan hebben we nog de drukknop voor het gelijk zetten of het verdraaien van de wijzer. En helemaal bovenaan staan de printopdrachten voor het display, voor de rest is het programma alleen om de RTC uit te lezen, dat is de meeste code.

Voor de rest moet je het programma maar eens rustig doorlopen, daar moet wel uit te komen zijn lijkt mij.