Sida 1 av 2
Atmega32 Timer/counter2 hjälp
Postat: 17 december 2005, 13:29:22
av Virr3
Hejsan...
jag försöker att få ordning på min atmega som ska ha ett interrupt.
jag valde timer/counter2 för att jag ska hänga en klockkristall mellan TOSC1 och TOSC0...
det hela är till för en klocka...
men iallfall, jag har suttit och läst databladet hela morgonen nu, och hopppas att jag fått allt rätt...
Om jag inte fattat fel, så ska registren vara något i denna stilen...
Kod: Markera allt
SREG= 0x80 Global interrupt enable
TCCR= 0x05 Aktivera "Normal mode"
TCNT= 0x00 Vad gör TCNT?
ASSR= 0x08 Asynchronous Timer/Counter2 Enable
TIMSK= 0x80 Timer/Counter2 Overflow Interrupt Enable
Är de registrena rätt? ska de vara fler register? är det någon som är fel?
i koden så får de bli något i stil med
Kod: Markera allt
uint8_t cl;
Interrupt(owerflow2)
{cl=1; }
sei(); //enable interrupt
här har jag lite problem, för att jag vill att den bara ska växla mellan ett och 0 under en väldigt kort tid, kanske bara en klockpuls. Men, hur gör jag? för nu så kommer cl bli ett efter att klockan räknat klart till 255 och sen är den ett resten av dagen...
Skulle vara jättesnällt ifall ni kunde kolla ifall det stämmer med registren, och hur jag löser problemet med att cl ska växla mella ett och noll

Postat: 17 december 2005, 18:24:11
av monstrum
Jag är nog inte helt säker på vad du vill. Men jag kan göra ett försök.
TCNT är helt enkelt räknarens nuvarande värde, inget konfigurationsregister.
Om du inte bara vill sätta cl till ett varje gång räknaren gör overflow så får du göra nåt annat. För att växla mellan 0 och 1 så kan du t.ex. istället köra
Postat: 17 december 2005, 21:00:57
av Virr3
aha... TCNT är alltså räknarens värde

det räta ut några frågotecken:)
skulle du kunna föklara vad "&1" gör? i koden?
Postat: 18 december 2005, 05:05:43
av monstrum
Absolut. X & 1 innebär att talet X AND'as med 1, alltså endast den lägsta biten kommer med, alla andra sätts till 0. Detta gör att när cl ökar från 1 till 2 så blir resultatet 0. Nästa gång ökas cl från 0 med 1 och blir 1, osv.
Postat: 18 december 2005, 23:14:31
av karlstedt
ööh? jag förstår inte ditt problem med att du vill "växla mellan ett och 0 under en väldigt kort tid, kanske bara en klockpuls"
är det inte bara att ha
i din interruptrutin isf?
Postat: 19 december 2005, 07:43:20
av Virr3
kommer den verkligen att vara 1:a under en klockcykel då?
är den inte 1:a en _väldigt_ kort tid om man gör så?
Postat: 19 december 2005, 10:26:20
av danei
en klockcykel är väldigt kort. Hu skulle det kunna vara kortare än så?
Postat: 19 december 2005, 10:33:26
av karlstedt
att den är hög kortare än en klockcykel behöver du nog inte oroa dig för

(bortsett från stig/fall-tider då)
isf skulle du gärna få förklara det för mig...
Det är här Sodjans prat om att lära sig assembler och hur en uC fungerar kommer in

Postat: 19 december 2005, 11:22:55
av speakman
Är det inte en klockcykel av själva timerklockan (32KHz) som menas då?
Mvh
speakman
Postat: 19 december 2005, 11:32:59
av karlstedt
möjligtvis.. men vad skulle vara avsikten med det?
vad jag förstår så ska det genereras en klockpuls för diverse externa kretsar?
men vem vet? kanske virr3 får ta och förklara lite bättre vad som ska hända.
Ska cl först bli hög och sedan låg i varje interrupt eller ska den bli hög i ett interrupt och låg i nästa interrupt?
Postat: 25 december 2005, 19:40:43
av Virr3
interruptet ska bli hög och låg under samma interrupt
det är en klockpuls till extärna kretsar ja...
men, jag undrar ifall det funkar att göra så, cl=1 cl=0..
blir den inte låg sammtidigt som den blir hög då? det är väl en liten fördröjning men, är den så stor att de skulle kunna trigga ett shiftregister?
Postat: 25 december 2005, 19:43:02
av cykze
Det står i databladet för skiftregistret hur lång pulsen måste vara.
Postat: 25 december 2005, 20:07:36
av sodjan
Om shiftresgistret är ur de vanliga 74xxx eller 4xxx serierna, så kommer
säkert pulsen från en "c1=1, c1=0" sekvens att vara längre en kortaste tillåtna pulstid på klockingången på shiftregistret. Kanske med en 10-potens...
Men vad är problemet ? Sätt in en eller två NOP mellan så är du absolut pä den säkra sidan...
Sen verkar de vara lite förvirring kring "CPU-klockpulser" och "klock-klockpulser"... Kanske bäst att förtydliga vad som avses...
Postat: 26 december 2005, 02:30:04
av Virr3
jo, jag vet att det står i databladet hur lång pulsen måste vara, men jag vet ju inte hur lång den kommer att bli...
men, får prova, funkar de inte så får jag säja till, men det verkar ju som att sodjan är säker på sin sak

Postat: 26 december 2005, 05:00:30
av Kaggen
> jo, jag vet att det står i databladet hur lång pulsen måste vara, men jag vet ju inte hur lång den kommer att bli...
Åjo! Har för mig att ATmega (beroende på modell iofs) utför en instruktionscykel per klockcykel.
Ponera att du kör uC i 4 MHz. Det blir då 4 miljoner klockcykler per sekund. Om en klockcykel = en instruktionscykel så går det alltså även 4 miljoner instruktioncykler på en sekund.
Och en instruktionscykel tar isåfall hur lång tid...?
Just det... 1 / 4 000 000 = 0,00000025 sekunder = 0,25 us (microsekunder)
Om vi förutsätter att du skriver i assembler och använder SBI och CBI kommandona så krävs två cykler för att sätta och två för att nolla den aktuella biten.
Kod: Markera allt
SBI PORTB,1 ; set bit 1 PORTB (2 cykler)
CBI PORTB,1 ; clear bit 1 PORTB (2 cykler)
Om dessa instruktioner tar två instruktionscykler vardera i anspråk blir alltså periodtiden 0,25 us * 4 = 1 us, d.v.s. 0,5 us hög och 0,5 us låg.
Vad den blir om man skriver funktionen i C är lite klurigare. Det beror dels på hur du kodar och dels på hur C-kompilatorn optimerar/genererar kod. Det blir dock iaf *inte mindre* än 1 us (om det inte finns någe sätt att optimera detta som inte jag vet om).
Vad detta betyder i ditt fall får du själv räkna på.
mvh Mats