Liste der Anhänge anzeigen (Anzahl: 3)
4x 7Segment mit multiplex und NUR 5 ausgängen
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.
Code:
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:
Code:
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