Digital klocka med PIC
Digital klocka med PIC
Någon som har byggt en digital klocka som visar tiden på 4 st 7-segment display med hjälp av en PIC processor?
iså fall undrar jag om ni gärna vill dela med er assembler koden
jag har själv fått lite problem med själva koden vill veta hur ni andra har gjort
iså fall undrar jag om ni gärna vill dela med er assembler koden
jag har själv fått lite problem med själva koden vill veta hur ni andra har gjort
under simulering så får jag en rullande tid som funkar fint
men jag vet inte hur jag ska skicka ut det till mina 7 segment display
variabler som jag använder för tiden
display_sekund1
display_sekund2
display_minut1
display_minut2
7-segmenten är 4 st i serie med varandra där hela PORTB är kopplad till
och via PORT C väljer jag vilken display som ska lysas
problemet är är att jag vet inte riktigt hur man skriver så att de uppdaterar
rätt display
men jag vet inte hur jag ska skicka ut det till mina 7 segment display
variabler som jag använder för tiden
display_sekund1
display_sekund2
display_minut1
display_minut2
7-segmenten är 4 st i serie med varandra där hela PORTB är kopplad till
och via PORT C väljer jag vilken display som ska lysas
problemet är är att jag vet inte riktigt hur man skriver så att de uppdaterar
rätt display
Hmmm...då vill jag rekommendera att du först gör en tabell som för ett given input svarar med det bitmönster som får rätt segment att lysa. Den kan t.ex vara i form av en indexering och ett antal RETLW.
Sen behöver du en timer som ger interrupt med minst 120 Hz.
För varje timer-interrupt gör du då följande:
1: Slår av "det gamla" segment-mönster (nollar PORT B)
2: Räknar upp i en indexeringsräknare vilken av siffren som ska visas.
3: Väljer rätt siffers data.
4: Slår upp i tabellen och får rätt monster.
5: Byta till nästa siffer på PORT C
6: Lägg ut segmentdatan på PORT B.
7: Avslut interruptrutinen.
Det är viktigt att du börjar med att släcka segnemten och sedan har en kort paus innan du slår på nästa siffer, i annat fall brukar man få "ghosting" då det förra monster "smittar av sig" på grund av ströladdninger osv.
Den korte stund kan man ju passande använda på att räkna lite
Sen behöver du en timer som ger interrupt med minst 120 Hz.
För varje timer-interrupt gör du då följande:
1: Slår av "det gamla" segment-mönster (nollar PORT B)
2: Räknar upp i en indexeringsräknare vilken av siffren som ska visas.
3: Väljer rätt siffers data.
4: Slår upp i tabellen och får rätt monster.
5: Byta till nästa siffer på PORT C
6: Lägg ut segmentdatan på PORT B.
7: Avslut interruptrutinen.
Det är viktigt att du börjar med att släcka segnemten och sedan har en kort paus innan du slår på nästa siffer, i annat fall brukar man få "ghosting" då det förra monster "smittar av sig" på grund av ströladdninger osv.
Den korte stund kan man ju passande använda på att räkna lite

