Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

AT90USB162 timer interupt svakih 0.1ms?

[es] :: Elektronika :: Mikrokontroleri :: AT90USB162 timer interupt svakih 0.1ms?

Strane: 1 2

[ Pregleda: 4731 | Odgovora: 22 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

endre85

Član broj: 207893
Poruke: 325



+116 Profil

icon AT90USB162 timer interupt svakih 0.1ms?08.09.2011. u 12:29 - pre 153 meseci
Da li neko zna objasniti kako u mikroC PRO for AVR napraviti da se desi prekid svakih 0.1ms ili svakih 0.01ms, ili da mozda da linkove ka nekim dobrim tutorialima? Kristal je na 8MHz.
 
Odgovor na temu

shpiki
Student
Novi Sad

Član broj: 50342
Poruke: 1651



+62 Profil

icon Re: AT90USB162 timer interupt svakih 0.1ms?08.09.2011. u 14:14 - pre 153 meseci
Napravis tajmerski interapt (googlaj Timer0/1/2/etc interrupt [hint]), inicijalna vrednost tajmera se izracuvana u zavisnosti od kristala (googlaj AVR Timer0 calculator [hint]), ostalo ce ti se samo kaz'ti! Ako i dalje budes "zapinjao", javi se...

Pozdrav!
There are only 10 types of people in the world:
those who understand binary, and those who don't.
 
Odgovor na temu

endre85

Član broj: 207893
Poruke: 325



+116 Profil

icon Re: AT90USB162 timer interrupt svakih 0.1ms?09.09.2011. u 12:38 - pre 153 meseci
Hvala na odgovoru. Nazalost juce nisam stigao da radim na ovome. Sad cu da procitam taj pdf koji si linkovao i jos neke linkove koje sam ja nasao da prelistam. U medjuvremenu imam par pitanja. Ako bih zeleo da generisem interapt svakih 0.01 usec tada bi zaokruzena podesavanja sa prilozene slike odradile posao?


I generalno to su vrednosti koje bih trebao upisati u odredjene registre?

Pitanje broj dva: Sa podesavanjima na prilozenoj slici timer bi odbrojao od 0 do 255 za 0.01 usec (sa greskom od 99,96%)?

EDIT:

I to bi sve trebalo da izgleda otprilike ovako:

Code:
void Timer0Overflow_ISR() org IVT_ADDR_TIMER0_OVF 
{
//radi nesto tokom prekida
}

void main() 
{

  DDRD   =  0xFF;               // set PORTD as output
  PORTD  =  0;                  

  SREG_I_bit = 1;               // Interrupt enable 
        //ili, moze i ovako:
       //SREG |= 0x80;              // enable global interrupt 
 
  TOIE0_bit  = 1;               // Timer0 overflow interrupt enable
     //da li ovo dovodi do istog rezultata:
     //TIMSK0=0x01;          // enable timer0 for overflow interrupt mode


  TCCR0 = 5;                    // Start timer with 128 prescaler
 //u vezi prescalera pitanje ide u sledecoj poruci!


 //da li ovde ide nesto od sledeca dva reda:
  //#asm("sei")
  //sei();


  while (1)                     // Endless loop, port is changed inside Interrupt Service Routine (ISR)
    ;
}





[Ovu poruku je menjao endre85 dana 09.09.2011. u 14:36 GMT+1]
 
Odgovor na temu

endre85

Član broj: 207893
Poruke: 325



+116 Profil

icon Re: AT90USB162 timer interupt svakih 0.1ms?09.09.2011. u 13:26 - pre 153 meseci
Razdvojio bih poruke radi lakseg pregleda. U primerima koje imam za podesavanje prescalera koristi se TCCRO. Iako mikroC za AT90USB162 prihvata naredbu TCCROA ili TCCROB, meni pretraga pdf-a uC-a ne daje nikakve rezultate, vec predpostavljam da se prescaler podesava pomocu CLKPR. E sad tu imam pitanje. Kaze ovako:

i ovako:


Sta to tacno znaci? Da ja moram prvo da upisem 0b10000000 u registar da bih mogao da odaberem odgovarajuci prescaler,pa posle upisujem npr 0x08 za 256 vrednost?! Ili mogu odmah da upisujem 0b10001000?
 
Odgovor na temu

Genie_1984
Novi Sad

Član broj: 61150
Poruke: 93



+1 Profil

icon Re: AT90USB162 timer interupt svakih 0.1ms?09.09.2011. u 13:48 - pre 153 meseci
Registrom CLKPR podešavaš radni takt celog uC-a...tebi treba prescaler Timer-a,to ti se nalazi na strani 103/104 (table 14-9) tj registar TCCR0B
Ne možeš nikako da postigneš interapt na svakih 0.01uS(osim ako nisi greškom u postu napisao 0.01uSec umesto 0.01mS koji se može postići)....bar ne sa kristalom od 8Mhz...

A što se tiče pitanja za registre upisuješ sve zajedno,ne pojedinačno.

Za početak ti je bolje da uzmeš neki kompajler koji ima Code Wizard (npr CodeVisionAVR)
 
Odgovor na temu

endre85

Član broj: 207893
Poruke: 325



+116 Profil

icon Re: AT90USB162 timer interupt svakih 0.1ms?09.09.2011. u 14:14 - pre 153 meseci
Hvala. Sad sam nasao TCCR0. Pa jel mogu onda da postignem interapt svakih 0.1us? Kao ovde, ili da pokusam prevesti/prilagoditi neki od sledecih kodova za upravljanje servo motorima koje sam dobio (doduse oni rade na 16MHz):

Code:

/*****************************************************
This program was produced by the
CodeWizardAVR V2.03.4 Standard
Automatic Program Generator
© Copyright 1998-2008 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com

Project : 
Version : 
Date    : 5/10/2011
Author  : 
Company : 
Comments: 


Chip type           : ATmega88
Program type        : Application
Clock frequency     : 16.000000 MHz
Memory model        : Small
External RAM size   : 0
Data Stack size     : 256
*****************************************************/

#include <mega88.h>
#include <stdio.h>
#include <delay.h>

#define PL   PORTD.5
#define PD   PORTD.6
#define ZL   PORTB.1
#define ZD   PORTB.2

#define UL_P0 PINC.0
#define UL_P1 PINC.1

#define UL_Z0 PINC.2
#define UL_Z1 PINC.3



int i;
volatile int prednja_levo, prednja_desno, zadnja_levo, zadnja_desno;



// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
// Reinitialize Timer 0 value
TCNT0=0xEC;
// Place your code here

i++;

if (i>=2000) i=0;

if (i<=prednja_levo) PL=1;
else PL=0;

if (i<=prednja_desno) PD=1;
else PD=0;

if (i<=zadnja_levo) ZL=1;
else ZL=0;

if (i<=zadnja_desno) ZD=1;
else ZD=0;




}

