Problem med Timer1 och Output Compare --> ATmega88

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
BEEP
EF Sponsor
Inlägg: 1593
Blev medlem: 21 januari 2006, 16:57:56
Ort: Mölndal

Problem med Timer1 och Output Compare --> ATmega88

Inlägg av BEEP »

Jag sitter här och fipplar med min nyinköpta STK500 och har börjat med att skriva lite kod
för Timer/Counter1 i normal mode som fungerar i AVR Studio men inte på STK500.

Kod: Markera allt

Init_TC1:
	; Time
	ldi 	tmp, 	0x7F		
	sts 	OCR1AH, tmp
	ldi 	tmp, 	0xFF			
	sts 	OCR1AL, tmp
	
	; Set OC1A on Compare Match
	ldi 	tmp, 	0b11000000
	sts 	TCCR1A, tmp

	; Clock Select
	ldi 	tmp, 	0b00000011
	sts 	TCCR1B, tmp

Main:
	; om något sker hoppa till Test
	rjmp Main

Test: 
	; Stoppa T/C1
	clr	tmp,
	sts	TCCR1B,	tmp
	
	; Nolla T/C1
	clr		tmp
	sts		TCNT1H, tmp
	sts		TCNT1L, tmp

	; Nolla PORTB1
	???

	; Starta T/C1
	ldi		tmp,	0b00000011
	sts		TCCR1B,	tmp

	rjmp Main
Det jag försöker göra i Test loopen är:
1. Stoppa T/C1
2. Skriva in 0x0000 i TCNT för att få den att räkna ifrån början
3. Nollställa PORTB1
4. Starta T/C1

Vid uppstart av ATmega88 så är PORTB1 noll tills T/C1 har nått compare värdet och då aktiveras
PORTB1 som jag har tänkt men sedan vill jag kunna nolla PORTB1 och starta om T/C1 ifrån noll
igen men hur jag än skriver till registerna så förblir PORTB1 aktiverad.
Senast redigerad av BEEP 8 januari 2007, 11:57:37, redigerad totalt 3 gånger.
Användarvisningsbild
exile
EF Sponsor
Inlägg: 496
Blev medlem: 21 oktober 2005, 23:32:07

Inlägg av exile »

Jag för står inte riktigt vad du vill göra? (det är möljit att jag är lite trög)

1. Det saknas hel del code som typ stackintsering interuptvektorn,mm
2. När ska du slå på "portb"

och så ett lite tipps använd [code]-taggarna när du infogar code så är den lite lättare att läsa :)
Användarvisningsbild
BEEP
EF Sponsor
Inlägg: 1593
Blev medlem: 21 januari 2006, 16:57:56
Ort: Mölndal

Inlägg av BEEP »

Så här hade jag tänk mig att det skulle fungera:
1. Timer1 slår på PORTB1 när Timer1 når compare värdet och sedan är PORTB1 på hela tiden.
2. Timer1 fortsätter att gå men det spelar ingen roll.
3. När vissa kriterier i Main loopen är uppfyllda så hoppar programmet till Test loopen.
4. I Test loopen så stoppas Timer1 och nollställs(0x0000).
5. PORTB1 slås av.
6. Sedan så startas Timer1.
7. Åter till Main loopen.
8. Se punkt 1.

Kod: Markera allt

.INCLUDE "m88def.inc"

.def tmp = r16

.org 0x0000
rjmp	Reset			; Reset Handler
nop						; IRQ0 Handler
nop						; IRQ1 Handler
nop						; PCINT0 Handler
nop						; PCINT1 Handler
nop						; PCINT2 Handler
nop						; Watchdog Timer Handler
nop						; Timer2 Compare A Handler
nop						; Timer2 Compare B Handler
nop						; Timer2 Overflow Handler
nop						; Timer1 Capture Handler
nop						; Timer1 Compare A Handler
nop						; Timer1 Compare B Handler
nop						; Timer1 Overflow Handler
nop						; Timer0 Compare A Handler
nop						; Timer0 Compare B Handler
nop						; Timer0 Overflow Handler
nop						; SPI Transfer Complete Handler
nop						; USART, RX Complete Handler
nop						; USART, UDR Empty Handler
nop						; USART, TX Complete Handler
nop						; ADC Conversion Complete Handler
nop						; EEPROM Ready Handler
nop						; Analog Comparator Handler
nop						; 2-wire Serial Interface Handler
nop						; Store Program Memory Ready Handler ;0x019	

.org 0x001A
Reset:
	; Set up the stackpointer
	ldi	tmp,	HIGH(RAMEND)
	out	SPH,	tmp
	ldi	tmp,	LOW(RAMEND)
	out	SPL,	tmp
	SEI

