klok pic16f628

Als ontspanning tijdens de examens heb ik mij wat verdiept in het programmeren van microcontrollers. Eerst ledjes aansturen, 7 segment decoder. Maar ik zou graag een klok willen programmeren. Maar hier heb ik een heleboel vragen bij. De meeste heb ik al opgezocht maar vond ik niet direct een antwoord op. Ik zou alleen de minuten en de uren willen weergeven en de displays gemultiplext sturen.

1. Nu werk ik altijd met Delayms, maar dit gaat nu niet omdat ik ze dan niet op een deftige manier kan multiplexen. Wat zijn hier de oplossingen voor?
2. Ik heb zowat zitten rondneuzen bij dickbest en daar heb ik een interessant IC'tje tegengekomen, DS1307 maar dit is een I²C sturing. Ik heb de datasheet al eens goed gelezen maar ik geraak er niet echt aan uit. Ook al wat gezocht naar voorbeelden op het internet maar deze zijn meestal in C of Asm, maar ik ben nu bezig met basic. Heeft iemand tips of voorbeelden van hoe ik dit moet gebruiken?
3. Het is later de bedoeling dat de 7 segment displays vervangen worden door 7 segment nixie buisjes. Ik heb al gezien dat er voor nixiebuisjes een driver bestaat 74141 maar deze is dus hier niet bruikbaar. Is er een ander bruikbaar IC? 74247, 4511 zijn niet bruikbaar veronderstel ik...? Of zullen het allemaal mosfets moeten worden voor de segmenten te sturen? Of 3 state buffer?

Karel

hadv

Golden Member

Het multiplexen kun je het best in een interrupt routine doen.

Just find out what you like and let it kill you

ik heb toevallig net vorige week een klok gemaakt met de pic16f628a en een ds1307 van dickbest.
ik heb nu de tijd gewoon op mijn lcd scherm met backup batterij en 2 instelknoppen. als je wilt heb ik hier een complete code in picbasic voor je.

Ik heb een tijd geleden een tutoreal voor de ds3232 RTC in picbasic te gebruiken geschreven.
Die rtc is bijna hetzelfde als een ds1307 (de 1307 kan wat minder.)
http://www.schematheek.net/index.php?p=artikel/artikel&t=28

Verder kan je hier ook nog een projectje met ds1307 vinden dat in picbasic is geprogrammeerd.
http://www.elektronicastynus.be/Projecten/Klokken/PC_Klok/index.php
http://www.elektronicastynus.be/Projecten/Werplaats_mods/IN-.../index.php

Met vriendelijke groet, Stynus ||| http://www.elektronicastynus.be ||| http://e-stynus.com ||| --> Automatische trapverlichting <--

@hadv: eens kijken hoe dit precies werkt :) bedankt voor de reactie.

@tysie: zou wel fijn zijn, dan kan ik dit wat ontleden :) ik heb mijn e-mailadres zichtbaar gemaakt.

@Stynus: die tutorial is wel handig :o kan ik zeker nuttige dingen uithalen, bedankt!

Karel

ik zal hem morgen sturen ik ben nu aant leren en die code staat op een andere computer

hadv

Golden Member

Mijn klok is bijna af, ik ben nu aan het calibreren (32768 kristal als basis voor de tijd).

Ik stuur 30 (6x5) kolommen en 2 rijen van 7 bits aan via de Timer0 interrupt. Deze code kun je van me krijgen als je dat wilt. Processor is een 18F442, maar het principe is ook voor 16F uC's bruikbaar.
Binnenkort komt-ie in Show your projects.

Als de code wilt hebben moet je maar even een seintje geven.

Just find out what you like and let it kill you

Ik denk dat ik verlopig even verder kan met de tutorial van stynus.
Maar misschien dat ik het later nog kan gebruiken, ik zal dan wel iets laten weten :)

Karel

@ Hadv

jij gebruikt zeker dot matrixen in plaats van LCD display?

...
hadv

Golden Member