// Declare your global variables here

void main(void)
{
// Declare your local variables here

// Crystal Oscillator division factor: 1
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif

// Input/Output Ports initialization
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=Out Func1=Out Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=0 State1=0 State0=T 
PORTB=0x00;
DDRB=0x06; //DDR -> Data Direction register
           //Ako sam dobro shvatio kada upisemo jedan pin je izlaz, a kada upisemo nula pin je ulaz
           //written logic one, the pin is output pin
           

// Port C initialization
// Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTC=0b00001111;
DDRC=0x00;

// Port D initialization
// Func7=In Func6=Out Func5=Out Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=0 State5=0 State4=T State3=T State2=T State1=T State0=T 
PORTD=0x00;
DDRD=0x60;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 2000.000 kHz
// Mode: Normal top=FFh
// OC0A output: Disconnected
// OC0B output: Disconnected
TCCR0A=0x00;
TCCR0B=0x02;
TCNT0=0xEC;
OCR0A=0x00;
OCR0B=0x00;

// Timer/Counter 0 Interrupt(s) initialization
TIMSK0=0x01;
// Timer/Counter 1 Interrupt(s) initialization
TIMSK1=0x00;
// Timer/Counter 2 Interrupt(s) initialization
TIMSK2=0x00;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
ADCSRB=0x00;

// Global enable interrupts
#asm("sei")
               
while (1)
      {
      
                 ////////////
                 ///ZADNJA///
                 ////////////
      if (UL_Z0 && !UL_Z1 )           //2 I 3
       {                        //otvorena
                    zadnja_levo=80;
                    zadnja_desno=80;
       }
      else if(!UL_Z0 && UL_Z1)
       {                        //zatvorena
                    zadnja_levo=100;
                    zadnja_desno=110;
       }
      else if(!UL_Z0 && !UL_Z1)
       {                           //pocetna
                  zadnja_levo=80;          //150
                  zadnja_desno=80;         //150
       }
      
                   ////////////
                   ///PREDNJA//
                   ////////////
                   
       if(UL_P0 && !UL_P1) // 0 I 1
       {                //otvorena
             prednja_levo=80 ; 
             prednja_desno=80 ;        
       }
       else if(!UL_P0 && UL_P1)
       {                 //zatvorena
              prednja_levo=130 ; 
              prednja_desno=95 ;         
       }
       
       else  if  (!UL_P0 && !UL_P1 )                    //pocetna
       {              
              prednja_levo=140;
              prednja_desno=145;
       }
       
       
    };
}
}