Init_PORTB:
	ldi	tmp,	0b00000010
	out	DDRB,	tmp

Init_TIMER1:
	; Tid
	ldi 	tmp, 	0x7F		
	sts 	OCR1AH, tmp
	ldi 	tmp, 	0xFF			
	sts 	OCR1AL, tmp
	
	; Set OC1A on Compare Match
	ldi 	tmp, 	0b11000000
	sts 	TCCR1A, tmp

	; Clock Select - clkI/O/64 (From prescaler)
	ldi 	tmp, 	0b00000011
	sts 	TCCR1B, tmp

Main:
	om något sker här, så hoppa till Test loopen -->
	rjmp Main

Test:
	; Stoppa Timer1
	clr	tmp
	sts	TCCR1B,	tmp ; CS02,CS01,CS00 = 0 - No clock source(Timer/Counter stopped)

	; Nolla Timer1
	clr		tmp
	sts		TCNT1H, tmp
	sts		TCNT1L, tmp

	; Nolla Output Compare A Flagga - OCF1A
	sbi		TIFR1,	1

	; Slå av PORTB1
	--> HUR GÖR JAG FÖR ATT SLÅ AV PORTB1? <--

	; Starta Timer1 - clkI/O/64 (From prescaler)
	ldi	tmp,		0b00000011
	sts	TCCR1B,	tmp

	rjmp Main
"interuptvektorn,mm"
Interrupts och mm, hmmm... :oops: ska ta ta läsa lite mer om det i PDF filen när huvudvärken har släppt :shock:
Senast redigerad av BEEP 14 februari 2006, 12:42:00, redigerad totalt 4 gånger.
Kaggen
Inlägg: 432
Blev medlem: 29 januari 2005, 03:06:02

Inlägg av Kaggen »

BEEP: --> HUR GÖR JAG FÖR ATT SLÅ AV PORTB1? <--

Som när du slår på den, fast med en nolla i rätt position istället?

OBS! Nedanstående exempel sätter PB0 - PB7 till "0" också.

Kod: Markera allt

  ldi   tmp,   0b00000000 ; 00000000 istället för 00000010
  out   PORTB,   tmp
Användarvisningsbild
cykze
EF Sponsor
Inlägg: 1539
Blev medlem: 8 april 2004, 10:40:28
Ort: Uppsala

Inlägg av cykze »

Det är smidigare att använda cbi/sbi istället om det bara rör sig om en bit som ska ändras.

sbi PORTB, 1 ;gör PB1 hög
cbi PORTB, 1 ;gör PB1 låg

Tänk på att lysdioderna nog är kopplade "tvärtom" på STK500, så att en låg utsignal tänder lysdioden och tvärtom.
Användarvisningsbild
BEEP
EF Sponsor
Inlägg: 1593
Blev medlem: 21 januari 2006, 16:57:56
Ort: Mölndal

Inlägg av BEEP »

Jag tror att jag har hittat felet "I will be back" :twisted:
Användarvisningsbild
exile
EF Sponsor
Inlägg: 496
Blev medlem: 21 oktober 2005, 23:32:07

Inlägg av exile »

Du måste tala om var den ska hoppa till i interuptvektorn
exemple:

Kod: Markera allt

.include "m88def.inc"

.def tmp = r16 

.org 0x0000 
rjmp   Reset         ; Reset Handler 

;talar om vart den ska hoppa
.org 0x000B 
rjmp	test         ; Timer1 Compare A Handler 

Reset: 
   ; Set up the stackpointer 
   ldi   tmp,   HIGH(RAMEND) 
   out   SPH,   tmp 
   ldi   tmp,   LOW(RAMEND) 
   out   SPL,   tmp 

Init_PORTB: 
   ldi   tmp,   0b00000010 
   out   DDRB,   tmp 

Init_TIMER1: 
   ; Tid 
   ldi	tmp,    0x7F       
   sts	OCR1AH, tmp 
   ldi	tmp,    0xFF          
   sts	OCR1AL, tmp 
    
   ; Set OC1A on Compare Match 
   ldi    tmp,    0b11000000 
   sts    TCCR1A, tmp 

   ; Clock Select - clkI/O/64 (From prescaler) cler on match
   ldi    tmp,    0b00001011 
   sts    TCCR1B, tmp

   
   ldi	tmp,	0b00000010
   sts	TIMSK1,	tmp
    
   ;Enablar interupt
   sei

Main: 
   ;loop for ever
   rjmp Main 

Test: 
   ; Slå av PORTB1 
   in	tmp,	PINB	;läser PORB B
   com	tmp				;inverterar
   out	PORTB,	tmp		;skriver ut till PORTB
   reti
   ;hoppar till baka där den kom ifrån
