[ endre85 @ 08.09.2011. 12:29 ] @
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.
[ shpiki @ 08.09.2011. 14:14 ] @
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!
[ endre85 @ 09.09.2011. 12:38 ] @
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]
[ endre85 @ 09.09.2011. 13:26 ] @
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?
[ Genie_1984 @ 09.09.2011. 13:48 ] @
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)
[ endre85 @ 09.09.2011. 14:14 ] @
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]
[ Genie_1984 @ 09.09.2011. 15:24 ] @
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.




[ endre85 @ 09.09.2011. 15:49 ] @
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]
[ Genie_1984 @ 09.09.2011. 16:35 ] @
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")
[ endre85 @ 09.09.2011. 17:07 ] @
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]
[ Genie_1984 @ 09.09.2011. 17:29 ] @
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]
[ endre85 @ 09.09.2011. 17:36 ] @
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]
[ Genie_1984 @ 09.09.2011. 18:01 ] @
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;
}
}
[ endre85 @ 09.09.2011. 18:10 ] @
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?
[ Genie_1984 @ 09.09.2011. 18:19 ] @
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 :)
[ endre85 @ 09.09.2011. 18:39 ] @
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]
[ Genie_1984 @ 09.09.2011. 19:18 ] @
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
[ endre85 @ 09.09.2011. 19:50 ] @
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?!

[ Genie_1984 @ 09.09.2011. 20:25 ] @
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?
[ endre85 @ 09.09.2011. 20:57 ] @
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]
[ Genie_1984 @ 09.09.2011. 22:01 ] @
"By default the AT90USB uses an internal osc at 8Mhz with the DIV8 fuse on (so 1MHz clock)."

To znači da ti uC radi na taktu od 1Mhz, znači u avrcalc kucaš tu vrednost kristala

kao preskaler stavi 1 a TCNT0=0x9c za interapt od 100uS. za 10uS ima grešku (tačna vrednost bude 11.11us) tako da je bolje 100us

FUSE biti se ne mogu menjati učitavanjem HEX fajla nego samo direktnim programiranjem

PS. AvrCalc koji ti koristiš brljavi. Koristi ovaj http://www.avrfreaks.net/index...=292&module=Freaks%20Tools

[Ovu poruku je menjao Genie_1984 dana 09.09.2011. u 23:40 GMT+1]
[ endre85 @ 09.09.2011. 22:47 ] @
Skontao sam to za fuse bitove, zato sam i postavio, ali izgleda da ima neka caka sa CLKPR.

Inace nece ni sad da radi. Bas je deprimirajuce. Ali mislim da negde drugde gresim (ili jos negde). Ja bih rekao da uopste ne generisem bilokakav pwm. Za _THRESHOLD = 30 i ispod diode konstantno svetle (malopre sam podizao za po jedan i prestalo je kod 36), cim predjem taj neki prag od 3X diode se nikad ni ne upale, a ni servo ne reaguje, da ima bar nekakvog pwm-a makar i pogresnog onda bi otisao skroz na jednu stranu i hteo bi da ide dalje od blokade. Ali nista, mogu slobodno da ga okrecem rukom.


Code:


const int _THRESHOLD = 30; //185
//char counter;
unsigned int counter;
int counter2;

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

    if (counter2==200)
    {
         counter2=0;
    }
  //  if(counter==41)
   // {
   // PORTD=0xFF;
    //PORTD= ~PORTD;
  //  counter=0;
  //  }
  
  //if (counter == 10)
  //{
  //    PORTD= ~PORTD;
  //    counter = 0;
  //}

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

void main() {

  //CLKSEL0.EXTE=1;
  //CLKSEL0.CLKS = 1;

   // set CLKPR bit to change clock prescaler
   //CLKPR = (1<<CLKPCE);
   // no clock prescaler
   //CLKPR = 0;


   ////////////////////////////////////////////////

  DDRD   =  0xFF;               // set PORTD as output
  DDRC   =  0xFF;
  PORTD  =  0x00;                  // clear PORTD
  PORTC  =  0x00;                  // 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
  TCCR0B=0x01;                   // Start timer with no (1) prescaler 0.1msec
  //TCNT0=0xF6;                  //za 8 mhz i 8 prescaler i 0.01msec
  TCNT0=0x9c;                    //za 1mhz i 1 prescaler i 0.1msec
  OCR0A=0x00;
  OCR0B=0x00;



  

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

  counter=0;
  counter2=0;
  //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)
    ;
}