Code:

/*****************************************************
This program was produced by the
CodeWizardAVR V2.05.3a Evaluation
Automatic Program Generator
© Copyright 1998-2011 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com

Project : 
Version : 
Date    : 25-Aug-2011
Author  : Freeware, for evaluation and
non-commercial use only
Company : 
Comments: 


Chip type               : ATmega88
Program type            : Application
AVR Core Clock frequency: 16.000000 MHz
Memory model            : Small
External RAM size       : 0
Data Stack size         : 256
*****************************************************/

#include <mega88.h>
#include <stdio.h>
#include <delay.h>

#define S1               PORTD.6                // izlaz za servo motor
#define S2               PORTD.5  

// Deklarišite vaše globalne promenljive ovde

int i, m,k;
volatile int SER_1, SER_2, tast_1,tast_2, tast_3,tast_4;
volatile unsigned char stanjetastera[3];
volatile unsigned char br_citanja;
// Prekidna servisna rutina tajmera 0
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
// Reinicijalizujte vrednost tajmera 0
TCNT0=0xEC;

i++;    
                        // inkrementiranje brojaca
if (i>=2000) i=0;                    // ukoliko je izbrojao do 20ms - reset brojaca
if (i<=SER_1) S1=1;                    // trajanje signala za kretanje motora
else S1=0;

if (i<=SER_2) S2=1;                    // trajanje signala za kretanje motora
else S2=0;                

k++;
if(k==100)
{
    
    k=0;//1ms   

    stanjetastera[br_citanja]=PINC&0x0f; 
    br_citanja++;
 
    if(br_citanja==3) //3ms
    {
        br_citanja=0;    
        if((stanjetastera[0]==stanjetastera[1]))
        {   
            if((stanjetastera[1]==stanjetastera[2]))
            {
               if(stanjetastera[0]&0x01)
                {
                    tast_3=1;
                }            
                else
                {
                    tast_3=0;
                }
               if(stanjetastera[0]&0x02)
                {
                    tast_4=1;
                }            
                else
                {
                    tast_4=0;
                }   
                         
               if(stanjetastera[0]&0x04)
                {
                    tast_3=1;
                }            
                else
                {
                    tast_3=0;
                }
               if(stanjetastera[0]&0x08)
                {
                    tast_4=1;
                }            
                else
                {
                    tast_4=0;
                } 
            }         
              
        }
    } 
}

}

void main(void)
{
// Deklarišite vaše lokalne promenljive ovde
m=0;
stanjetastera[0]=0;
stanjetastera[1]=0;
stanjetastera[2]=0;
br_citanja=0;

// Faktor deljenja kristalnog oscilatora: 1
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif

// Inicijalizacija ulazno/izlaznih portova
// Inicijalizacija Porta C
// Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTC=0x0f;
DDRC=0x00;

// Inicijalizacija Porta D 
// Func7=In Func6=Out Func5=Out Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=0 State5=0 State4=T State3=T State2=T State1=T State0=T 
PORTD=0x00;
DDRD=0x60;

// Inicijalizacija tajmera/brojaca 0
TCCR0A=0x00;
TCCR0B=0x02;
TCNT0=0xEC;
OCR0A=0x00;
OCR0B=0x00;
// Inicijalizacija prekida tajmera/brojaca 0
TIMSK0=0x01;
tast_1=0;
tast_2=0;
tast_3=0;
tast_4=0;

// Globalna dozvola prekida
#asm("sei")  
   
 while(1)
 {
     if(tast_1)
    {   
     SER_1=50;     
    }   
    if(tast_2)
    {   
     SER_1=150;     
    }   
                
    if(tast_3)
    {   
     SER_2=50;     
    }   
    if(tast_4)
    {   
     SER_2=150;     
    }    
 }        
}







