PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : 4x 7Segment mit multiplex und NUR 5 ausgängen



tristate
09.11.2005, 17:44
So hab mal wieder n paar fragen:
ich möchte wie der titel ja schon sagt eine 4 stellige 7 segment anzeige mittels multiplexverfahren ansteuern.
hab jetzt schon ziemlich viel darüber gelesen aber das beste beispiel ist glaub ich das in den sampels von proteus.

Tiny 15 - Test of ADC - also include multiplex display driver.

; Specify Device.
.device ATTINY15

; I/O Register Definitions
.equ SREG =$3F
.equ GIMSK =$3B
.equ GIFR =$3A
.equ TIMSK =$39
.equ TIFR =$38
.equ MCUCR =$35
.equ TCCR0 =$33
.equ TCNT0 =$32
.equ TCCR1 =$30
.equ TCNT1 =$2F
.equ OCR1A =$2E
.equ OCR1B =$2D
.equ PORTB =$18
.equ DDRB =$17
.equ ACSR =$08
.equ ADMUX =$07
.equ ADCSR =$06
.equ ADCH =$05
.equ ADCL =$04

; Variable Declarations
.def temp = r16
.def isrsreg = r18
.def isrtemp1 = r19
.def isrtemp2 = r20
.def cseg = r21
.def seg0 = r22
.def seg1 = r23
.def seg2 = r24
.def seg3 = r25

.cseg ; CODE segment.

;Interrupt Vectors
.org 0
rjmp init ;Reset
reti ;INT 0
reti ;Pin Change
reti ;Output compare
reti ;Timer 1
rjmp tov0 ;Timer 0
reti ;EEPROM ready
reti ;Analog Comparator
reti ;ADC Complete

;Initialization
init: ldi r16,$1F ; 5 bits are outputs
out DDRB,r16 ; set portb bit 0 for outputs to display
ldi r16,3 ; Timer 0 rolls over at 1.6MHz/256/64 = 97Hz
out TCCR0,r16
ldi r16,$02 ; Enable TOVF0
out TIMSK,r16
ldi cseg,$01 ; Start at segment
sei ; Enable Interrupts

ldi r16,$8E ; Enable, ADIE, Prescale = 1/64
out ADCSR,r16
ldi r16,0 ; Select ADC0 as input, VCC as VREF
out ADMUX,r16

loop: ldi r16,$20 ; Sleep enable, idling mode
out MCUCR,r16
sleep ; Wait for a timer 0 interrupt
cpi cseg,8 ; Wait for write to MS segment
breq loop

ldi r16,$28 ; Sleep enable, ADC low noise mode
out MCUCR,r16
sleep ; Wait for ADC to convert

in r0,ADCL ; Read the converted value
in r1,ADCH

;Convert and display value for output
;Start value taken to be in r1:r0
clr r4 ;Count result
dc1a: mov r2,r0 ;Subtract 1000's
mov r3,r1
ldi r16,$e8
sub r2,r16
ldi r16,$3
sbc r3,r16
brcs dc1b
inc r4
mov r0,r2
mov r1,r3
rjmp dc1a ; Go again
dc1b: mov seg0,r4 ; Store result

clr r4
dc2a: mov r2,r0 ;Subtract 100's
mov r3,r1
ldi r16,100
sub r2,r16
clr r16
sbc r3,r16
brcs dc2b
inc r4
mov r0,r2
mov r1,r3
rjmp dc2a ; Go again
dc2b: mov seg1,r4 ; Store result

clr r4
dc3a: mov r2,r0 ;Subtract 10's
ldi r16,10
sub r2,r16
brcs dc3b
inc r4
mov r0,r2
rjmp dc3a ; Go again
dc3b: mov seg2,r4 ; Store result

mov seg3,r0 ; The units are trivial


rjmp loop ; Go again


;Timer 0 interrupt - display driver
tov0: in isrsreg,SREG ; Preserver sreg

clr isrtemp1 ; Blank the display
out PORTB,isrtemp1

lsr cseg ; Advance segment selector address
brcc tov0_1
ldi cseg,0x08 ; Reset to seg 3
tov0_1: out PORTB,cseg ; Drive the latch

