logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Sygnał PWM na attiny25. Nie włącza się PWM-ka OC1B.

mati1988k 11 Sty 2011 12:23 2357 5
REKLAMA
  • #1 8990044
    mati1988k
    Poziom 13  
    Witam.

    Napisałem taki prosty program:

    #include <avr/io.h>
    #include <util/delay.h>
    #include <stdlib.h>
    
    int main(void)
    {
        DDRB  = 0xFF;
    
        TCCR1 = 1<<CS12;
        GTCCR = 1<<PWM1B | 1<<COM1B1 | 1<<FOC1B;
        OCR1B = 125;
    
        TCCR0A = 1<<COM0A1 | 1<<COM0B1 | 1<<WGM00 | 1<<WGM01;
        TCCR0B = 1<<FOC0A | 1<<FOC0B | 1<<CS01;
        OCR0A = 125;
        OCR0B = 125;
    
        int a,b,c;
       
        srand (100);    // Zamiast 100 mozna dac odczyt z wiszacej nozki ADC
    
        while(1)
        {
            a=rand()%255;
            b=rand()%255;
            c=rand()%255;   
    
            OCR1B = a;
            _delay_ms(10000);
            OCR0A = b;
            _delay_ms(10000);
            OCR0B = c;
            _delay_ms(10000);
        }
    }


    Jednak nie włącza mi się w ogóle PWM-ka OC1B. Już kilka razy czytałem notę ale nie mogę znaleźć miejsca gdzie robię błąd.
  • REKLAMA
  • #2 8990099
    jarekz_2
    Poziom 16  
    mati1988k napisał:
    Witam. Napisałem taki prosty program:(...)

    Ja w ATtiny25 wytwarzam PWM na wyjściach OC1A i OC1B i robię to tak:
    	.EQU	PWM_PERIOD				= 16
    ;inicjalizacja:
    		ldi		R24,PWM_PERIOD*120/256
    		out		OCR1A,R24
    		ldi		R24,PWM_PERIOD*120/256
    		out		OCR1B,R24
    		ldi		R24,PWM_PERIOD-1	;80MHz / 1 / 16 = 5MHz
    		out		OCR1C,R24
    		ldi		R24,0b11100001		;CTC1=1 PWM1A=1 COM1A=10
    							;CS1=0001 (PCK/1)
    		out		TCCR1,R24
    		ldi		R24,0b01100000		;TSM=0 PWM1B=1 COM1B=10
    							;FOC1B=0 FOC1A=0 PSR1=0 PSR0=0
    		out		GTCCR,R24
    ;ustawienie szerokości impulsów w programie:
    		out		OCR1A,R24		;A = 0000aaaa
    		out		OCR1B,R25		;B = 0000bbbb
    

    U Ciebie brakuje chyba ustawienia okresu przebiegu (rejestr OCR1C).
  • REKLAMA
  • #3 8990408
    Electix
    Poziom 21  
    Na pierwszy rzut oka widzę że zapomniałeś przy inicjalizacji kanału PWM1 ustawić bity COM1x1 i COM1x0. Po resecie są one ustawione na 0 a ta konfiguracja powoduje odłączenie wyjść OC1x. Patrz tabelka na str. 89 noty. :)
  • REKLAMA
  • #4 8991204
    mati1988k
    Poziom 13  
    Po ustawianiu OCR1C dalej program nie działa, w ogóle nie rusza licznik w timer 1.

    A COM1B1 ustawiam tutaj : GTCCR = 1<<PWM1B | 1<<COM1B1 | 1<<FOC1B;

    Może po prostu symulator w AVR studio coś szwankuje ? Bo programu nie wgrywałem na procka tylko testuje go na kompie.
  • REKLAMA
  • #5 8993212
    jarekz_2
    Poziom 16  
    mati1988k napisał:
    Po ustawianiu OCR1C dalej program nie działa, w ogóle nie rusza licznik w timer 1.
    A COM1B1 ustawiam tutaj : GTCCR = 1<<PWM1B | 1<<COM1B1 | 1<<FOC1B

    Masz bałagan w kodzie, niektóre operacje dotyczą Timera 1, a niektóre Timera 0. Chyba nie tak miało być?...
    mati1988k napisał:
    Może po prostu symulator w AVR studio coś szwankuje ? Bo programu nie wgrywałem na procka tylko testuje go na kompie.

    Też możliwe. Zwłaszcza że odczekujesz po 10 sekund między operacjami - może symulator rozciąga te czasy i praktycznie wciąż odlicza te opóźnienia...
  • #6 8993335
    Electix
    Poziom 21  
    A przepraszam nie zauważyłem... :P Teraz dokładniej przejrzałem sobie DSa od tego procka. I mam takie pytanie po co odpalasz FOCxx? W opisie bitów FOCxx w DS jest takie zdanie na końcu:
    Cytat:

    FOC1B is not in use if PWM1B bit is set.

    Sprawdź jeszcze dokładnie ustawianie źródła taktowania tego PWM bo on może śmigać albo z zegara wewnętrznego procesora (tryb synchroniczny) albo może śmigać asynchronicznie pędzony zegarem z wbudowanej w procesor pętli PLL. Zwróć uwagę że ten PWM1 ma nieco inną konstrukcję niż PWM0.
    Przychodzi mi do głowy jeszcze jedna rzecz. Sprawdź czy nie powinieneś operacji tego typu:
    GTCCR = 1<<PWM1B | 1<<COM1B1 | 1<<FOC1B

    zapisać w taki sposób:
    GTCCR = (1<<PWM1B | 1<<COM1B1 | 1<<FOC1B)

    Nie uwzględnienie priorytetów operatorów jest często ciężko wykrywalnym błędem.
    No i na końcu można rozważyć opcję że może coś być nie tak z symulatorem...
REKLAMA