Sad gledam CVavr, jel taj code wizard neki debuger/simulator?



[Ovu poruku je menjao endre85 dana 09.09.2011. u 15:24 GMT+1]
 
Odgovor na temu

Genie_1984
Novi Sad

Član broj: 61150
Poruke: 93



+1 Profil

icon Re: AT90USB162 timer interupt svakih 0.1ms?09.09.2011. u 15:24 - pre 153 meseci
Sa 8Mhz ne može ni 0.1uS
U ovim primerima što si postavio sa kristalom od 16Mhz, preskalerom 1/8 Fcpu (TCCR0B=0x02) i brojačem podešenim da broji od 0xEC (TCNT0=0xEC;) prekid se dešava svakih 10uS (0.00001 sek)

Ako bi hteo da bude kristal 8Mhz,prescaler da ostane isti (TCCR0B=0x02) brojač treba da broji od 0xF6 (TCNT0=0xF6)



code wizard je program koji ti pomaže oko postavljanja vrednosti registra za željenje opcije (ADC,prekide,portove i sl.) uglavnom su u sklopu kompajlera (kao što je CodeWizardAVR deo CodeVisionAVR) i generišu početni kod za taj kompajler. imaš ga npr i u sklopu AtmanAvr IDE-a za AVRGCC.




 
Odgovor na temu

endre85

Član broj: 207893
Poruke: 325



+116 Profil

icon Re: AT90USB162 timer interupt svakih 0.1ms?09.09.2011. u 15:49 - pre 153 meseci
Bio si u pravu prvi put. Sad gledam timing dijagrame servo motora i ne znam zasto sam se uhvatio za mikro sekunde, kad mi mili sekundi obavljaju posao. Servo radi na frekvenciji od 50 Hz , tj. 20msec.

Meni je potreban interapt svakih 0.1 msec ili svakih 0.01 msec. Jos jednom izvinjavam vam se sto sam forsirao pogresno.

EDIT: Da, 10 [usec] mi treba za vecu rezoluciju a ne 0.01 [usec]. Kako sam samo permutovao... Sramota me da pogledam sebe u ogledalo. I da u primerima koje sam postavio oni generisu prekid na 0.01 msec i brojac broji do 2000, a u primeru sa PIC uC broje do 200 sa prekidima na 0.1msec.

EDIT2:Sad sam proverio vrednosti primera u calculatoru:

TCNT0=0xEC je potvrdjeno

Meni sad calculator za svaki prescaler <=16 daje gresku 0% . Evo primera sa prescalerom 8:

Drago mi je da smo ovo rascistili. Sto se tice performansi jer odabran prescaler igra neku ulogu? U smilsu da li je bolje da postavim na 2 ili npr 8?

[Ovu poruku je menjao endre85 dana 09.09.2011. u 17:16 GMT+1]

Jel mi treba u telo programa:
// Global enable interrupts
//#asm("sei")
//ili
//sei();



[Ovu poruku je menjao endre85 dana 09.09.2011. u 17:32 GMT+1]
 
Odgovor na temu

Genie_1984
Novi Sad

Član broj: 61150
Poruke: 93



+1 Profil

icon Re: AT90USB162 timer interupt svakih 0.1ms?09.09.2011. u 16:35 - pre 153 meseci
Generalno ako Timer0 radi u tajmer modu nema velike razlike. Prekid se dešava na svakih 10uS pa to ti je,bitno za tvoju primenu je da greška 0. Ja generalno uvek uzimam što niži preskaler,mada nikad nisam nešto posebno razmišljao o tome :)

Globalni interapt mora biti omogućen,na koji način zavisi od kompajlera, za CVavr je #asm("sei")
 
