ATmega128 - funguje mi jen jedno PWM

Diskuze a poradna o programátorech a programování různých obvodů

Moderátor: Moderátoři

Zpráva
Autor
Uživatelský avatar
endthe
Příspěvky: 56
Registrován: 07 bře 2009, 00:00
Bydliště: Brno
Kontaktovat uživatele:

ATmega128 - funguje mi jen jedno PWM

#1 Příspěvek od endthe »

Zdravim snazim se udelat program pro ATmega128 pro ovladani dvou serv HS 422 pripojenych na PB5 (OC1A) a PB6 (OC1B). ovladaní je pomoci PWM rizeneho tlacitky (krokovani UP a DOWN pro kazde servo (pres interupty na portu D)). Problem je v tom ze mi jede pouze jedno PWM na OC1A a nedari se mi rozchodit druhe PWM na OC1B :( . Prikladam i zdrojak. Prosim o radu a celkem to specha. Dekuji

kod programu mam nasledujici v AVR studio 4:

Kód: Vybrat vše

/**************************************************************
Project : PWM
Version : 1.0
Date    : 21.2.2009
Author  :
Comentar: manualni PWM - melo by se dat ritit pomoci tlacitek
Pouzita serva: HS-422
Chip type           : ATmega128
Program type        : Application
Clock frequency     : 16,000000 MHz
Memory model        : Small
External RAM size   : 0
Data Stack size     : 1024
**************************************************************/
#include <avr/io.h>
#include <avr/iom128.h>
#include <avr/interrupt.h>
//#####################################################################
#define NSTEP 10
#define NDELAY 100 //bylo tu 500
int isdelay = 0;
//######################TLACITKA PRO SERVO 1################################

//###########################INT0 UP###########################
ISR (SIG_INTERRUPT0)
{

if (isdelay)
return;

PORTB=~PORTB; //pro kontrolu funce (ostatni LED na portu B blikaji)

 int tmp=(int)OCR1A;
 if ((tmp+NSTEP)<255)
   OCR1A+=NSTEP;
 else
   OCR1A=255;

   isdelay=1;
}

//###########################INT1 DOWN###########################
ISR (SIG_INTERRUPT1)
{

if (isdelay)
return;

PORTB=~PORTB; //pro kontrolu funce (ostatni LED na portu B blikaji)

 int tmp=(int)OCR1A;
 if ((tmp-NSTEP)<0)
   OCR1A-=NSTEP;
   
 else
   OCR1A=0;

   isdelay=1;
}

//######################TLACITKA PRO SERVO 2################################

//###########################INT2 UP###########################
ISR (SIG_INTERRUPT2)
{

if (isdelay)
return;

PORTB=~PORTB; //pro kontrolu funce (ostatni LED na portu B blikaji)

 int tmp=(int)OCR1B;
 if ((tmp+NSTEP)<255)
   OCR1B+=NSTEP;
   
 else
   OCR1B=255;
   
   isdelay=1;
}


//###########################INT3 DOWN###########################
ISR (SIG_INTERRUPT3)
{

if (isdelay)
return;

PORTB=~PORTB; //pro kontrolu funce (ostatni LED na portu B blikaji)

 int tmp=(int)OCR1B;
 if ((tmp-NSTEP)<0)
   OCR1B-=NSTEP;
 else
   OCR1B=0;

   isdelay=1;
}

//#####################################################################

void preruseni_init(void) // uvodni nastaveni podminek pro povoleni preruseni
{
  EICRA = 0;
  EIMSK = 0x0f;
  SREG |= (1<<SREG_I);
}

//#####################################################################

void delay(unsigned int msec);

//#####################################################################

int main(void)
{
  DDRB = 0x61; //povoleni portu PB5 a PB6 jako vystup PWM (OC1A a OC1B)
  DDRD = 0;    //Porty D jako vstupy (interupty nastavene pro tlacitka 1-4)
  PORTD = 0xff;
  preruseni_init();

//######################PWM PRO SERVO 1################################
 
ICR1=20000; //nastavenim ICR1=20000 dosahnu f=50Hz

TCCR1A|=(0<<COM1A0)|(1<<COM1A1)|(0<<COM1B0)
|(0<<COM1B1)|(0<<FOC1A)|(0<<FOC1B)|(1<<WGM11)|(0<<WGM10);
 
TCCR1B|=(0<<ICNC1)|(0<<ICES1)|(1<<WGM13)|(1<<WGM12)
| (0<<CS12)|(1<<CS11)|(0<<CS10);

//######################PWM PRO SERVO 2################################
ICR1=20000; //nastavenim ICR1=20000 dosahnu f=50Hz

TCCR1B|=(0<<COM1B0)|(1<<COM1B1)|(0<<COM1C0)
|(0<<COM1C1)|(0<<FOC1B)|(0<<FOC1A)|(1<<WGM11)|(0<<WGM10);


TCCR1C|=(0<<ICNC1)|(0<<ICES1)|(1<<WGM13)|(1<<WGM12)
| (0<<CS12)|(1<<CS11)|(0<<CS10);


//#####################################################################

  while(1) {
   if (isdelay)
    delay(NDELAY);
   };
 }

//#####################################################################

//void PWM(unsigned char motor1, unsigned char motor2)
//{
//   OCR1A = motor1; // Vystup servo 1
//   OCR1B = motor2; // Vystup servo 2
//}

//#####################################################################

void delay(unsigned int msec) {
 int unsigned i,n;
 for (i=msec;i>0;i--) {
  for (n=100;n>0;n--);
 }
 isdelay=0;
}


:arrow: administrator: přejmenováno z "ATmega128 PWM"
Andrea
Příspěvky: 9340
Registrován: 07 zář 2007, 00:00

#2 Příspěvek od Andrea »

V nastavení máš pomotané registry TCCR1A, B a C.

A jestli dobře počítám, tak ti to při 16MHz generuje 100Hz a ne 50.
Naposledy upravil(a) Andrea dne 07 bře 2009, 13:43, celkem upraveno 1 x.
Uživatelský avatar
endthe
Příspěvky: 56
Registrován: 07 bře 2009, 00:00
Bydliště: Brno
Kontaktovat uživatele:

#3 Příspěvek od endthe »

takze by to melo jit takto:

Kód: Vybrat vše

//######################PWM PRO SERVO 1################################
 
ICR1=20000; //nastavenim ICR1=20000 dosahnu f=50Hz

TCCR1A|=(0<<COM1A0)|(1<<COM1A1)|(0<<COM1B0)
|(0<<COM1B1)|(0<<FOC1A)|(0<<FOC1B)|(1<<WGM11)|(0<<WGM10);
 

//######################PWM PRO SERVO 2################################
ICR1=20000; //nastavenim ICR1=20000 dosahnu f=50Hz

TCCR1B|=(0<<COM1B0)|(1<<COM1B1)|(0<<COM1C0)
|(0<<COM1C1)|(0<<FOC1B)|(0<<FOC1A)|(1<<WGM11)|(0<<WGM10);



//#####################################################################
Uživatelský avatar
endthe
Příspěvky: 56
Registrován: 07 bře 2009, 00:00
Bydliště: Brno
Kontaktovat uživatele:

#4 Příspěvek od endthe »

endthe píše:takze by to melo jit takto:

Kód: Vybrat vše

//######################PWM PRO SERVO 1################################
 
ICR1=20000; //nastavenim ICR1=20000 dosahnu f=50Hz

TCCR1A|=(0<<COM1A0)|(1<<COM1A1)|(0<<COM1B0)
|(0<<COM1B1)|(0<<FOC1A)|(0<<FOC1B)|(1<<WGM11)|(0<<WGM10);
 

//######################PWM PRO SERVO 2################################
ICR1=20000; //nastavenim ICR1=20000 dosahnu f=50Hz

TCCR1B|=(0<<COM1B0)|(1<<COM1B1)|(0<<COM1C0)
|(0<<COM1C1)|(0<<FOC1B)|(0<<FOC1A)|(1<<WGM11)|(0<<WGM10);



//#####################################################################


ja to delal podle datasheetu
Andrea
Příspěvky: 9340
Registrován: 07 zář 2007, 00:00

#5 Příspěvek od Andrea »

Jestli to děláš podle datašítu, tak nevím podle kterého, protože to máš pořád stejně blbě.
Uživatelský avatar
endthe
Příspěvky: 56
Registrován: 07 bře 2009, 00:00
Bydliště: Brno
Kontaktovat uživatele:

#6 Příspěvek od endthe »

Andrea píše:Jestli to děláš podle datašítu, tak nevím podle kterého, protože to máš pořád stejně blbě.



no primo od atmela ale je mozne ze sem se do toho zamotal tak porad co opravit
Andrea
Příspěvky: 9340
Registrován: 07 zář 2007, 00:00

#7 Příspěvek od Andrea »

endthe píše:
Andrea píše:Jestli to děláš podle datašítu, tak nevím podle kterého, protože to máš pořád stejně blbě.



no primo od atmela ale je mozne ze sem se do toho zamotal tak porad co opravit

V datašítu jsou přece ty tři registry rozkreslené na jednotlivé bity, tak do nich strkej jen co do nich patří. Nebo kde vidíš, že FOC1A a FOC1B patří do TCCR1A, že COM1B patří do TCCR1A i do TCCR1B?
Uživatelský avatar
endthe
Příspěvky: 56
Registrován: 07 bře 2009, 00:00
Bydliště: Brno
Kontaktovat uživatele:

#8 Příspěvek od endthe »

ja se ridil taky pomoci http://winavr.scienceprog.com/example-a ... g-avr.html

akorad sem ty tlacitka dal na interupty
Andrea
Příspěvky: 9340
Registrován: 07 zář 2007, 00:00

#9 Příspěvek od Andrea »

endthe píše:ja se ridil taky pomoci http://winavr.scienceprog.com/example-a ... g-avr.html

akorad sem ty tlacitka dal na interupty

Nojo, ale cpeš to do megy128, tak musíš koukat do datašítu megy128.
Uživatelský avatar
endthe
Příspěvky: 56
Registrován: 07 bře 2009, 00:00
Bydliště: Brno
Kontaktovat uživatele:

#10 Příspěvek od endthe »

to prvni PWM jede ale to druhe ne :( a uz sem z toho zoufalej zas tak moc ty atmely neumim
Uživatelský avatar
endthe
Příspěvky: 56
Registrován: 07 bře 2009, 00:00
Bydliště: Brno
Kontaktovat uživatele:

#11 Příspěvek od endthe »

Kód: Vybrat vše

//######################PWM PRO SERVO 1################################
 
ICR1=20000; //nastavenim ICR1=20000 dosahnu f=50Hz

TCCR1A|=(0<<COM1A0)|(1<<COM1A1)|(0<<COM1B0)
|(0<<COM1B1)|(1<<WGM11)|(0<<WGM10);


//######################PWM PRO SERVO 2################################
ICR1=20000; //nastavenim ICR1=20000 dosahnu f=50Hz

TCCR1B|=(0<<COM1B0)|(1<<COM1B1)|(0<<COM1C0)
|(0<<COM1C1)|(1<<WGM11)|(0<<WGM10);



//#####################################################################


takze by to melo byt takto?
Andrea
Příspěvky: 9340
Registrován: 07 zář 2007, 00:00

#12 Příspěvek od Andrea »

Ne, podíval ses do toho datašítu ATmega128?
Kde v něm vidíš, že registr TCCR1B obsahuje bity COM1B0, COM1B1, COM1C0, COM1C1, WGM11, WGM10? Já vidím toto:
Přílohy
TCCR1x.gif
(29.11 KiB) Staženo 121 x
Uživatelský avatar
endthe
Příspěvky: 56
Registrován: 07 bře 2009, 00:00
Bydliště: Brno
Kontaktovat uživatele:

#13 Příspěvek od endthe »

Kód: Vybrat vše

TCCR1B|=(0<<ICNC1)|(0<<ICES1)|(1<<WGM13)|(1<<WGM12)|(0<<CS12)|(1<<CS11)|(0<<CS10);


no tim padem takto
Uživatelský avatar
endthe
Příspěvky: 56
Registrován: 07 bře 2009, 00:00
Bydliště: Brno
Kontaktovat uživatele:

#14 Příspěvek od endthe »

jinak uz me to nenapada :?
Andrea
Příspěvky: 9340
Registrován: 07 zář 2007, 00:00

#15 Příspěvek od Andrea »

No sláva a ještě co do TCCR1A.
Odpovědět

Zpět na „Programování PIC, ATMEL, EEPROM a dalších obvodů“