Sto se tice kalkulatora, interesantno je da ni ovaj koji si ti preporucio ne prijavljuje gresku kada ukucam 0.01 msec, ali zato ima greske kad je 10usec. Kod ovog drugog nema ni tada. No, posto si iskusniji, poslusacu tvoju preporuku za avrcalc.
[ endre85 @ 13.10.2011. 18:19 ] @
OK, ostao sam duzan da postavim kod.

Code:

/*
 * Project name:
     LED_Blinking (Simple 'Hello World' project)
 * Copyright:
     (c) Mikroelektronika, 2010.
 * Revision History:
     20080930:
       - initial release;
 * Description:
     This is a simple 'Hello World' project. It turns on/off diodes connected to
     PORTA, PORTB, PORTC and PORTD.
 * Test configuration:
     MCU:             ATmega16
                      http://www.atmel.com/dyn/resources/prod_documents/doc2466.pdf
     dev.board:       easyavr6 -
                      http://www.mikroe.com/eng/prod...1/easyavr6-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:
     - Make sure you turn ON the PORTA, PORTB, PORTC and PORTD LEDs (SW8.1, SW8.2, SW8.3 and SW8.4).
*/
#include <string.h> //vidi za string funkcije u ovoj bibilioteci

#define BUFF_SIZE 70 //40 da probamo sa 70 da bude velicina: 'SLOVOzaSERVO'XXX puta 17 => 4*17=68, plus karakter za kraj i jos nesto==70

char uart_rd;
int res;

unsigned char a[3];
typedef unsigned char byte;

bit t;
byte br_bajta,s,br_bajta2;
//byte output[4];
int output;
//byte dolazni;
int result;

//char SG;
int SG;
byte SG2[2];
byte SG3[2];
const char _THRESHOLD = 20;
char counter;
const int SMTH = 1250; //servo motor treshold
                       //1250*16 usec=20msec
int smcount;       //servo motor count
int j;
volatile long mer_time;

bit brzosporo;
//Pinovi na koje treba povezati odredjene servo motore
sbit ServoGLava at PORTB.B0;

sbit ServoLevaRukaRame at PORTB.B1;
sbit ServoLevaRukaLakat at PORTB.B2;
sbit ServoLevaRukaSaka at PORTB.B3;

sbit ServoDesnaRukaRame at PORTB.B4;
sbit ServoDesnaRukaLakat at PORTB.B5;
sbit ServoDesnaRukaSaka at PORTB.B6;

sbit ServoLevaNoga1 at PORTB.B7;   //neka 1 bude u torsu
sbit ServoLevaNoga2 at PORTC.B1;
sbit ServoLevaNoga3 at PORTC.B2;
sbit ServoLevaNoga4 at PORTC.B3;
sbit ServoLevaNoga5 at PORTC.B4;

sbit ServoDesnaNoga1 at PORTC.B5;  //neka 1 bude u torsu
sbit ServoDesnaNoga2 at PORTC.B6;
sbit ServoDesnaNoga3 at PORTC.B7;
sbit ServoDesnaNoga4 at PORTD.B0;
sbit ServoDesnaNoga5 at PORTD.B1;

//vrednosti pri kojima se postavlja nizak logicki nivo za zadati servo
volatile char trVrednostiFIServa[7];

volatile int glavafi;

volatile int lrrfi;   //LevaRukaRameFaktorIspune
volatile int lrlfi;
volatile int lrsfi;

volatile int drrfi;   //DesnaRukaRameFaktorIspune
volatile int drlfi;
volatile int drsfi;

/*
volatile int ln1fi;   //LevaNoga1FaktorIspune
volatile int ln2fi;
volatile int ln3fi;
volatile int ln4fi;
volatile int ln5fi;

volatile int dn1fi;   //DesnaNoga1FaktorIspune
volatile int dn2fi;
volatile int dn3fi;
volatile int dn4fi;
volatile int dn5fi;
*/
volatile char prijem[BUFF_SIZE];
volatile char brkar;
volatile char stiglaporuka;
//min fi je 34
//maks fi je 115

void initUSARTbyMIKROC();
//void initUSARTbyME( unsigned int );
void initUSARTbyME( unsigned int baud );
void initUC();
void demoBrzinaSM();
void demoBrzinaSM2();

void pocetnaPozicijaSM();
void pocetnaPozicijaSM_NIZ();

void testiranjeUART();
void ServoPosByUART();

void podesiServoPozicije();
void izvucipodatke();
void newline();

void delay_x16us(long dtime)
{
 mer_time=dtime;
 while(mer_time);
}