Odgovor na temu

endre85

Član broj: 207893
Poruke: 325



+116 Profil

icon Re: AT90USB162 timer interupt svakih 0.1ms?09.09.2011. u 17:07 - pre 153 meseci
Evo ga code:

Code:

const char _THRESHOLD = 1850;
char counter;

void Timer0Overflow_ISR() org IVT_ADDR_TIMER0_OVF 
{
// Reinitialize Timer 0 value
TCNT0=0xF6;

  if (counter ==2000)
  {
      counter = 0;
  }

  if (counter >= _THRESHOLD) 
  {
    PORTD = 0xFF;             // toggle PORTB
    PORTC.B2=1;
  }
  else
  {
   PORTD = 0x00;
   PORTC.B2=0;
  }
                  // increment counter
    counter++;
}

void main() {

  DDRD   =  0xFF;               // set PORTD as output
  DDRC   =  0xFF;
  PORTD  =  0;                  // clear PORTD
  PORTC  =  0;                  // clear PORTc

  SREG_I_bit = 1;               // Interrupt enable
  TOIE0_bit  = 1;               // Timer0 overflow interrupt enable
  TIMSK0=0x01;                    //isto sto i gore
                                // Start timer with 8 prescaler
  TCCR0B=0x02;

  //da li ovde ide nesto od sledeca dva reda:
 //#asm("sei")
  //sei();
 asm{sei}; //dodao ovo
  while (1)                     // Endless loop, port is changed inside Interrupt Service Routine (ISR)
    ;
}


Ali ne radi ocekivano. Tera servo samo na jednu stranu. Sto znaci da PWM nije dobar. KAd udjem u debugger mikro C-a i stavim breakpoint na recimo TCNT0=0xF6;, program nikad ne stane tamo. Sto znaci da se prekidi ne desavaju.

Inace evo ploce na kojoj pokusavam da nateram gornji kod da proradi. Sad razmisljam da li je mozda nesto potrebno definisati u kodu oko oscilatora?!

[Ovu poruku je menjao endre85 dana 09.09.2011. u 18:33 GMT+1]
 
Odgovor na temu

Genie_1984
Novi Sad

Član broj: 61150
Poruke: 93



+1 Profil

icon Re: AT90USB162 timer interupt svakih 0.1ms?09.09.2011. u 17:29 - pre 153 meseci
sa _THRESHOLD = 1850 i interapt 10uS impuls će biti na izlazu će biti 18.5 mS logička 1 zatim 1.5mS logička 0. Pretpostavljam da je prikačena na neki tranzistor (šema?) koji invertuje signal pa će biti obrnuto na motoru što znači ako je motor kao ovde trebalo bi da stoji.
Proveri datasheet motora koje su vrednosti u tvom slučaju...

SREG_I_bit = 1; je asm{sei}; pa ti to ne treba

[Ovu poruku je menjao Genie_1984 dana 09.09.2011. u 18:42 GMT+1]
 
Odgovor na temu

endre85

Član broj: 207893
Poruke: 325



+116 Profil

icon Re: AT90USB162 timer interupt svakih 0.1ms?09.09.2011. u 17:36 - pre 153 meseci
Cek, cek. Sta sad ne vidim?!
Zar nisam napisao da ako je jednako ili iznad 1850 (dakle u periodu od 1.5 msec)

Code:
  if (counter >= _THRESHOLD)  //if counter>=1850 then port=1
  {
    PORTD = 0xFF;             // toggle PORTB
    PORTC.B2=1;
  }


da bude logicki visok nivo, a ako je manji od 1850 da bude logicki nizak nivo?!
Code:
else //if counter<1850 then port=0
  {
   PORTD = 0x00;
   PORTC.B2=0;
  }


Servo kacim direktno na plocicu, kontam da na VCC daje 5 volti (na osnovu usb specifikacije, mada sada vidim da izmedju VBUS (5v) i VCC postoji neki otpornik). Nedavno sam istim ovim servom upravljao preko PIC-a, na isti nacin i radio je ok, i za visok nivo signala od 1.5msec dolazio je otprilike u svoj srednji polozaj.



EDIT: Sad sam probao sa spoljasnjim izvorom napajanja od 5 volti i rezultat je isti.