sbrc cseg,3 ; Select byte to output
mov isrtemp1,seg3
sbrc cseg,2
mov isrtemp1,seg2
sbrc cseg,1
mov isrtemp1,seg1
sbrc cseg,0
mov isrtemp1,seg0

ldi isrtemp2,$10 ;Bit 4 is set to enable the 7447
or isrtemp1,isrtemp2

sbi PORTB,4 ;Pre Assert PB4
out PORTB,isrtemp1 ;Drive the segment value onto the display

out SREG,isrsreg
reti
hier wird das eigentliche "datensignal" und die auswahl der anzeige mit nur 5 pins erreicht dh datensignal und steuersignal sind gemischt. Dementsprechend find ich die programmierung schwierig.
kann mir mal irgendjemand den asm code in verständliches C übersetzen?
oder mir verständlich machen wie ich dieses "muster" ausgebe?
im anhang seht ihr das datensignal wenn 0001 ausgegeben wird(von oben: PINB0 , PINB1 , PINB2 , PINB3 , dann 3 pins des signals hinterm d-flipflop, und PINB4 also clock)
so hab da mal angefangen nen code zammen zu basteln und zwar gehts mir um die erste ziffer also hier mal das ganze um eine 0 zu übertragen:


include <stdio.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include <math.h>
#include <avr/delay.h>

int main(void);
char Convert2PacketBCD(char value);

SIGNAL (SIG_OUTPUT_COMPARE0)
{
char temp1;
PORTB=0b00000000;
PORTB=0b10000001;
temp1=Convert2PacketBCD(0x00);
temp1&=0x0F;
temp1|=0b10000000;
PORTB = temp1;


}

char Convert2PacketBCD(char value)
{
unsigned char result;

result = value % 10;
result += (value - result)/10 * 0x10;

return result;
}

int main(void) {








DDRB =0xff;
PORTB=0x00;

TCCR0= 0x02;
TIMSK=0x02;
sei();
while (1) {

}
return 0;
}
dann sieht das ganze allerdings so aus wie im mylogic.jpg
wieso bekomme ich innerhalb der int routine schon 2 pulse??? also ganz unten ist mein clock. naja bekomm zwar ne null allerdings auch noch ne 1 wegen den pulsen
na bin für jede menge anregungen dankbar
antworten kann ich heut leider nicht mehr höchstens zu später stunde..
mfg

SprinterSB
10.11.2005, 12:17
hier wird das eigentliche "datensignal" und die auswahl der anzeige mit nur 5 pins erreicht dh datensignal und steuersignal sind gemischt. Dementsprechend find ich die programmierung schwierig.
kann mir mal irgendjemand den asm code in verständliches C übersetzen?
oder mir verständlich machen wie ich dieses "muster" ausgebe?
Das asm nach C zu 'übersetzen' und aufzudröseln ist IMHO mehr Arbeit als sich anzuschauen, welche Signale die Schaltung haben will und ihr diese zu geben.

B4 wählt aus zwischen 174 (D-Latch) und 47 (DCB-Dekoder/LED-Treiber). Die einzelnen Displays sind mit gemeinsamer Anode wie's aussieht. Der 174 geht wohl weiter zu 4 Anodentreibern.

Je nach B4 landen die Daten B0 bis B3 einmal direkt am 47 und einmal an dein Eingängen des 174.

Beim Wegschalten vom 174 zum 47 gibt's ne Flanke am 174.CLK und die 4 Bits werden in dessen Latches übernommen.

Gleichzeitig ist der 47 OFF so daß am Display nix zuckelt. Ist der 47 aktiv, dann dat der 174 seine Daten im Latch und wird durch die am Eingang anliegenden Werte nicht behelligt.

That's it.

An den 47 legst du den anzuzeigenden Wert und an den 174 welches Display jeweils diesen Wert zeigen soll.

tristate
12.11.2005, 16:35
ja war gar ned so schwer :wink: habs zwar n bissl anders gelöst als die das im assembler gemacht haben aber es funzt auch so..
mfg