Use adc to measure pwm signals dutycycle

Go To Last Post
9 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have been trying for a while, and I'm stuck!
Is this possible? do anyone know?
I have tried both single mode and free running mod.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Please learn to read the forum guidelines before posting:

https://www.avrfreaks.net/index.p...

(so I'm moving this from Academy to AVR forum)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well, if it slow enough you can do it.

Or if you use a low pass filter to get a DC value out which you feed to the ADC.

Otherwise using the timers is more common for this.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you have a reasonable random number generator, you can sample at random times and stochastically measure the duty cycle. Otherwise, I'd think about CountZero's recommendation for a low-pass filter and measure the DC voltage.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The AVR app note 135 discusses how to use the timer input capture mode to measure PWM duty cycle. Of course if the micro you're using doesn't have a timer that supports that you'll have to use one of the other suggested methods.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Excellent App Note, NW, thanks for the reference! Here's a direct link: http://www.atmel.com/dyn/resourc...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

kmr wrote:
Excellent App Note, NW, thanks for the reference! Here's a direct link: http://www.atmel.com/dyn/resourc...

Not a problem! To their credit Atmel really does put out some useful and well thought out app notes.

Thanks for putting in the link for those that don't know where the app notes are stashed away.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

NorthwestWolf wrote:
Atmel really does put out some useful and well thought out app notes.
Agreed. I need to remember to browse their notes more often.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I use this program to measure input pwm duty cycle. but only I take 0 char. what is wrong in this program?
please help me I'm in hurry.

#include 

// I2C Bus functions
#asm
   .equ __i2c_port=0x15
   .equ __sda_bit=0
   .equ __scl_bit=1
#endasm
#define write_address_bus1 162 
#define write_address_bus2 164
#define read_address_bus1 163
#define read_address_bus2 165 
void write_eeprom1(unsigned char data, unsigned int address);
unsigned char read_eeprom1(unsigned int address);
void write_eeprom2(unsigned char data, unsigned int address);
unsigned char read_eeprom2(unsigned int address);
#include    
#include 
#include 
int intrupt_case;
unsigned int count1,count2;
unsigned int period1,period2,period3;

// Timer 1 input capture interrupt service routine
interrupt [TIM1_CAPT] void timer1_capt_isr(void)
{
// Place your code here
 switch (intrupt_case){
     case 0x00:
         TCCR1B=0x11;
         intrupt_case=0x01;
         break;
     case 0x01:
         TCCR1B=0x50;
         count1=ICR1H;
         count2=ICR1L;
         count1=count2|(count1<<8 );
         intrupt_case=0x02;
         break;
     case 0x02:
         TCNT1=0x0000;
         TIMSK=0x00;
         intrupt_case=0x12;
         break;
}; 
}

#define ADC_VREF_TYPE 0x40
// Read the AD conversion result
unsigned int read_adc(unsigned char adc_input)
{
ADMUX=adc_input|ADC_VREF_TYPE;
// Start the AD conversion
ADCSRA|=0x40;
// Wait for the AD conversion to complete
while ((ADCSRA & 0x10)==0);
ADCSRA|=0x10;
return ADCW;
}

// Declare your global variables here

void main(void)
{
//local variable                  
unsigned int input1,counter1,counter2;
char input1h,input1l;
char input2h,input2l;
char input3h,input3l;
char var1,var2;

intrupt_case=0x00; 
period1=0x00;
period2=0x00;
period3=0x00;              
counter1=0;
counter2=0;
// Declare your local variables here

// Input/Output Ports initialization
// Port A initialization
// Func0=In Func1=In Func2=In Func3=In Func4=In Func5=In Func6=In Func7=In 
// State0=T State1=T State2=T State3=T State4=T State5=T State6=T State7=T 
PORTA=0x00;
DDRA=0x00;

// Port B initialization
// Func0=In Func1=In Func2=In Func3=In Func4=In Func5=In Func6=In Func7=In 
// State0=T State1=T State2=T State3=T State4=T State5=T State6=T State7=T 
PORTB=0x00;
DDRB=0x00;

// Port C initialization
// Func0=In Func1=In Func2=In Func3=In Func4=In Func5=In Func6=In Func7=In 
// State0=T State1=T State2=T State3=T State4=T State5=T State6=T State7=T 
PORTC=0x00;
DDRC=0x00;

// Port D initialization
// Func0=In Func1=In Func2=In Func3=In Func4=Out Func5=Out Func6=In Func7=In 
// State0=T State1=T State2=T State3=T State4=0 State5=0 State6=T State7=T 
PORTD=0x00;
DDRD=0x30;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=FFh
// OC0 output: Disconnected
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Ph. correct PWM top=ICR1
// OC1A output: Non-Inv.
// OC1B output: Non-Inv.
// Noise Canceler: Off
// Input Capture on Rising Edge
TCCR1A=0xA2;
TCCR1B=0x50;
TCNT1H=0x00;
TCNT1L=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
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
GICR|=0x00;
MCUCR=0x00;
MCUCSR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;

// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: Off
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud rate: 9600
UCSRA=0x00;
UCSRB=0x08;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x33;

// Analog Comparator initialization
// Analog Comparator: On
// Analog Comparator Input Capture by Timer/Counter 1: On
// Analog Comparator Output: Off
ACSR=0x04;
SFIOR=0x00;

// ADC initialization
// ADC Clock frequency: 125.000 kHz
// ADC Voltage Reference: AVCC pin
// ADC High Speed Mode: Off
// ADC Auto Trigger Source: None
ADMUX=ADC_VREF_TYPE;
ADCSRA=0x86;
SFIOR&=0xEF;

// I2C Bus initialization
i2c_init(); 

ICR1H=0x0f;
ICR1L=0xa0;
while (1)
      {
      input1=read_adc(3);
      input1l=input1&0x00ff;
      input1h=(input1&0xff00)>>8;
      input1=read_adc(4);
      input2l=input1&0x00ff;
      input2h=(input1&0xff00)>>8;
      input1=read_adc(5);
      input3l=input1&0x00ff;
      input3h=(input1&0xff00)>>8; 
      ADCSRA=0x00;
      SFIOR=0x08;
      ADMUX.0=0;
      ADMUX.1=0;
      ADMUX.2=0;
      for (input1=0x00;input1<0x04;input1++){
         TIMSK=0x20;
         while (intrupt_case!=0x12) {}
         period1=period1+count1;
         intrupt_case=0x00;
      }      
      
       
      ADMUX.0=0;
      ADMUX.1=1;
      ADMUX.2=0;
      for (input1=0x00;input1<0x04;input1++){
         TIMSK=0x20;
         while (intrupt_case!=0x12) {}
         period2=period2+count1;
         intrupt_case=0x00;
      }                
      ADMUX.0=0;
      ADMUX.1=0;
      ADMUX.2=1;
      for (input1=0x00;input1<0x04;input1++){
         TIMSK=0x20;
         while (intrupt_case!=0x12) {}
         period3=period3+count1;
         intrupt_case=0x00;
      }
      SFIOR=0x00;
      ADMUX=ADC_VREF_TYPE;
      ADCSRA=0x86;
      SFIOR&=0xEF;
      var1=period1&0x00ff;
      var2=(period2&0xff00)>>8;
      
      printf("%c",var1);
      delay_ms(10);
      printf("%c",var2);
      delay_ms(10);  
      
      };
}