Voor het project waar ik nu mee bezig ben inderdaad 6 stuks 5x7 bicolor. Met de juiste weerstanden wordt dat prachtig rood, geel/oranje en groen.
Is een cadeautje voor vrienden van me die een huis hebben gekocht.
"ze wilden een klok".
Dan kun je natuurlijk met een LCD'tje, of zelfs een GLCD'tje, gaan werken, maar dat is zo klein en lang zo leuk niet als een klok waarbij je, door een touchbutton aan te raken door, momenteel 33, kleurpatronen heen wandelt.
Die kleurpatronen varieren van alles rood of groen of geel tot een soort van Knightrider waarbij 1 kleur heen en weer jakkert.

Just find out what you like and let it kill you

Wat als ik met basic bvb 47 / 10 doe?
krijg ik dan 4 of een 5 als uitkomst?
En als het een 5 zou zijn, is er dan een manier voor te zorgen dat hij toch naar beneden afrond?

Karel

Integer divide is altijd 4. Rounding gebeurt alleen als je floating point variabelen gebruikt.

Arco - "Simplicity is a prerequisite for reliability" - www.arcovox.com

En ik vrees dat iemand die dit soort vragen stelt, meer kan leren door eerst in assembler wat rond te hannessen.

hoe beter de vraag geschreven, zoveel te meer kans op goed antwoord

Ik heb dit jaar een 8086 leren programmeren met assembler dus ik kan het wel, maar als ik dan eens een programma voor microcontrollers bekijk zie dit er gans anders uit... Daarmee dat ik picbasic genomen heb, dit heb ik in het secundair ook gezien, eigenlijk bascom maar lijkt er wat op vind ik. C kan ik ook een beetje, maar zelfde probleem als met asm, ziet er een stuk anders uit voor microcontrollers...

Goede tutorials zijn altijd welkom voor pics te programmeren in C en ASM ;)

Karel

Als je de 8086 in assembly kunt programmeren, moet de PIC een fluitje van een cent zijn...
Heeft een veel eenvoudigere instructieset: http://ww1.microchip.com/downloads/en/DeviceDoc/31029a.pdf

Arco - "Simplicity is a prerequisite for reliability" - www.arcovox.com

Merci die pdf had ik nog niet gevonden, na de examens een goed bekijken ;) Programmeren in asm vind ik een stuk leuker dan basic :)

Karel

Op 14 juni 2010 17:43:23 schreef tysie:
ik heb toevallig net vorige week een klok gemaakt met de pic16f628a en een ds1307 van dickbest.
ik heb nu de tijd gewoon op mijn lcd scherm met backup batterij en 2 instelknoppen. als je wilt heb ik hier een complete code in picbasic voor je.

Heb je toevallig die code nog?

Ik wil nl een DS3231 RTC koppelen aan een PIC16F628A

Plans are nothing, planning is everything. Dwight D. Eisenhower
fatbeard

Honourable Member

Op 16 juni 2010 11:17:21 schreef charel000:
Merci die pdf had ik nog niet gevonden, na de examens een goed bekijken ;) Programmeren in asm vind ik een stuk leuker dan basic :)

Karel

I second that motion ;)

Een goed begin is geen excuus voor half werk; goed gereedschap trouwens ook niet. Niets is ooit onmogelijk voor hen die het niet hoeven te doen.
LDmicro user.

Wel oude koe, maar legitieme vraag...
@fatbeard: Dan maar gelijk een 'echte' assembly-klok erbij. (gebruikt maar 4% flashgeheugen... :) )
Met gelijkzetknopje en knipperende secondepunt...

pic asm code:


;==============================================================================
; CLOCK.ASM. Clock frequency = 10MHz
;==============================================================================
#include <p16F648a.inc>
 
                __config (_EXTCLK_OSC & _WDT_OFF & _LVP_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _BOREN_OFF)
                radix    dec
 
pclath_temp     equ     0x70
w_temp          equ     0x71
status_temp     equ     0x72
digcount        equ     0x73
digit1          equ     0x74
digit2          equ     0x75
digit3          equ     0x76
digit4          equ     0x77
seccount        equ     0x78
flags           equ     0x79
mincount        equ     0x7A
keycount        equ     0x7B

#define         fminute flags,0
#define         fkeyrpt flags,1

#define         dp      portb,7
#define         button  porta,4
 
maxdigits       equ     d'4'
keytime         equ     d'250'
keyrepeattime   equ     d'30'