[Ovu poruku je menjao endre85 dana 09.09.2011. u 18:58 GMT+1]

Jednostavno se generise prekid:

TCNT0 ostaje zakucan na 246

[Ovu poruku je menjao endre85 dana 09.09.2011. u 19:08 GMT+1]
 
Odgovor na temu

Genie_1984
Novi Sad

Član broj: 61150
Poruke: 93



+1 Profil

icon Re: AT90USB162 timer interupt svakih 0.1ms?09.09.2011. u 18:01 - pre 153 meseci
Da u pravu si....moja greška :)

counter ne može biti char (0..255) mora biti int (ili unsigned int)

u ISR prepravi :


void Timer0Overflow_ISR() org IVT_ADDR_TIMER0_OVF
{
// Reinitialize Timer 0 value
TCNT0=0xF6;
counter++;
if (counter ==2000)
{
counter = 0;
}

if (counter >= _THRESHOLD)
{
PORTD = 0xFF; // toggle PORTB
PORTC.B2=1;
}
else
{
PORTD = 0x00;
PORTC.B2=0;
}
}
 
Odgovor na temu

endre85

Član broj: 207893
Poruke: 325



+116 Profil

icon Re: AT90USB162 timer interupt svakih 0.1ms?09.09.2011. u 18:10 - pre 153 meseci
O tome sam i ja razmisljao, ne vezano za moj problem. Ali rekoh ako je ovima iz primera radilo, onda da ne menjam. Scratch that, taj counter je zaostao iz nekog drugog primera. Upravu si, promenio sam mu tip.

Opet, meni je problem sto uopste ne ulazim u funkciju prekida. Pogledaj zadnju sliku koju sam postavio.

Samo si counter++ prebacio, jel tako?
 
Odgovor na temu

Genie_1984
Novi Sad

Član broj: 61150
Poruke: 93



+1 Profil

icon Re: AT90USB162 timer interupt svakih 0.1ms?09.09.2011. u 18:19 - pre 153 meseci
ni neće nikada jer mislim da oni ne simuliraju prekide. imaš Jump to interrupt da bi ušao u prekidnu rutinu,proveri u dokumentaciji :)
 
Odgovor na temu

endre85

Član broj: 207893
Poruke: 325



+116 Profil

icon Re: AT90USB162 timer interupt svakih 0.1ms?09.09.2011. u 18:39 - pre 153 meseci
Aha, ima smisla.

Evo ga code. Sada servo uopste ne radi.
Code:

/*
 * Project name:
     Timer0_Interrupt (Using Timer0 to obtain interrupts)
 * Copyright:
     (c) Mikroelektronika, 2010.
 * Revision History:
     20080930:
       - initial release;
 * Description:
     This code demonstrates how to use Timer0 and it's interrupt.
     Program toggles LEDs on PORTB.
 * Test configuration:
     MCU:             ATmega128
                      http://www.atmel.com/dyn/resources/prod_documents/doc2467.pdf
     Dev.Board:       BIGAVR6
                      http://www.mikroe.com/eng/prod...22/bigavr6-development-system/
     Oscillator:      External Clock 08.0000 MHz
     Ext. Modules:    -
     SW:              mikroC PRO for AVR
                      http://www.mikroe.com/eng/products/view/228/mikroc-pro-for-avr/
 * NOTES:
     - Turn on LEDs on PORTB.
*/

const int _THRESHOLD = 1800;
//char counter;
int counter;

void Timer0Overflow_ISR() org IVT_ADDR_TIMER0_OVF 
{
// Reinitialize Timer 0 value
TCNT0=0xF6;
counter++;
    
  if (counter ==2000)
  {
      counter = 0;
  }

  if (counter >= _THRESHOLD) 
  {
    PORTD = 0xFF;             // toggle PORTB
    PORTC = 0xFF;
//    PORTC.B2=1;
  }
  else
  {
   PORTD = 0x00;
   PORTC = 0x00;
//   PORTC.B2=0;
  }
}