sts och out är ungefär samma instruktion men out går fortare att utföra men har ett begränsat område som den kan addressera....
Användarvisningsbild
BEEP
EF Sponsor
Inlägg: 1593
Blev medlem: 21 januari 2006, 16:57:56
Ort: Mölndal

Inlägg av BEEP »

Tackar för all hjälp men själva problemet är att jag vill sätta PORTB-1 till 0.

Så här fungerar det när jag sätter på ATmega88:

1. Sätter PORTB-1 till utgång
2. Skriver comparevärdet till Timer1
3. Talar om för Timer1 att den ska sätta PORTB-1 till 1 när den når comparevärdet.
4. Sätter prescalern
5. När Timer1 når comparevärdet så blir PORTB-1 = 1(ska egentligen inte ha någon puls i uppstarten men just nu så är detta bra för då kan jag se att Timer1 jobbar och aktiverar PORTB-1).
6. Main loppen körs tills någon kod i den exekveras och går då till Test loopen.
7. I Test loopen så stoppar jag Timer1 och försöker att sätta PORTB-1 till 0.


Jag låter nu bli att starta upp Timer1 i Test loopen och försöker bara att få PORTB-1 = 0.

Kod: Markera allt

.INCLUDE "m88def.inc"

.def tmp = r16

.org 0x0000
rjmp 	Reset						; Reset Handler	

.org 0x001A
Reset:

Init_PORTB:
	ldi		tmp, 	0b00000010 	
	out		DDRB, 	tmp 

Init_TIMER1:
	; Tid
	ldi		tmp,	0x00     
	sts		OCR1AH,	tmp
	ldi		tmp,	0x05         
	sts		OCR1AL,	tmp

	; Set OC1A on Compare Match
	ldi		tmp,	0b01000000
	sts		TCCR1A,	tmp

   ; Clock Select - clkI/O/64 (From prescaler)
   ldi    tmp,    0b00000011
   sts    TCCR1B, tmp

Main:
	; OBS! Main loopen väntar inte på att få hoppa till interuptvektorn!

	En hel hög med fulkod :-) -----------------------------
	-------------------------------------------------------
	-------------------------------------------------------

	Om något sker här så hoppa till Test loopen ---------->

	Mera fulkod--------------------------------------------
	--------------------------------------------------- osv

	rjmp	Main

Test:
	; Stoppa Timer1
	clr   tmp
	sts   TCCR1B,   tmp ; CS02,CS01,CS00 = 0 - No clock source(Timer/Counter stopped)

	; Nolla Timer1
	clr		tmp
	sts		TCNT1H, tmp
	sts		TCNT1L, tmp

	; Nolla Output Compare A Flagga - OCF1A
	sbi		TIFR1,	1

	; Slå av PORTB-1
	;--> HUR GÖR JAG FÖR ATT SLÅ AV PORTB-1? <--
	; OBS! sbi, cbi, sts och out funkar inte!

	; Jag låter bli att starta Timer1, försöker tills vidare att lösa problemet
	: med att hur jag ska göra för att få PORTB-1 = 0.
	; Starta Timer1 - clkI/O/64 (From prescaler)
	;ldi		tmp,	0b00000011
	;sts		TCCR1B,	tmp

	rjmp Main 
Senast redigerad av BEEP 14 februari 2006, 20:46:03, redigerad totalt 4 gånger.
Användarvisningsbild
exile
EF Sponsor
Inlägg: 496
Blev medlem: 21 oktober 2005, 23:32:07

Inlägg av exile »

Jaha (lite trög fattad) du vill stänga av PINB1 som är kopplat till timmer1
Testa det här, jag tror att det fungerar :)

Kod: Markera allt

   ldi	tmp,	0b10000000
   sts  TCCR1A,	tmp
   sts	TCCR1C,	tmp
   ldi	tmp,	0b11000000
   sts	TCCR1A,	tmp
Användarvisningsbild
BEEP
EF Sponsor
Inlägg: 1593
Blev medlem: 21 januari 2006, 16:57:56
Ort: Mölndal

Inlägg av BEEP »

DET FUNKAR :) (är lycklig och dansar en krigsdans runt STK500an).

Jag har tidigare försökt att använda TCCR1A och TCCR1C men fick inte det till att fungera så du ska ha JÄTTE MYCKET TACK exile.
Senast redigerad av BEEP 14 februari 2006, 20:37:28, redigerad totalt 1 gång.
Användarvisningsbild
exile
EF Sponsor
Inlägg: 496
Blev medlem: 21 oktober 2005, 23:32:07

Inlägg av exile »

Tack, det är alltigt roligt att kunna hjälpa :)
Skriv svar