- LiFePO4 Speicher Test         
Seite 2 von 2 ErsteErste 12
Ergebnis 11 bis 20 von 20

Thema: servo pwm mit c erzeugen

  1. #11
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    2.187
    Anzeige

    LiFePo4 Akku selber bauen - Video
    mein board hat übrigens nen atmega32 und einen 16MHz quartz
    Bei meinem Code musst Du dann die OCR Werte verdoppeln also 2600 anstatt 1300 und 10000 anstatt 5000 usw.
    Du kriegst aber dann auch ein Auflösung von 0,5µs = 2000 Schritte

  2. #12
    Neuer Benutzer Öfters hier
    Registriert seit
    19.07.2007
    Beiträge
    16
    @radbruch: könntest du deinen code etwas mehr komplettieren? ich weiß wenig damit anzufangen und was muss ich includen damit er sei() kennt?

    @oberallgeier: eine solche timer init funktion habe ich auch in meinem code aber du übergibst ganz andere werte was an meinem 16MHz quartz liegen sollte

    @wkrug: kannst du mir erklären was ui_pwm bei dir machen und wie man nun konkret den pwm setzt?
    dein code compiliert bei mir nicht - es sind zig namen undeclared.

    Ich weiß auch nicht warum im forum mit thema "rn-control" code für einen atmel16 mit 16MHz quartz gepostet wird - oder gibt es den RN-Control auch mit diesen bauteilen?

    mein aktueller code sieht so aus:
    Code:
    [...]
    
    void init_timer1(void)
    {
       TCCR1A = (1<<COM1A1)|(1<<COM1B1)|(1<<WGM10)|(1<<WGM11);
    
       TCCR1B = (1<<CS12);
    
       TIMSK &= ~0x3c;
    }
    
    int main(void)
    {
    int stellung = <je nach bitwert des PWM>
    DDRD |= 0xB0;
    OCR1BL = stellung;
    damit dreht er sich auch schon nur sehr unvorhersehbar.

    was muss ich in meinem fall in TCCR1A und TCCR1B schreiben damit ich die servostellung per OCR1BL oder OCR1AL kontrollieren kann?

    es wäre wirklich hilfreich einfach ein kleines funktionierendes code snippet zu haben welches ich mit avr-gcc für meinen atmel32 compiliere und testen kann! auf jeden fall vielen dank für eure hilfe aber ich bin zu sehr newbie um atmel16 code einfach mal so für meinen atmel32 umzuschreiben.
    kann den code nicht jmd. auf seinem RN-Control mit einem servo testen?

  3. #13
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Hallo

    sei() und cli() sind in interrupt.h. Ich habe dir mal mein Programm auf's nötigste geputzt, ich hoffe, es funzt so:
    Code:
    #include <avr/io.h>			// I/O Port definitions
    #include <avr/interrupt.h>	// Interrupt macros
    
    uint8_t  x, y, z;
    
    void delay(uint16_t d)
    {
    	uint16_t d1, dummy;
    	for (d1=d; d1>0; d1--) dummy^=d1;
    }
    
    void init(void)
    {
    	cli();
    
    	DDRA |= 16;
    	DDRC |= 3;
    
    	TCCR0 =  (0 << WGM00) | (1 << WGM01);					// CTC-Mode
    	TCCR0 |= (0 << COM00) | (0 << COM01);					// ohne OCR-Pin
    	TCCR0 |=	(0 << CS02)  | (1 << CS01) | (0 << CS00);	// prescaler /8
    	TIMSK =  (1 << OCIE0); 										// Interrupt ein
    	OCR0  = 9; // 100kHz?
    
    	sei();
    }
    
    ISR(TIMER0_COMP_vect)
    {
    	static uint16_t count=0;
    	if(count>x) PORTA &= ~16; else PORTA |= 16;
    	if(count>y) PORTC &= ~1;  else PORTC |= 1;
    	if(count>z) PORTC &= ~2;  else PORTC |= 2;
    	if(count<1000)count++; else count=0;
    };
    
    int main(void)
    {
    	init();
    
    	z=105; y=110; x=90; delay(50000);
    	z=90; delay(10000);
    
    	while(1);
    	return 0;
    }
    Die Funktion delay() habe ich inzwischen so gelöst:

    Code:
    volatile uint16_t count, time;
    
    void delay(uint16_t d)                                // Warteschleife
    {
    	d+=time; while(d>time);
    }
    
    und in der ISR:
    
    	if (count < 1000) count++; else { count=0; time++; }
    Gruß

    mic
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  4. #14
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    2.187
    @JoSch1337
    @wkrug: kannst du mir erklären was ui_pwm bei dir machen und wie man nun konkret den pwm setzt?
    dein code compiliert bei mir nicht - es sind zig namen undeclared.
    ui_pwm[0..3] sind die Impulsdauern für die Servokanäle 1...4.
    Ich hab die mal einfach willkürlich auf beliebige Werte gesetzt.
    Gültige Werte sollten im Bereich von 1000...2000 bzw. 1150...1950 liegen.
    Das gilt für einen 8MHz Quarz und Taktteiler 8 für Timer 1.
    Bei 16MHz sind die Werte 2000...4000 einzugeben und auch der Wert für uc_cycle zu verdoppeln.

    Der Code ist für den C - Compiler "CodeVision AVR" gemacht ist. Mein Codevision compiliert ihn ohne Fehlermeldung.
    Die Einstellwerte für die Register des Timers 1 sind auch einwandfrei auslesbar.
    Code:
    TCCR1A=0x00;
    TCCR1B=0x02;
    ....
    TIMSK=0x18;
    In den Bemerkungen oberhalb des Abschnittes wird auch genau erklärt was da eigentlich eingestellt wird.
    Die paar Zeilen Code auf AVR-GCC anzupassen sollte aber auch nicht wirklich ein Problem sein - oder?
    SEI ist ein Assembler Befehl, der Global die Interrupts freigibt. Wie macht AVR - GCC das ?
    Das Include File passt natürlich auch nicht, es muss natürlich das passende von AVR GCC genommen werden.

  5. #15
    Neuer Benutzer Öfters hier
    Registriert seit
    19.07.2007
    Beiträge
    16
    radbruch, werde mich zuerst mal deinem code widmen denn ich glaube den verstehe ich jetzt.
    init startet dabei einen timer der die entsprechenden register setzt die hoffentlich zu einem 50Hz signal führen.
    aber wie kommt ISR(TIMER0_COMP_vect) von einem count von 0 weg wenn die variable jedesmal auf neue auf 0 gesetzt wird?
    davon abgesehen soll der code wahrscheinlich folgendes machen:
    durch einen timer wird fortwährend auf 1000 hochgezählt und je nachem wie x, y und z gesetzt sind die entsprechenden ports an und wieder aus geschaltet. somit wäre es anscheind möglich an jedem beliebigen port so ein pwm zu erzeugen.
    wie ich nun auf die 50Hz komme ist mir ein rätsel - woher soll ich die genauen register wissen? die, die ich momentan gesetzt habe und die eine partielle fukntion ermöglichen decken sich ja überhauptnicht mit eurem code.

  6. #16
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Hallo

    Durch das "static" wird count nur einmal mit dem Startwert geladen und behält dann seinen aktuellen Wert bei jedem Aufruf der ISR bei. (In der delay()-Variante mit time ist count global)

    In init() wird der Timer mit prescale/8 im CTC-Mode gestartet, d.h. er zählt von 0 bis zum Vergleichswert (9 bei 8MHz, 19 bei 16MHz) und ruft dann die ISR auf. Das sollte 8000000/8/10=100kHz ergeben (oder 16000000/8/20). In der ISR wird dann count auf 1000 gezählt, dass ergibt 100 Herz als Wiederholung. Hier beginnt dann die "Grauzone": Bei 100KHz (1/100000) dauert ein count 0,01ms, meine Servos (verschiedene Hersteller) stehen bei ca. 100 counts, was 1 ms entspricht, in der Mitte, von ca. 50-150 machen sie 180°. Eigentlich sollte Mitte aber bei 1,5ms sein, ich habe keine Ahnung, warum das nicht passt. (Das stört mich nicht wirklich, ich würde nur gerne wissen, wo der Fehler liegt.)

    Das ist aber keine echte PWM, es werden lediglich verschieden lange Impulse erzeugt. Und das mit einem "normalen" Timer und nicht mit den PWM-Modi des Timers. Vermutlich decken sich deshalb die von dir verwendeten Register nicht mit meinen.

    Gruß

    mic
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  7. #17
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    29.11.2006
    Ort
    Geislingen a. d. Steige
    Alter
    32
    Beiträge
    344
    hi JoSch1337,
    ich hab das so gemacht nur mit dem timer0!
    http://martin.roboterbastler.de/elektronik/Servo.html
    https://www.roboternetz.de/wissen/in...os#Ansteuerung

    hab ich mit bis zu 16 Servos bei 16 Mhz getestet dann darf der mega aber nur noch wenige andere dinge tun.

    MfG Martin

  8. #18
    Neuer Benutzer Öfters hier
    Registriert seit
    19.07.2007
    Beiträge
    16
    @martinfunk: das hört sich vielversprechend an - ich werde das nachher alles mal ausprobieren!

    was ich noch nicht verstehe sind zeilen wie:
    TCCR2 |= (1<<WGM21) | (1<<CS20); //Prescale=1
    OCR2 = F_CPU/100000;
    diese stelle ich ja je nach quartz ein, oder? solange ich aber nur copy&past mache und nicht verstehe was ich tue bin ich jedoch immer nur auf euch angewiesen mir zu sagen wie das bei 16MHz auszusehen hat.

  9. #19
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Hallo Martin, hallo JoSch

    Mein Code ist von diesen Beispielen abgeleitet, allerdings verwende ich prescaler /8 und dafür OCRx=9. Im Orginal mit prescaler /1 wird ins OCR-Register 80 eingetragen und damit sollen die Servos mit 100-200 laufen. Das machen meine eben nicht.

    @JoSch:
    Die unterschiedlichen Taktfrequenzen der Kontroller werden durch OCRx = F_CPU/100000; wieder ausgeglichen. Wenn der Takt z.B. doppelt so hoch ist, ist der es Wert für OCR auch, der Timer braucht deshalb doppelt soviel Takte um auf OCR zu zählen, weil er aber auch doppelt so schnell zählt, gleicht es sich aus. Oje, reichlich viele doppelt, ich hoffe, das ist halbwegs verständlich...

    Gruß

    mic
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  10. #20
    Neuer Benutzer Öfters hier
    Registriert seit
    19.07.2007
    Beiträge
    16
    Hi!!
    Vielen Dank an euch alle!!
    Es hat sich nun dieser code: http://martin.roboterbastler.de/elektronik/Servo.html
    als optiimal herausgestellt! funzt zufriedenstellen - der servo hat brav alles gemacht was ich ihm gesat habe!

    Dafür gibts jetzt ein anderes Problem - just nachdem ich das Board eine Weile nach dem Test zu weiteren Zwecken wieder anschalten wollte ging es nicht an!!! TOT!!! wie kann das sein??

    Hier der Link zu einem neuen Thread den ich dafür eröffnet habe: https://www.roboternetz.de/phpBB2/viewtopic.php?t=37230

Seite 2 von 2 ErsteErste 12

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

LiFePO4 Speicher Test