set_disp        macro   d4, d3, d2, d1
                movlw   d4
                movwf   digit4
                movlw   d3
                movwf   digit3
                movlw   d2
                movwf   digit2
                movlw   d1
                movwf   digit1
                clrf    seccount
                bcf     fminute
                endm
 
;==============================================================================
; Program start
;------------------------------------------------------------------------------
                org     0x000
                goto    Init
 
;==============================================================================
; Interrupt routine
;------------------------------------------------------------------------------
Irq             org     0x004                   
                ;--------------------------------------------------------------
                movwf   w_temp                  ;Save context registers
                movf    status,w                ;
                movwf   status_temp	            ;
                movf    pclath,w	            ;
                movwf   pclath_temp
                ;-------------------------------------------------------------- 
                banksel pir1                    ;See if timer2 interrupt
                btfss   pir1,tmr2if             ;
                goto    restore                 ;No, return
                ;--------------------------------------------------------------
                btfsc   button                  ;See if button pressed
                goto    button_no               ;No, end
                btfsc   fkeyrpt                 ;Yes, see if repeat
                goto    button_set              ;
                movlw   keytime                 ;See if max time
                xorwf   keycount,w              ;
                btfsc   status,z                ;
                goto    button_2                ;Yes, set repeat flag
                incf    keycount,f              ;First press, incr time
                movlw   keyrepeattime           ;if keyrepeattime reached
                xorwf   keycount,w              ;
                btfss   status,z                ;
                goto    button_end              ;
                goto    button_inc2             ;
button_2        bsf     fkeyrpt                 ;
                goto    button_inc              ;
button_set      incf    keycount,f              ;In repeat mode.
                movlw   keyrepeattime           ;Update time every repeat cycle
                xorwf   keycount,w              ;
                btfsc   status,z                ;
                goto    button_inc              ;
                goto    button_end              ;
button_no       bcf     fkeyrpt                 ;
                clrf    keycount                ;
                goto    button_end              ;
button_inc      clrf    keycount                ;
button_inc2     clrf    seccount                ;
                clrf    mincount                ;
                bsf     fminute                 ;
button_end
                ;--------------------------------------------------------------  		
                incf    seccount,f              ;Counter handling (250 irq's is
                movf    seccount,w              ;one second)
                xorlw   d'250'                  ;On 60 seconds, update minutes
                btfss   status,z                ;
                goto    irq_disp                ;
                clrf    seccount                ;
                incf    mincount                ;
                movf    mincount,w              ;  
                xorlw   d'60'                   ;
                btfss   status,z                ;
                goto    irq_disp                ;  
                clrf    mincount                ;
                bsf    	fminute                 ;
                ;--------------------------------------------------------------                  
irq_disp        movf    digcount,w		        ;Display update cycle
                call    digtab			        ;Digit 0 to MAXDIGITS
                movwf	porta                   ;
                movlw	digit1                  ;
                movwf	fsr                     ;
                movf	digcount,w              ;
                addwf	fsr,f                   ;
                movf	indf,w                  ;
                call	segtab                  ;			
                movwf	portb                   ;
                movf    digcount,w              ;
                xorlw   d'2'                    ;Toggle the DP every half second
                btfss   status,z                ;      
                goto    irq_disp_nodp           ;
                movf    seccount,w              ;
                sublw   d'125'                  ;
                btfss   status,c                ;
                bsf     dp                      ;
irq_disp_nodp   incf	digcount,f              ;    
                movf	digcount,w              ;
                xorlw	maxdigits               ;
                btfsc	status,z                ;
                clrf	digcount                ;
                ;--------------------------------------------------------------
                banksel	pir1                    ;Clear timer flag
                bcf		pir1,tmr2if
                goto	restore
                ;--------------------------------------------------------------  
segtab          addwf   pcl,f                   ;Segment tab (port B)
                dt      0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f
                ;-------------------------------------------------------------- 
digtab          addwf   pcl,f                   ;Digit tab (port A)
                dt      0x1,0x2,0x4,0x8
                ;--------------------------------------------------------------              
restore         movf    pclath_temp,w	        ;Context restore      
                movwf   pclath                  ;
                movf    status_temp,w           ;
                movwf   status                  ;
                swapf   w_temp,f                ;
                swapf   w_temp,w                ;
                retfie                          ;