void UART1_Data_recive() org IVT_ADDR_USART1__RX
{
 char temp;
 temp=UDR1;
 prijem[brkar]=temp;
 brkar++;
 prijem[brkar]='\0'; //oznacava da je u pitanju string

 if(temp=='!') //to znaci da je stigao string sa ! koji odredjuje kraj korisne informacije
 {
  stiglaporuka=1;
 }

//prijem karaktera na serijski port
}

void Timer1Overflow_ISR() org IVT_ADDR_TIMER1_OVF
{
  //Interapt na svakih 16 uS
  TCNT1H = 0xff;
  TCNT1L = 0x80;


  smcount++;

  //Kratko pojasnjenje:
  //Generisemo interapt svakih 16 usec, kada i povecavamo brojace
  //glavni brojac (smcount) koji ujedno i predstavlja jednu periodu rada servo motora
  //se resetuje na otp svakih 20 msec
  //Pomocu njega odredjujemo faktor ispune odredjenih servo motora
  //u smislu da se na pinove postavlja visok logicki nivo na pocetku periode,
  //a spusta se na nizak kada se odredjena promenljiva servo motora imau
  //vrednost jednaku sa sa glavnim brojacem
 
/*
  for(j=0;j<4;j++)
  {
    if(smcount>trVrednostiFIServa[j])
    {
       switch (j)
       {
         case 0:    ServoGLava=0;
         break;
         case 1:    ServoLevaRukaRame=0;
         break;
         case 2:    ServoLevaRukaLakat=0;
         break;
         case 3:    ServoLevaRukaSaka=0;
         break;
//         case 5:
//         break;
//         case 6:
//         break;

       }
    }
  }
*/



//IMPORTANT
//Saovakvim principom rada interapta, 4 motora su otprilike maxumum za OK rad
//Prelazak na nizak nivo glave
///*
  if(smcount>trVrednostiFIServa[0])
  {
   ServoGLava=0;
  }
//*/

///*
//Prelazak na nizak nivo leve ruke
  if(smcount>trVrednostiFIServa[1])
  {
   ServoLevaRukaRame=0;
  }
   if(smcount>trVrednostiFIServa[2])
  {
   ServoLevaRukaLakat=0;
  }
  if(smcount>trVrednostiFIServa[3])
  {
   ServoLevaRukaSaka=0;
  }
//*/
/*
//Prelazak na nizak nivo desne ruke
  if(smcount>drrfi)
  {
   ServoDesnaRukaRame=0;
  }
   if(smcount>drlfi)
  {
   ServoDesnaRukaLakat=0;
  }
  if(smcount>drsfi)
  {
   ServoDesnaRukaSaka=0;
  }

*/
/*

//Prelazak na nizak nivo leve noge
  if(smcount>ln1fi)
  {
   ServoLevaNoga1=0;
  }
   if(smcount>ln2fi)
  {
   ServoLevaNoga2=0;
  }
  if(smcount>ln3fi)
  {
   ServoLevaNoga3=0;
  }
   if(smcount>ln4fi)
  {
   ServoLevaNoga4=0;
  }
  if(smcount>ln5fi)
  {
   ServoLevaNoga5=0;
  }
//Prelazak na nizak nivo desne noge
  if(smcount>dn1fi)
  {
   ServoDesnaNoga1=0;
  }
   if(smcount>dn2fi)
  {
   ServoDesnaNoga2=0;
  }
  if(smcount>dn3fi)
  {
   ServoDesnaNoga3=0;
  }
   if(smcount>dn4fi)
  {
   ServoDesnaNoga4=0;
  }
  if(smcount>dn5fi)
  {
   ServoDesnaNoga5=0;
  }
*/

  if(smcount>SMTH) //ovde brojac dostize max vrednost, pa dizemo sve na kec na pocetku novog ciklusa
  {
    smcount=0;

    ServoGLava=1;

    ServoLevaRukaRame=1;
    ServoLevaRukaLakat=1;
    ServoLevaRukaSaka=1;
/*
    ServoDesnaRukaRame=1;
    ServoDesnaRukaLakat=1;
    ServoDesnaRukaSaka=1;
*/
/*
    ServoLevaNoga1=1;
    ServoLevaNoga2=1;
    ServoLevaNoga3=1;
    ServoLevaNoga4=1;
    ServoLevaNoga5=1;

    ServoDesnaNoga1=1;
    ServoDesnaNoga2=1;
    ServoDesnaNoga3=1;
    ServoDesnaNoga4=1;
    ServoDesnaNoga5=1;
*/

  }
  
  if(mer_time>0)
   mer_time--;
  else
   mer_time=0;

}


