Viene visualizzato il passaggio dei secondi su due display 7-segmenti, mente il punto di uno dei display rimane acceso per 1/2 secondo e spento per il successivo;
Il passaggio dei secondi è scandito dal Timer1 in Modalità CTC, quando viene raggiunto il massimo valore viene generato l'interrupt;
Si vuole inoltre che ogni 60 secondi il conteggio si azzeri (viene visualizzato fino a 59)
codice assembly:
- Codice: Seleziona tutto
;*************************************
;written by: Antonio Cittadino
;date:
;version:
;file saved as: Clock1
;for AVR: Atmega8535
;clock frequency 4MHz
;*************************************
.nolist
.include "m8535def.inc"
.list
;===============
;Declaretion:
.def temp=R16
.def seconds=R17
.def tens=R18
.def ones=R19
.def displayNumber=R22
.def displayCounter=R23
.def halfSecond=R24
;================
;Interrupt Vector
rjmp Init
reti
reti
reti
reti
reti
rjmp TIM1_COMPA
reti
reti
reti
reti
reti
reti
reti
reti ;0x00E "ADC" ADC Conversion Complete Handler
reti ;0x00F "EE_RDY" EEPROM Ready Handler
reti ;0x010 "ANA_COMP" Analog Comparator Handler
reti ;0x011 "TWSI" Two-wire Serial Interface Handler
reti ;0x012 "EXT_INT2" IRQ2 Handler
reti ;0x013 "TIM0_COMP" Timer0 Compare Handler
reti ;0x014 "SPM_RDY" Store Program Memory Ready Handler
;=================
;Start the program:
rjmp Init
;===============
Init:
ldi temp,high(RAMEND) ; Main program start
out SPH,temp ; Set Stack Pointer to top of RAM
ldi temp,low(RAMEND)
out SPL,temp
sei ; Enable interrupts
;Output/Input
ser temp
out DDRB,temp ;PB0:6 output (SEG, Diasplay7-seg), rest NC
out DDRC,temp ;PC2,3 output (K, select Display), rest NC
;PC2=Dis3 PC3=Dis4
clr temp
out DDRD,temp ;PD1:3 output, rest NC
;PD2=UP, PD3=DOWN
;Pull-up resitor
ldi temp,0b00001100;PD2,3 pull-up resistor
out PortD,temp
;Look-Up Table
ldi temp,0b00111111
mov R0,temp ;number0
ldi temp,0b00001001
mov R1,temp ;numerb1
ldi temp,0b01011110
mov R2,temp
ldi temp,0b01011011
mov R3,temp
ldi temp,0b01101001
mov R4,temp
ldi temp,0b01110011
mov R5,temp
ldi temp,0b01110111
mov R6,temp
ldi temp,0b00011001
mov R7,temp
ldi temp,0b01111111
mov R8,temp
ldi temp,0b01111011
mov R9,temp
;initial condition register
clr tens
clr ones
ldi displayCounter,50
clr displayNumber
clr halfSecond
clr seconds
clr ZH
;initial condition I/O register
;starting by selecting Display3
ldi temp,0b00000100
out PortC,temp
rjmp Start
;===============
;Subroutines
;HalfSecond passed ISR
TIM1_COMPA:
push temp
in temp,SREG
push temp
;____________
inc halfSecond
cpi halfSecond,2
breq passed1s
sbi PortA,6 ;turn ON DotDIS3
pop temp
out SREG,temp
pop temp
reti
passed1s:
cpi seconds,60
brne PC+2
clr seconds
cbi PortA,6 ;turn OFF DotDIS3
clr halfSecond
inc seconds
pop temp
out SREG,temp
pop temp
reti
;__________________________________________________________________________________________
Display:
;NOTE: tens,ones are "digitConvert" of "second"
;How made (indirecting address):
;"first lap" (after 50 dec), DN=0,DN-2!=0, ZL=18+0=R18(point tens), DN=0+1=1
;"second lap" (other 50 dec) DN=1, DN-2!=0 ,ZL=18+1=19( point ones), DN=1+1=2
;"third lap" (other 50 dec) DN=2, DN-2=0--> clr DN=0, ZL=18+0 (point again tens)
dec displayCounter
breq PC+2
ret
ldi displayCounter,50
cpi displayNumber,2
brne PC+2 ;if DisplayNumber-2!=0 -->PC+2
clr displayNumber
;indirecting address, Z will point always tens or ones
ldi ZL,18
add ZL,displayNumber
ld temp, Z
clr ZL
add ZL,temp
ld temp,Z
;PortB-->Tens-->DIS4 selected(by multiplexing) PortB-->Ones--->DIS3 selected(by multiplexing)
out PortB,temp
inc displayNumber
;Multiplexing
;NOTE: initial condition DIS3 selected (from initi section)
in temp,PinC
lsl temp
sbrc temp,4
ldi temp,0b00000100
;"fisrt lap" lsl selecting DIS4
;"second lap" return to initial condition (selecting DIS3)
out PortC,temp
ret
;____________________________________________________________________________________________
DigitConvert:
clr tens
clr ones
FindTens:
subi seconds,10
brcs FindOnes
inc tens
rjmp FindTens
FindOnes:
subi seconds,-10
mov ones,seconds
ret
;===============
;Main body of program:
Start:
;NOTE there is a correct way to access a 16bit I/O register
;write: 1st-High byte 2nd-Low byte
;read: 1st-Low byte 2nd-High byte
ldi temp, (1<<CS10)|(1<<CS11)|(1<<WGM12) ;CLK(I/O)/64 and CTC
out TCCR1B,temp
;MaxValue 31250(f=4Hz prs=64)0x7A12 , halfsecond passed
ldi temp,0x7A
out OCR1AH,temp
ldi temp,0x12
out OCR1AL,temp
;Timer/counter1 output compare match A enable interrupt
;this interrupt is enabled if Iflag in SREG in set ("sei" enable global interrupt)
;and bit4 of TIMSK is set (OCIE1A)
ldi temp, 1<<OCIE1A
out TIMSK,temp
Loop:
rcall DigitConvert
rcall Display
rjmp Loop
posto anche il video per far capire cosa non funziona
[url][/url]
per intenderci il DISPLAY4 è quello delle Decine (a SX) mentre il DISPLAY3 è quello delle unità a DX
Come si vede dal video non vengono incrementati le decine, penso sia un problema dovuto al multiplexing poiché ho simulato il programma su AVRstudio e funziona.
Inoltre, Il punto lampeggia, ma è veramente poco luminoso, c'è da dire che le prime volte che ho provato il programma l'intensità luminosa era la stessa dei segmenti, poi ho modificato alcune cose, salvato, ed ora è cosi, non è il display perché ho provato a scambiarli e non cambia nulla, cosa potrebbe essere?
Flowchart:

Elettrotecnica e non solo (admin)
Un gatto tra gli elettroni (IsidoroKZ)
Esperienza e simulazioni (g.schgor)
Moleskine di un idraulico (RenzoDF)
Il Blog di ElectroYou (webmaster)
Idee microcontrollate (TardoFreak)
PICcoli grandi PICMicro (Paolino)
Il blog elettrico di carloc (carloc)
DirtEYblooog (dirtydeeds)
Di tutto... un po' (jordan20)
AK47 (lillo)
Esperienze elettroniche (marco438)
Telecomunicazioni musicali (clavicordo)
Automazione ed Elettronica (gustavo)
Direttive per la sicurezza (ErnestoCappelletti)
EYnfo dall'Alaska (mir)
Apriamo il quadro! (attilio)
H7-25 (asdf)
Passione Elettrica (massimob)
Elettroni a spasso (guidob)
Bloguerra (guerra)


, la luminosità dei LED/segmenti del display è invece proporzionale ad una corrente
.