void main() {

  DDRD   =  0xFF;               // set PORTD as output
  DDRC   =  0xFF;
  PORTD  =  0;                  // clear PORTD
  PORTC  =  0;                  // clear PORTc
  
  SREG_I_bit = 1;               // Interrupt enable
  TOIE0_bit  = 1;               // Timer0 overflow interrupt enable
  TIMSK0=0x01;                    //isto sto i gore
  
  TCCR0A=0x00;
  TCCR0B=0x02;                   // Start timer with 8 prescaler
  TCNT0=0xF6;
  OCR0A=0x00;
  OCR0B=0x00;


  //TCCR0B=0x02;                   // Start timer with 8 prescaler

  //da li ovde ide nesto od sledeca dva reda:
 //#asm("sei")
 //sei();
 asm{sei};
 
  //sei();
  while (1)                     // Endless loop, port is changed inside Interrupt Service Routine (ISR)
    ;
}

Posto se na portu D nalaze dve diode na njima ponekad mogu da pratim rad uC-a. Tako na primer primetio sam zanimljivu stvar. Ako _TRESHOLD postavim na 550, tada diode ocekivano blinkaju, ali nakon kratkog vremena naprave pauzu, pa ponovo blinkaju pa ponovo pauza. Ne znam odakle sad dolazi taj zastoj u radu.

EDIT: nisam promenio tip _TRESHOLD

EDIT2: Ne dobijam nikakvu reakciju...

[Ovu poruku je menjao endre85 dana 09.09.2011. u 19:52 GMT+1]
 
Odgovor na temu

Genie_1984
Novi Sad

Član broj: 61150
Poruke: 93



+1 Profil

icon Re: AT90USB162 timer interupt svakih 0.1ms?09.09.2011. u 19:18 - pre 153 meseci
Code:


const int _THRESHOLD = 185;

int counter;

void Timer0Overflow_ISR() org IVT_ADDR_TIMER0_OVF 
{

TCNT0=0x9E;
counter++;
    
  if (counter ==200)
  {
      counter = 0;
  }

  if (counter >= _THRESHOLD) 
  {
    PORTD = 0xFF;             // toggle PORTB
    PORTC = 0xFF;

  }
  else
  {
   PORTD = 0x00;
   PORTC = 0x00;

  }
}

void main() {

  DDRD   =  0xFF;               // set PORTD as output
  DDRC   =  0xFF;
  PORTD  =  0;                  // clear PORTD
  PORTC  =  0;                  // clear PORTc
  
  SREG_I_bit = 1;               // Interrupt enable
  TOIE0_bit  = 1;               // Timer0 overflow interrupt enable

  
  TCCR0A=0x00;
  TCCR0B=0x02;                   // Start timer with 8 prescaler
  TCNT0=0x9E;
  OCR0A=0x00;
  OCR0B=0x00;

  while (1)                     // Endless loop, port is changed inside Interrupt Service Routine (ISR)
    ;
}


Probaj ovako. povećao sam interapt na 100uS
 
Odgovor na temu

endre85

Član broj: 207893
Poruke: 325



+116 Profil

icon Re: AT90USB162 timer interupt svakih 0.1ms?09.09.2011. u 19:50 - pre 153 meseci
Ne radi ni sa tim interaptom. Ja sam pokusavao da debagujem na sledeci nacin:

Code:

void Timer0Overflow_ISR() org IVT_ADDR_TIMER0_OVF 
{
// Reinitialize Timer 0 value
TCNT0=0xF6;
counter++;

    if(counter==40)
    {
    PORTD=0xFF;
    counter=0;
    }
}


Cim stavim veci broj od 40, diode na portu D se nikad ne upale. Ispod i jednako 40 constanto svetle (pretpostavljam zbog veoma male vremenske ne moze se registrovati gasenje, to je 0.4 msec pa nije ni cudo).

Zasto ne bi radio ako je counter==41 i vece?!

 
Odgovor na temu

Genie_1984
Novi Sad

Član broj: 61150
Poruke: 93



+1 Profil

icon Re: AT90USB162 timer interupt svakih 0.1ms?09.09.2011. u 20:25 - pre 153 meseci
Pitanje je zašto se ugase,jer ako staviš == 40 čim dostigne tu vrednost led bi trebalo da se upale (isto i ako je <=) i nikad da se ne gase (jer nigde ne resetuješ PORTD)
Da li fuse biti postavljeni za spoljašni kristal 8Mhz?
 
