Hey.
heb vandaag een counter gemaakt met 7segment displays, bestuurd door een pic (16F690). Ik bestuur het door multiplexing. Maar het lukt slechts met 2 digits. Wanneer ik de code aanpas voor 3 digits (en uiteraard het derde display correct aansluit) dan geeft het derde display de eerste twee displays samen weer. Het probleem moet softwarematig zijn, ofwel hou ik ergens geen rekening met iets ivm multiplexing. Het eigenaardige is dat het wel lukt met 2 displays.
Hieronder de code voor 3 displays.
program segmentcounter
dim shifter, digit, portc_index as byte
dim number as word
dim port as byte[3]
sub function Mask(dim num as byte) as byte ' this function returns masks
select case num ' for common cathode 7-seg. display
case 0 result = $C0
case 1 result = $F9
case 2 result = $A4
case 3 result = $B0
case 4 result = $99
case 5 result = $92
case 6 result = $82
case 7 result = $F8
case 8 result = $80
case 9 result = $90
end select 'case end
end sub
sub procedure interrupt
PORTA = shifter ' turn on appropriate 7seg. display
PORTC = port[portc_index]
Inc(portc_index) ' increment value of variable portc_index
shifter = shifter << 1
if shifter > 4 then
shifter = 1 ' prepare mask for digit
end if
if portc_index > 2 then
portc_index = 0 ' turn on 1st, turn off 2nd 7seg.
end if
TMR0 = 0
INTCON = $20
end sub
main:
OPTION_REG = $80
digit = 0
portc_index = 0
shifter = 1
TMR0 = 0
INTCON = $A0 ' Disable PEIE,INTE,RBIE,T0IE
TRISA = 0
TRISC = 0
PORTC = 0
PORTA = 0
number = 0
while TRUE
digit = number div 100 mod 10
port[2] = Mask(digit)
digit = number div 10 mod 10 ' prepare digits for diplays
port[1] = Mask(digit)
digit = number mod 10
port[0] = Mask(digit)
Delay_ms(100)
Inc(number) ' increment counter
if number > 999 then
number = 0
end if
wend
end.pros
Prosper, yop la boum, c'est le roi du macadam (aldus Maurice Chevalier)
Voor zover ik iets van basic ken, zie ik daar geen fouten.
Maar misschien zijn het spook-segmenten, die de uitlezing verzieken. Ik zou --in de interrupt-routine-- eerst PORTA 0 maken, vervolgens PORTB instellen, en pas dan het gepaste bit op PORTA hoog maken.
Als er bipolaire transistors gebruikt worden, kan de tijd --tijdens dewelke PORTA 0 is-- best nog verlengd worden.
Arco
Special Member
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Staat er nog een analoge functie aan op port a misschien?
Is de multiplex frequentie niet te hoog?
Weet niet welke basic dit is, maar dit kan waarschijnlijk ook:
sub procedure interrupt
PORTA = 1 << portc_index 'turn on appropriate 7seg. display
PORTC = port[portc_index]
portc_index = (portc_index + 1) mod 3 'turn on 1st, turn off 2nd 7seg.
TMR0 = 0
INTCON = $20
end sub
Werk je soms ergens met inverse logic? Pinnetje moet laag zijn ipv. hoog om wat aan te sturen? Met 2 gaat dat inderdaad goed en met 3 niet...
Arco
Special Member
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Als het inderdaad een inverse logic probleem is moeten ze (bij 3 displays) allemaal verkeerd weergeven...
De code ziet er goed uit. Ik zou als eerste hardware probleem proberen uit te sluiten door een test programma te schrijven dat bijvoorbeeld 1 seconde op display 1 een 1 zet, daarna 1 seconde op display 2 een 2 en daarna een 3 op display 3.
Bedankt voor de vele hoogstwaarschijnlijk probleemoplossende reacties. Ik ga jullie suggesties onmiddellijk es proberen.
Een hardwaretest heb ik al es uitgeprobeerd. Het enige wat ik niet kan testen is of de transistoren zouden te traag zijn, maar dat denk ik niet, want met 2 displays lukt het wel.
Ik zie:
if shifter > 4 then
shifter = 1 ' prepare mask for digit
end if
if portc_index > 2 then
portc_index = 0 ' turn on 1st, turn off 2nd 7seg.
end ifHet is logischer om gewoon dit te doen:
if portc_index > 2 then
shifter = 1 ' prepare mask for digit
portc_index = 0 ' turn on 1st, turn off 2nd 7seg.
end if TMR0 = 0overbodig, het vertraagd het interrupt alleen maar. het interrupt it requested wanneer TMR0 al overflowde naar 0, en nu zet je hem even later weer op 0.
INTCON = $20Hoe kan dit ooit werken? Met dat commando zet je GIE uit. Ik zou doen:
INTCON.T0IF = 0of
LOW INTCON.T0IFafhankelijk van welke vasic je hebt (ik werk zelf niet met basic, dus kenners, klopt dit?)
Misschien niet de oplossing die je zoekt, maar wel wat pic basics om je vertrouwd te laten raken in basic
Ik heb nu het hele topic overlopen en alles geprobeerd wat jullie voorstelden, behalve de verversingsfrequentie (dus de interrupt) te verlagen. Ik ga direct nog es de info over timer0 en interrupts in de datasheet herlezen en trachten de frequentie te verlagen.
Werk je soms ergens met inverse logic?De 8 pinnen van poort c worden laag gezet om het overeenkomstige segment te laten oplichten. De displays zijn dus uiteraard common anode. De 3 transistoren (2N3906) worden aangestuurd via poort A, waarbij een logische 1 de transistor doet geleiden en dus de overeenkomstige digit activeert.
Zijn er nog suggesties om uit te proberen? Is er iemand die nog zijn hersenen es wil pijnigen en een verklaring zoeken waarom het wel lukt voor 2 displays en niet voor 3.
[Bericht gewijzigd door jefkeVV op (13%)]
Op 8 september 2008 12:22:59 schreef jefkeVV:
De 3 transistoren (2N3906) worden aangestuurd via poort A, waarbij een logische 1 de transistor doet geleiden en dus de overeenkomstige digit activeert.
Nee, dit zijn pnp transistoren, dus een logische nul doet de transistor geleiden.....
Zou het kunnen dat de het komt omdat de interne rc-oscillator wordt geberuikt ipv een extern kristal?
@zonnepaneeltje:
Het zijn idd pnp-transistoren. Ik sluit ze als volgt aan:
collector naar 5V, emittor naar common anode, basis naar uitgangspin pic. Maak ik de correcte uitganspin hoog, dan licht de overeenkomstige digit op.
Dit klopt toch, of niet?
[Bericht gewijzigd door jefkeVV op (56%)]
Nee, de emitter moet aan de 5V.
De basis via een weerstandje naar de pic.
Als je de poortpin laag maakt gaat het desbsteffende digit aan.
De door jou beschreven aansluiting kan wel, maar dan moet je een NPN tor nemen.
[Bericht gewijzigd door Zonnepaneeltje op (22%)]