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

[atmega88] gcc 4.2.2 /AVR Studio 4.14.589, PWM na T1

GreG$ 24 Wrz 2008 16:52 2052 4
  • #1 5567201
    GreG$
    Poziom 13  
    Witam.

    Czy komuś działa Fast PWM (mode 14) na tym procku?
    Zresztą ! czy działa wam jakikolwiek PWM zgodnie z dokumentacją???
    Męczę ten temat dość długo i coś mnie trafia.
    Debugger na T1 robi dziwne rzeczy w każdym razie nie całkiem z datatsheetem.
    
    void init_t1( const uint OCR1A_val, const uint OCR1B_val)
    {
    	OCR1A  = OCR1A_val;
       OCR1B  = OCR1B_val;
    	TCNT1  = 0;
       ICR1 = MAX_PWM;
    
    	TCCR1A = (1<<COM1A1)|(0<<COM1A0)|
                (0<<COM1B1)|(0<<COM1B0)|
                (0<<FOC1A)|(0<<FOC1B)|
                (1<<WGM11)|(0<<WGM10);//Fast PWM, 10-bit [s.132]
    
    	TCCR1B = (0<<ICNC1)|(0<<ICES1)|
                (1<<WGM13)|(1<<WGM12)|//Fast PWM, 10-bit [s.132]
                (0<<CS12)|(0<<CS11)|(0<<CS10);
    }


    
    void check_input_voltage( void)
    {// na tej podstawie wypełnic data.set_val
       if((uint)sadc.tab[ADC_IN] > 20)
       OCR1A = (uint)sadc.tab[ADC_IN];
    }
    
    SIGNAL (SIG_ADC)
    {// get & check input ADC value & correct PWM on timer1, if needed
       sadc.tab[sadc.channel] = get_adc16();
    
       switch( sadc.channel)
       {
       case ADC_OUT:  check_pwm_voltage();
                      sadc.channel = ADC_IN;
                      break;
       case ADC_IN:
       default:       check_input_voltage();
                      sadc.channel = ADC_OUT;
                      break;
       };
    }


    
    int main()
    {
       init_io();
       //init_clock( eeprom_read_byte( &adrCLK_PS));
       init_t0( eeprom_read_byte( &adrOCR0A_VAL), eeprom_read_byte( &adrOCR0B_VAL));
       init_t1( eeprom_read_word( &adrOCR1A_VAL), eeprom_read_word( &adrOCR1B_VAL));
       init_adc();
    
       t0_start( eeprom_read_byte( &adrCLK0_select));
    #if defined (__AVR_ATmega88__)||(__AVR_ATtiny25__)||(__AVR_ATtiny45__)||(__AVR_ATtiny85__)
       t0oc0a_on();
    #endif
       sadc.channel = ADC_OUT;
    
       t1_start( eeprom_read_byte( &adrCLK1_select));
       //t1oc1a_on();
       sei();
    
       while(1);
    return 0;
    }


    Jak ktoś temat przerobił i wie co może być "nie tak" to podeślę cały projekt dla lepszego poglądu.
  • #3 5567353
    GreG$
    Poziom 13  
    Balu napisał:
    No na pewno będzie działał, jeśli niewybierzesz żadnego zegara... na bank!:)


    Masz rację... ale jak wspomniałeś "jeśli"...

    w funkcji main jest:
    
    t1_start( eeprom_read_byte( &adrCLK1_select));
    


    zdefinowane:
    
    #define t1_start( prescaler)  TCCR1B |= prescaler
    

    natomiast prescaler jest większy od zera (dokładnie == 1)
  • #5 5568004
    GreG$
    Poziom 13  
    Nie ma znaczenia, w którym miejscu odpalę zegar. W kodzie mogę włączać i wyłączać go w dowolnym miejscu. (zrobiłem Ci jednak przyjemność :D i sprawdziłem - bez znaczenia)

    Dodam trochę o sprzęcie. Na ADC0 wisi potencjometr wieloobrotowy 5K i na razie kod ma tylko przepisać wartość ADCW do OCR1A. No i PINB1/OC1A ma zap#$@#$%, żeby ładny PWMik wylazł.
    Specjalnie zrezygnowałem z assemblera, żeby było szybciej i łatwiej... no i mam...

    najbardziej wnerwia mnie to, ze debugger AVRStudio zasuwa licznikiem UP a potem DOWN w mode 14, 15 (i chyba w 7 tez) tak jak w trybie "Phase Correct"
REKLAMA