Odgovor na temu

endre85

Član broj: 207893
Poruke: 325



+116 Profil

icon Re: AT90USB162 timer interupt svakih 0.1ms?09.09.2011. u 20:57 - pre 153 meseci
Malopre sam se pogresno izrazio. Postavio sam jedan snippet a pricao sam o drugom. Prvo sam probao sa ovim kodom (naravno varirao sam vrednosti iza countera, i kad nisam dobijao ocekivane rezultate sam presao na onaj jednostavniji, gde je paljenje sa kasnjenjem):

//if (counter == 10)
//{
// PORTD= ~PORTD;
// counter = 0;
//}

Pa sam ga naknadno iskomentarisao i presao na onaj se jednim paljenjem kada counter dostigne odredjenu vrednost.

Negde gore sam pitao da li nesto treba dodati u kodu za odredjivanje kristala. U ovom FLIP-u ne vidim nigde podesavanja za fuse bitove. Dok uglavnom mikroElektronika programeri imaju tu opciju. Sad cu da vidim da li ima neki hint u dokumentaciji za tacno odredjivanje internog ili externog oscilatora.

Trenutno imam jos pristup UniDS3 razvojnoj ploci preko koga mogu programirati PIC i 8051, i mogao bih programirati atmega32. Samo sto je potrebno da koristim ovu malu startUSB plocicu

Da li mogu preko ovog Clock Selection Register 0 – CLKSEL0 da odredim koji kristal da se koristi za generisanje clocka?

ovako nekako:
CLKSEL0.EXTE = 1;
CLKSEL0.CLKS = 1


[Ovu poruku je menjao endre85 dana 09.09.2011. u 22:22 GMT+1]


EDIT: sad sam nasao sledecu informacije:

Citat:
By default the AT90USB uses an internal osc at 8Mhz with the DIV8 fuse on (so 1MHz clock).



Citat:
Q: After reading the datasheet, it seems you can only program the Fuse bytes using serial or parallel mode and not using USB (like FLIP) etc. Is that the case?

A: Correct, you can reprogram the fuses with an ISP, HVPP or JTAG device. The USB bootloader is unable to change the fuses.


Hvala ti na strpljenju, veruj mi pomogao si mi mnogo. Iako jos ne radi sada imam mnogo bolju ideju sta i kako treba.

EDIT2:
Nasao sam i ovo:
Citat:
You can�t change the fuse, but you can change the CLKPR, at the top in main.
Code:
// set CLKPR bit to change clock prescaler
CLKPR = (1<<CLKPCE);
// no clock prescaler
CLKPR = 0;


Citat:
When the CKDIV8 fuse is set, it sets the CLKPS bits 3:0 to 0011 by default. But nothing prevents you to change that back to an undivided system clock or CLKPS bits 3:0 to 0000. When altering the CLKPR, you must disable global interrupts, write the CLKPCE bit to one, and all other bits to zero, then within 4 clock cycles, set the desired clock prescaler bits, while writing a zero to CLKPCE.

Although, this doesn�t alter in anyway the USB clock, which is derived from an internal PLL clock source, locked on the PLL prescaler (2MHz), which has his input from the crystal oscillator or external clock input, that�s why USB only works with a crystal or external clock source (8 or 16MHz).

Change the CLKPR at the start in main, just like you would do to stop the watchdog (something you should do, if you�re not using the watchdog).


[Ovu poruku je menjao endre85 dana 09.09.2011. u 22:33 GMT+1]

U jednom od gornjih primera koje sam postavio, stoji sledeca stvar:

Code:
// Crystal Oscillator division factor: 1
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif


Kontam da bi tako nesto i meni pomoglo.

[Ovu poruku je menjao endre85 dana 09.09.2011. u 22:42 GMT+1]

[Ovu poruku je menjao endre85 dana 09.09.2011. u 22:45 GMT+1]

[Ovu poruku je menjao endre85 dana 09.09.2011. u 22:45 GMT+1]
 
Odgovor na temu

[es] :: Elektronika :: Mikrokontroleri :: AT90USB162 timer interupt svakih 0.1ms?

Strane: 1 2

[ Pregleda: 4731 | Odgovora: 22 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.