+ Post New Thread
Results 1 to 8 of 8
  1. #1
    Full Member level 6
    Points: 2,603, Level: 11

    Join Date
    Jan 2013
    Location
    India
    Posts
    371
    Helped
    3 / 3
    Points
    2,603
    Level
    11

    PWM in Atmega328 using Code Vision AVR

    Hello,

    I have to use all the 6 PWM pins in Atmega328 using codevision AVR. However i am stuck with configuring in Timer0 PWM itself. Below is the simple code with nothing in main and timer0 overflow interrupt and compare match A and B interrupt. Here pins OCR0A and OCR0B are toggling with same frequency though i am changing OCR0A and OCR0B values in Timer0 overflow interrupt. Can anybody tell me why is this happening.

    Code:
    #include 
    
    // Timer 0 overflow interrupt service routine
    interrupt [TIM0_OVF] void timer0_ovf_isr(void)
    {
    OCR0A=250;                         ///////////////////////Change in OCR0A value
    OCR0B = 100;                       ///////////////////////Change in OCR0B value
    PORTD.6 = 1;
    PORTD.5 = 1;    
    }
    
    // Timer 0 output compare A interrupt service routine
    interrupt [TIM0_COMPA] void timer0_compa_isr(void)
    {
    
    PORTD.6 = 0;
    }
    
    // Timer 0 output compare B interrupt service routine
    interrupt [TIM0_COMPB] void timer0_compb_isr(void)
    {
    
    PORTD.5 = 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=In Func1=In Func0=In 
    // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
    PORTB=0x00;
    DDRB=0x00;
    
    // 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=0x00;
    DDRC=0x00;
    
    // Port D initialization
    // Func7=In Func6=Out Func5=Out Func4=In Func3=In Func2=In Func1=Out Func0=Out 
    // State7=T State6=0 State5=0 State4=T State3=T State2=T State1=0 State0=0 
    PORTD=0x00;
    DDRD=0x63;
    
    // Timer/Counter 0 initialization
    // Clock source: System Clock
    // Clock value: 8000.000 kHz
    // Mode: Normal top=FFh
    // OC0A output: Toggle on compare match
    // OC0B output: Toggle on compare match
    TCCR0A=0x50;
    TCCR0B=0x01;
    TCNT0=0x00;
    OCR0A=0x0A;
    OCR0B=0x0A;
    
    // Timer/Counter 1 initialization
    // Clock source: System Clock
    // Clock value: Timer 1 Stopped
    // Mode: Normal top=FFFFh
    // OC1A output: Discon.
    // OC1B output: Discon.
    // Noise Canceler: Off
    // Input Capture on Falling Edge
    // Timer 1 Overflow Interrupt: Off
    // Input Capture Interrupt: Off
    // Compare A Match Interrupt: Off
    // Compare B Match Interrupt: Off
    TCCR1A=0x00;
    TCCR1B=0x00;
    TCNT1H=0x00;
    TCNT1L=0x00;
    ICR1H=0x00;
    ICR1L=0x00;
    OCR1AH=0x00;
    OCR1AL=0x00;
    OCR1BH=0x00;
    OCR1BL=0x00;
    
    // Timer/Counter 2 initialization
    // Clock source: System Clock
    // Clock value: Timer 2 Stopped
    // Mode: Normal top=FFh
    // OC2A output: Disconnected
    // OC2B output: Disconnected
    ASSR=0x00;
    TCCR2A=0x00;
    TCCR2B=0x00;
    TCNT2=0x00;
    OCR2A=0x00;
    OCR2B=0x00;
    
    // External Interrupt(s) initialization
    // INT0: Off
    // INT1: Off
    // Interrupt on any change on pins PCINT0-7: Off
    // Interrupt on any change on pins PCINT8-14: Off
    // Interrupt on any change on pins PCINT16-23: Off
    EICRA=0x00;
    EIMSK=0x00;
    PCICR=0x00;
    
    // Timer/Counter 0 Interrupt(s) initialization
    TIMSK0=0x07;
    // 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)
          {
          // Place your code here
    
          };
    }
    I checked toggling frequency using scope.

    Thanx

    •   AltAdvertisment

        
       

  2. #2
    Super Moderator
    Points: 69,518, Level: 64
    Achievements:
    7 years registered
    Awards:
    Most Frequent Poster 3rd Helpful Member

    Join Date
    Apr 2014
    Posts
    14,202
    Helped
    3243 / 3243
    Points
    69,518
    Level
    64

    Re: PWM in Atmega328 using Code Vision AVR

    Hi,

    It depends on configuration...and I didn't go through your setup....
    But with OCRx registers for PWM you don't change frequency, you change duty cycle.

    To do this you don't use the "toggle pin" but you use one of the true PWM setup.
    Use CTC mode.
    You don't need interrupts, you don't need ISRs, all PWM can be done by hardware without processing power (just setup).

    There are more than enough examples and discussions about PWM, first go through them, then refer to one if the examples.

    Klaus
    Please donīt contact me via PM, because there is no time to respond to them. No friend requests. Thank you.



    •   AltAdvertisment

        
       

  3. #3
    Full Member level 6
    Points: 2,603, Level: 11

    Join Date
    Jan 2013
    Location
    India
    Posts
    371
    Helped
    3 / 3
    Points
    2,603
    Level
    11

    Re: PWM in Atmega328 using Code Vision AVR

    Thank you Klausst,
    It means we don't need even Timer0 interrupt to modify the values of OCRx registers.



    •   AltAdvertisment

        
       

  4. #4
    Super Moderator
    Points: 69,518, Level: 64
    Achievements:
    7 years registered
    Awards:
    Most Frequent Poster 3rd Helpful Member

    Join Date
    Apr 2014
    Posts
    14,202
    Helped
    3243 / 3243
    Points
    69,518
    Level
    64

    Re: PWM in Atmega328 using Code Vision AVR

    Hi,

    You may use the interrupt, but thereīs no need for it.

    Read the datasheet: Iīm about sure you may wirte to the OCRx registers at any time, but internally its updated when the conter restarts.

    Klaus
    Please donīt contact me via PM, because there is no time to respond to them. No friend requests. Thank you.



  5. #5
    Full Member level 6
    Points: 2,603, Level: 11

    Join Date
    Jan 2013
    Location
    India
    Posts
    371
    Helped
    3 / 3
    Points
    2,603
    Level
    11

    Re: PWM in Atmega328 using Code Vision AVR

    Thanx Klausst,
    I used timer0 interrupt and used OCR registers for PWM. now when timer0 interrupt occurs, OCR registers get their values for pulse width. It's working now.



  6. #6
    Super Moderator
    Points: 69,518, Level: 64
    Achievements:
    7 years registered
    Awards:
    Most Frequent Poster 3rd Helpful Member

    Join Date
    Apr 2014
    Posts
    14,202
    Helped
    3243 / 3243
    Points
    69,518
    Level
    64

    Re: PWM in Atmega328 using Code Vision AVR

    Hi,

    may I ask where you see the benefit in using interrupts?

    out of curiosity I checked the datasheet. It says:
    The OCR0x Registers are double buffered when using any of the Pulse Width Modulation (PWM) modes. For
    the normal and Clear Timer on Compare (CTC) modes of operation, the double buffering is disabled. The
    double buffering synchronizes the update of the OCR0x Compare Registers to either top or bottom of the
    counting sequence. The synchronization prevents the occurrence of odd-length, non-symmetrical PWM pulses,
    thereby making the output glitch-free.
    The OCR0x Register access may seem complex, but this is not case. When the double buffering is enabled, the
    CPU has access to the OCR0x Buffer Register, and if double buffering is disabled the CPU will access the
    OCR0x directly.
    Klaus
    Please donīt contact me via PM, because there is no time to respond to them. No friend requests. Thank you.



  7. #7
    Full Member level 6
    Points: 2,603, Level: 11

    Join Date
    Jan 2013
    Location
    India
    Posts
    371
    Helped
    3 / 3
    Points
    2,603
    Level
    11

    Re: PWM in Atmega328 using Code Vision AVR

    Hello,
    I have to generate sine waves for inverter. So using timer interrupts.

    Thanx



    •   AltAdvertisment

        
       

  8. #8
    Super Moderator
    Points: 69,518, Level: 64
    Achievements:
    7 years registered
    Awards:
    Most Frequent Poster 3rd Helpful Member

    Join Date
    Apr 2014
    Posts
    14,202
    Helped
    3243 / 3243
    Points
    69,518
    Level
    64

    Re: PWM in Atmega328 using Code Vision AVR

    Hi,

    I have to generate sine waves for inverter. So using timer interrupts.
    Makes sense.
    You didnīt mention SPWM before, thus I was confused...

    Still you could do it without interrupt....But polling flags in main loop isn't an elegant solution. I also prefer the interrupt solution for SPWM.

    Klaus
    Please donīt contact me via PM, because there is no time to respond to them. No friend requests. Thank you.



--[[ ]]--