void main() {

  char i;
  initUC();
  initUSARTbyMIKROC();
  //initUSARTbyME(9600);

  //pocetnaPozicijaSM();
    pocetnaPozicijaSM_NIZ();

/*
  SG='@';
  t=0;
  brzosporo=0;
  br_bajta=0;
  br_bajta2=1;
*/
  stiglaporuka=0;
  
  for(i=0;i<BUFF_SIZE;i++) //petlja za ciscjenje bafera
  {
   prijem[i]=0;
  }
  brkar=0;
 
  do {

      
      if(stiglaporuka)
      {
       stiglaporuka=0;
       izvucipodatke();
      }
//    demoBrzinaSM();
//    demoBrzinaSM2();
//    testiranjeUART();
//    ServoPosByUART();

     
  } while(1);            // Endless loop
}

void izvucipodatke()
{
 char fims[4];    //faktor ispune motora string
 char i;
 char fim[7];     //faktor ispune motora
 int rbm,trb;     //rbm - redni bronj motora; trb - trenutni broj
                  //pazi (prilikom slanja) da trb ne sme biti veci od 255
 char tk;         //trebalo bi da bude trenutni karakter

 for(i=0;i<7;i++) //7 motora, ima tako da upisujemo 7 vrednosti u niz
 //pre iscitavanja podataka iz bafera, upiseu nulu za svaku od 7 vrednosti
 {
  fim[i]=0;
 }
 
 for(i=0;i<BUFF_SIZE;i++)  //iscitavamo karakter po karakter iz bafera serijskog "porta"
 {
  tk=prijem[i];
  prijem[i]=0;             //optimizacija koda, odmah nakon iscitavanja odg karaktera, ovo postavljamo na nulu
  
  if(isalpha(tk))
  {
    rbm=tk-'A';                           //redni broj motora= (ASCII code trenutnog karaktera)-(ASCII code slova A); tako za A dobijemo 0, za B 1, za C 3, itd.
    //UART1_Write('s');                     //obavestenje da je stiglo slovo
    //UART1_Write(rbm+1+'0');               //provera koje slovo
    trb=0;                                //Posto je stiglo slovo, pripremamo se za prihvat brojeva koji ga slede, te trb "resetujemo"
  }
  else if(isdigit(tk))                    //ispitivanja da le je trenutni karakter broj, i ako jeste:
  {
    trb*=10;    //Zasto mnozim trb, kada je on nula??????
    trb+=tk-'0';
    fim[rbm]=trb;   //Menjamo podatke za koje je stigla nova informacija o servu
    //UART1_Write(trb);
  }
 }
 
 for(i=0;i<7;i++)
 {
  if (fim[i]>0) //mala zastita kako ne bi prepisao prethodne vrednosti na nesto nepozeljno
                //mozda cak da stavim (fim[i]>30 && fim[i]<115)
  trVrednostiFIServa[i]=fim[i];
 }
 
/*for(i=0;i<7;i++)
 {
   UART1_Write('b');
   UART1_Write(fim[i]);
 }*/
 
 brkar=0;
}

void initUSARTbyMIKROC()
{

  UART1_Init(9600);               // Initialize UART module at 9600 bps
  
  //Setuj flag koji dozvoljava USART RX interupt
  RXCIE1_bit=1;
  //Delay_ms(100);                  // Wait for UART module to stabilize
  delay_x16us(6250);                //wait for 100msec
  PORTD.B5 = ~PORTD.B5;
  UART1_Write_Text("Start");  //radi testiranja
  
  delay_x16us(32500);
  PORTD.B5 = ~PORTD.B5;
}

void initUC()
{

   //MCUSR &= ~(1 << WDRF);
   //wdt_disable();
   
  DDRD = 0xFB;           // Set direction of PD2 to be input, the rest of PORTD output
  PORTD  = 0;
  DDRB = 0xFF;           // Set direction to be output
  PORTB  = 0;

  DDRC=0b11111110;   //DAKLE PORTC.B0 MORA OSTATI ULAZ. proveri semu
                     //na taj pin je vezan KRISTAL
  //DDRC = 0xFE;           // Set direction to be output
  PORTC  = 0;
  

  CLKPR = 0x80;
  CLKPR = 0x00;

  TCNT1H = 0xff;//100us
  TCNT1L = 0x80;
  SREG_I_bit = 1;               // Interrupt enable
  TOIE1_bit  = 1;               // Timer1 overflow interrupt enable
  TCCR1B = 1;                   // Start timer with 8 prescaler

}
void demoBrzinaSM()
{


     //PORTD = ~PORTD;
     PORTD.B6 = ~PORTD.B6;
     glavafi++;
     delay_x16us(3750); //1000 --> cekanje od 16 msec
                        //1250 --> cekanje od 20 msec
                        
     if(glavafi>114) //150
     {
      delay_x16us(31250);
      glavafi=35;//10;
      //delay_x16us(25600);  //~410 msec
      delay_x16us(62500);  //1000 msec
      delay_x16us(62500);
     }

}