;==============================================================================
; Initialize
;------------------------------------------------------------------------------ 
Init		
                banksel pie1
                bsf     pie1,tmr2ie
                clrf	digcount
		
                banksel t2con                   ;Timer 2 on
                movlw   b'00100111'             ;Prescaler 16, postscaler 5
                movwf   t2con
		
                banksel pr2                     ;Timer 2 value 
                movlw   d'124'
                movwf   pr2
		
                bsf     intcon,gie	
                bsf     intcon,peie
 
                banksel cmcon                   
                movlw   0x07
                movwf   cmcon

                clrf    seccount
                clrf    mincount
                clrf    keycount

                banksel trisa                   ;Set in/output
                movlw   b'00010000'
                movwf   trisa
                movlw   b'00000000'
                movwf   trisb
 
;==============================================================================
; Main program
;------------------------------------------------------------------------------
main            set_disp 0,0,0,0                ;Load with 00:00 (min:sec)
                
loop            btfss   fminute					;Loop until minute elapsed
                goto    loop

update          incf    digit1,f				;Update digits
                movlw   d'10'
                xorwf   digit1,w
                btfss   status,z
                goto    loop_end
                clrf    digit1
		
                incf    digit2,f
                movlw   d'6'
                xorwf   digit2,w
                btfss   status,z
                goto    loop_end
                clrf    digit2
                
                incf    digit3,f
                movlw   d'10'
                xorwf   digit3,w
                btfss   status,z
                goto    loop_end
                clrf    digit3
                incf    digit4,f

loop_end        bcf     fminute
                movlw   d'2'
                xorwf   digit4,w
                btfss   status,z
                goto    loop
                movlw   d'4'
                xorwf   digit3,w
                btfsc   status,z
                goto    main                                                               
         	goto	loop
				      
                end

Arco - "Simplicity is a prerequisite for reliability" - www.arcovox.com

Hmm, Dat is een Assembly.
Ik zoek eigenlijk een PICBasic voorbeeld om een DS3231 uit te lezen.
In de PICbasic cursus wordt dat deel net overgeslagen.

Plans are nothing, planning is everything. Dwight D. Eisenhower

Da's gewoon een i2c ic, dus weinig bijzonders aan.
Maar er zijn wel voorbeelden: http://www.picbasic.co.uk/forum/showthread.php?t=20345

Arco - "Simplicity is a prerequisite for reliability" - www.arcovox.com

Ik heb het voorbeeld bekeken, maar kan er nog niet veel mee beginnen. Het is geen PICBasic en na 'converteren' krijg ik nog veel compiler errors.
Daarbij vind je eigenlijk vrijwel niets op internet vwb de koppeling van een RTC zoals de DS3231 en de PIC16F628A. Wat je wel regelmatig tegenkomt is de PIC6F877A.
Blijkbaar is die meer geschikt voor een I2C protocol.
Kan het überhaupt wel met een PIC16F628A?
Want ja, daar ben ik mee begonnen met de microprocessoren en om nu meteen maar een ander type te gaan gebruiken lijkt voor nu althans een stap te ver.

Plans are nothing, planning is everything. Dwight D. Eisenhower

De 627/28//48(a) hebben geen i2c, dus moet dat softwarematig geëmuleerd worden, niet de beste keuze.
Daarbij is het al een bejaard beestje (ruim 20 jaar), niet de beste keus om mee te beginnen.

Iets als de 16F1827 is pin-compatible en heeft een MSSP (SPI/I2C) en kan veel meer voor een lagere prijs.

Arco - "Simplicity is a prerequisite for reliability" - www.arcovox.com

Dan moet ik misschien toch gaan kijken naar een meer moderner type uC.
Het is best wel lastig (voor mij althans) om een goed overzicht te hebben wat er aan PIC controllers op de markt is met hun mogelijkheden.

Tja, ik had een voorraadje van de PIC16F628A gekocht; ze kostten € 0,92 bij 'Alie'. Is natuurlijk ook wel supergoedkoop.
De 1827 is bij Conrad te koop zag ik, echter niet in een DIL uitvoering.

De PIC16F877A kan blijkbaar wel I2C aan en is goed verkrijgbaar. Of is dat ook een 'oud' beestje? er zijn wel voorbeelden met software van deze chip te
vinden merkte ik.

Plans are nothing, planning is everything. Dwight D. Eisenhower