NerdKits - electronics education for a digital generation

You are not logged in. [log in]

NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

Microcontroller Programming » Duty cycle

November 04, 2010
by LindaEC
LindaEC's Avatar

How would I go about inputing a certain duty cycle and have the processor tell me the on and off time.

November 04, 2010
by esoderberg
esoderberg's Avatar

LindaEC,

Below are basic blocks of code that will measure the pulse width of an input on PC4. Once you have the pulse width, duty cycle should be easy to figure.

Basic flow used - run clock in background, use interrupt to capture change in PC4, either from or to high or low, and calculate the time of each pulse.

/ Clock set up

void realtimeclock_setup() {
  // setup Timer0:
  // CTC (Clear Timer on Compare Match mode)
  // TOP set by OCR0A register
  TCCR0A |= (1<<WGM01);
  // clocked from CLK/
  // which is 16000000/64, or 250000 increments per second
  TCCR0B = 0;
  TCCR0B |= (1<<CS01) | (1<<CS00);
  // set TOP to 4
  // because it counts 0, 1, 2,3,4, 0, 1, 2 ...
  // so 0 through 4 equals 5 events
  OCR0A = 4;
  // enable interrupt on compare event
  // (250000 / 5 = 50000 per second)
  TIMSK0 |= (1<<OCIE0A);
}

// the_time will store the elapsed time
// (50000 = 1 second)
// 
// note that this will overflow eventually
//
volatile int32_t time;
volatile int32_t t1;
volatile int32_t t2;

SIGNAL(SIG_OUTPUT_COMPARE0A) {
  // when Timer0 gets to its Output Compare value,
  // elapsed time (0.00002 seconds per count).
  time++;
}

// This is what gets executed on interupt for measuring PW, set to trip with change to PC4

ISR(PCINT1_vect){

if(PINC & (1<<PC4)) {t1 = time;}// if change in PC4 plus high ---  ie start of pulse then mark start time t1

else {t2 = time; //if change in PC4 plus low -- IE end of pulse,  t2 - t1 = pulse width

}

void init_accelerometer(){

  //make PC4 input pin
  DDRC &= ~(1<<PC4);

  //Enable PIN Change Interrupt 1 - This enables interrupts on pins
  //PCINT14...8 see p70 of datasheet
  PCICR |= (1<<PCIE1);

  //Set the mask on Pin change interrupt 1 so that only PCINT12 (PC4) triggers
  //the interrupt. see p71 of datasheet
  PCMSK1 |= (1<<PCINT12);
}

int main() {
  realtimeclock_setup();

  init_accelerometer();

  // turn on interrupt handler
  sei();

while(1) {rest of your program}
November 06, 2010
by LindaEC
LindaEC's Avatar

Thanks, I will try the code you posted.

Post a Reply

Please log in to post a reply.

Did you know that binary numbers use base 2 to represent numbers, and these are important for understanding microcontroller registers? Learn more...