void demoBrzinaSM2()
{


 if (brzosporo==0)
 {
     glavafi++;
     delay_x16us(3750); //1000 --> cekanje od 16 msec
                        //1250 --> cekanje od 20 msec

     if(glavafi>114)
     brzosporo=1;
 }
 if (brzosporo==1)
 {
     glavafi--;
     delay_x16us(10); //1000 --> cekanje od 16 msec


     if(glavafi<1)
     brzosporo=0;
 }
}

void pocetnaPozicijaSM()
{
    glavafi=35;//34 je minimalna vrednost koju konta. Sve idpod toga dolazi do ove pozicije, a ako je vec u ovoj onda se mrda
    //ServoGLava=1; //logicki visok napon na pin

    lrrfi = 45;
    //ServoLevaRukaRame = 1;
    lrlfi = 55;
    //ServoLevaRukaLakat = 1;
    lrsfi = 65;
    //ServoLevaRukaSaka = 1;
/*
    drrfi = 75;
    drlfi = 85;
    drsfi = 95;
*/
/*
    ln1fi = 65;
    ln2fi = 75;
    ln3fi = 85;
    ln4fi = 95;
    ln5fi = 105;

    dn1fi = 65;
    dn2fi = 75;
    dn3fi = 85;
    dn4fi = 95;
    dn5fi = 105;
*/
//    smcount=0; //razmisli da li je bolje da ovo stavljas pred DO
}

void pocetnaPozicijaSM_NIZ()
{
   trVrednostiFIServa[0]=45;

   trVrednostiFIServa[1]=65;
   trVrednostiFIServa[2]=85;
   trVrednostiFIServa[3]=105;
}
void initUSARTbyME( unsigned int baud )
{
//iz dokumentacije:
   PORTD.B5 = ~PORTD.B5;
/* Set baud rate */
   UBRR1H = (unsigned char)(baud>>8);
   UBRR1L = (unsigned char)baud;
/* Enable receiver and transmitter */
   UCSR1B = (1<<RXEN1)|(1<<TXEN1);
/* Set frame format: 8data, 2stop bit */
   UCSR1C = (1<<USBS1)|(3<<UCSZ10);

   delay_x16us(62500);
   PORTD.B5 = ~PORTD.B5;
}

void testiranjeUART()
{
     //testiranje uart-a
     if (UART1_Data_Ready())      // If data is received,
     {
     PORTD.B5 = ~PORTD.B5;
     //delay_x16us(6250);   //cekanje od 100msec
     uart_rd = UART1_Read();      //   read the received data,
     //delay_x16us(6250);
     UART1_Write(uart_rd);        //   and send data via UART
     }
}


void ServoPosByUART()
{
//jednostavna verzija
 /*
    ServoGLava=fim[0];

    ServoLevaRukaRame=fim[1];
    ServoLevaRukaLakat=fim[2];
    ServoLevaRukaSaka=fim[3];
*/
}

void podesiServoPozicije()
{

}
void newline(){
 UART1_Write(13); // Carriage Return
 UART1_Write(10); // Line Feed
}


Nisam izbacio visak u odnosu na prekid tajmera tj. same teme, mozda nekom zatreba.

Mala napomena najmanji prekid koji se moze generisati je 10usec i tada se moze upravljati samo jednim servom. Sada se prekid desava svakih 16usec i upravlja se sa 7 serva. Tek cu videti da li sa ovim prekidom tajmera mogu izgurati i malo komplikovanije upravljanje servo motorima pomocu serijskog.

Evo ga i mali program koji savrseno funkcionise u sprezi sa gornjim uC (upravlja servo motorima preko serijskog), pisan je u C sharp 2010:
http://www.2shared.com/file/t0...SerialServoComm_13okt2011.html



Hvala svima na pomoci.

Poz.

[Ovu poruku je menjao endre85 dana 13.10.2011. u 19:34 GMT+1]