Icecap tack för att du tog din tid, jag ska försöka göra som du säger
jag förstår inte riktigt hur den där indexeringen fungerar =/
om jag har:
seg7_0 equ b'11111100' ;0
seg7_1 equ b'01100000' ;1
seg7_2 equ b'11011010' ;2
seg7_3 equ b'11110010' ;3
seg7_4 equ b'01100110' ;4
seg7_5 equ b'10110110' ;5
seg7_6 equ b'10111110' ;6
seg7_7 equ b'11100000' ;7
seg7_8 equ b'11111110' ;8
seg7_9 equ b'11100110' ;9
säg att display_sekund1 har fått värdet 3 hur gör jag med retlw för att den ska hämta seg7_3?
jag förstår inte riktigt hur den där indexeringen fungerar =/
om jag har:
seg7_0 equ b'11111100' ;0
seg7_1 equ b'01100000' ;1
seg7_2 equ b'11011010' ;2
seg7_3 equ b'11110010' ;3
seg7_4 equ b'01100110' ;4
seg7_5 equ b'10110110' ;5
seg7_6 equ b'10111110' ;6
seg7_7 equ b'11100000' ;7
seg7_8 equ b'11111110' ;8
seg7_9 equ b'11100110' ;9
säg att display_sekund1 har fått värdet 3 hur gör jag med retlw för att den ska hämta seg7_3?
Kolla : http://ww1.microchip.com/downloads/en/A ... 00556e.pdf
"Implementing a Table Read"
Exemplen i app noten är inte helt felfria, man fungerar bra som en utgångspunkt. Kolla och kom igen om det är några frågetecken...
"Implementing a Table Read"
Exemplen i app noten är inte helt felfria, man fungerar bra som en utgångspunkt. Kolla och kom igen om det är några frågetecken...
nu är allting fixad, förutom att jag har lite problem med delay funktionen där jag vill skapa 1 ms och 100 ms, jag använder 4 MHz kristall
hur lång tid tar 1 instruktion med 4 MHz?
jag vet inte om de är en bra lösning men jag har valt att ha 1 sekunds fördröjning då jag skickar ut mina värden till alla 7 segment display
hur lång tid tar 1 instruktion med 4 MHz?
jag vet inte om de är en bra lösning men jag har valt att ha 1 sekunds fördröjning då jag skickar ut mina värden till alla 7 segment display
- EagleSpirit
- Inlägg: 1288
- Blev medlem: 27 maj 2003, 23:15:48
- Ort: Västerås
- Kontakt:
En pic @ 4Mhz hinner med 1 miljon instruktioner per sekund.. Vilket blir 1µs per instruktion... Du kan testa dina tidsfunktioner med stopwatch i MPLAB..
Jag förstår inte riktigt hur du löst det med uppdatering en gång i sekunden men du bör göra som icecap sa, då komer du få en uppdateringsfrekvens på 30hz som passar perfekt för att ögat inte ska se uppdateringen... Anledningen till att det måste vara så är att du inte kan tända alla displayer samtidigt så det måste vara en flytande uppdatering...
Jag förstår inte riktigt hur du löst det med uppdatering en gång i sekunden men du bör göra som icecap sa, då komer du få en uppdateringsfrekvens på 30hz som passar perfekt för att ögat inte ska se uppdateringen... Anledningen till att det måste vara så är att du inte kan tända alla displayer samtidigt så det måste vara en flytande uppdatering...
EagleSpirit tack för hjälpen, de hjälpe mig jätte mycket
Under simuleringen så fick jag att 1 minut motsvarade 60.002554 sekunder vilket jag tycker är rätt okej men i verkligheten så ser man att de går fel ett par sekund per minut =/ vad kan det bero på? har jag fel lastkapacitansern på min oscillator så de inte svänger riktigt?
jag använder 22pf för 4 MHz kristallen
Under simuleringen så fick jag att 1 minut motsvarade 60.002554 sekunder vilket jag tycker är rätt okej men i verkligheten så ser man att de går fel ett par sekund per minut =/ vad kan det bero på? har jag fel lastkapacitansern på min oscillator så de inte svänger riktigt?
jag använder 22pf för 4 MHz kristallen
Därför att när du uppdaterar displayerna går det åt lite tid. Denna tid adderas till din delay-loop, så det blir för mycket totalt. En timer däremot tickar på oberoende av vad som händer i övrigt, och ger interrupt när det är dags att uppdatera displayerna. samtidigt startas timern om och en ny sekund börjar räknas ner.
Men slakta mig gärna om jag har fel, jag är inte så himla erfaren själv
Men slakta mig gärna om jag har fel, jag är inte så himla erfaren själv
> kan inte du förklara lite närmare på hur timer-interrupt fungerar,...
Ytterligare en missuppfattning...
Du ska först läsa igenom de rellevanta delarna av databladet (i detta fall naturligtsvis om "Timers" och "Interrupt"), och sedan fråga här om det var något som var oklart (vilket det säkert kommer att vara !
).
Det är ju lite onödigt att någon här skall förklara något som du i alla fall hade förstått direkt ur databladet. Det som är oklart däremot, det kan vi säkert hjälpa till med.
Men för att svara kort, en klocka ska inte byggas på "delay" funktioner. Nog om det. Läs på om timers och interrupt i databladet, där har du den "rätta vägen"...
Förresten, jag tror inte att du har talat om vilken PIC du använder eller vilket språk (assembler eller något annat) som du använder. Därför kan jag inte heller styra dig till de rätta kapitlen/sidorna i databladet.
Ytterligare en missuppfattning...

Du ska först läsa igenom de rellevanta delarna av databladet (i detta fall naturligtsvis om "Timers" och "Interrupt"), och sedan fråga här om det var något som var oklart (vilket det säkert kommer att vara !

Det är ju lite onödigt att någon här skall förklara något som du i alla fall hade förstått direkt ur databladet. Det som är oklart däremot, det kan vi säkert hjälpa till med.
Men för att svara kort, en klocka ska inte byggas på "delay" funktioner. Nog om det. Läs på om timers och interrupt i databladet, där har du den "rätta vägen"...

Förresten, jag tror inte att du har talat om vilken PIC du använder eller vilket språk (assembler eller något annat) som du använder. Därför kan jag inte heller styra dig till de rätta kapitlen/sidorna i databladet.
Jovisst kan jag.
1: man ställer in timern till att ge interrupt med en viss frekvens. Den frekvens är ytterst sällan så långsam som 1 sek och därför har man en "prescale"-värde.
2: För varje timer-interrupt räknas prescalern upp eller ner, beroende på tycke. Såklart markerar man i lämpligt register att timer-interrupten är avklarat.
3: När prescalern har räknats nog har det gått 1 sekund. Återställ därför prescalern och räkna upp sekunder på normalt sätt.
Exempel: Timern sätts till att ge interrupt med 33Hz och prescalern sätts till 33.
I timer-interrupt rutinen (ISR = Interrupt Service Routine) rensas interruptflaggan och prescalern räknas ner med 1.
Om prescalern då INTE har nådd 0 är det klart, avsluta ISR'n.
I annat fall har det gått 1 sek. Återställ därför prescalern till 33 och räkna upp sekunderna med 1 (osv).
Ganska enkelt faktisk.
Om du är riktig klurig använder du timer-interrupten till att scanna på samma gång som du använder den som tidsbas.
1: man ställer in timern till att ge interrupt med en viss frekvens. Den frekvens är ytterst sällan så långsam som 1 sek och därför har man en "prescale"-värde.
2: För varje timer-interrupt räknas prescalern upp eller ner, beroende på tycke. Såklart markerar man i lämpligt register att timer-interrupten är avklarat.
3: När prescalern har räknats nog har det gått 1 sekund. Återställ därför prescalern och räkna upp sekunder på normalt sätt.
Exempel: Timern sätts till att ge interrupt med 33Hz och prescalern sätts till 33.
I timer-interrupt rutinen (ISR = Interrupt Service Routine) rensas interruptflaggan och prescalern räknas ner med 1.
Om prescalern då INTE har nådd 0 är det klart, avsluta ISR'n.
I annat fall har det gått 1 sek. Återställ därför prescalern till 33 och räkna upp sekunderna med 1 (osv).
Ganska enkelt faktisk.
Om du är riktig klurig använder du timer-interrupten till att scanna på samma gång som du använder den som tidsbas.