Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Write a C program to generate a 4 kHz, 80 percent duty cycle waveform. (Without

ID: 3765575 • Letter: W

Question

Write a C program to generate a 4 kHz, 80 percent duty cycle waveform. (Without using PWM module) Design a circuit that can scale the voltage from the range of 0 mV 100 mV to the range of 0 V~ 5 V. Design a circuit that can shift and scale the voltage from the range of 2 V ~ 2.5 V to the range of 0 V ~ 5 V. Suppose that there is a 10-bit A/D converter with VRL = 2 V and VRH = 4 V. Find the corresponding voltage values for the A/D conversion results of 40, 100,240, 500, 720, 800, and 1000. Write a C program to generate an interrupt 20ms after the rising edge on pin PT2 is detected. (You must use timer input capture functionality to detect the rising edge) What is the slowest clock signal that can be generated from the PWM output? Write an instruction sequence to generate a 160-kHz digital waveform with 80 percent duty cycle from the PWM2 pin output. Use left-aligned mode. Write an instruction sequence to generate a 120-kHz digital waveform with 40 percent duty cycle from the PWM2 pin output. Use center-aligned mode. Using the Successive Approximation algorithm (used for A/D conversion), show the steps involved in converting an analog input voltage of 1.75 V to an 8-bit digital code (89) on the Voltage-time graph below (cycle-by-cycle). Label the values properly.

Explanation / Answer

Ans1

#include <stdio.h>
int pwm(unsigned t, unsigned dc)
{
unsigned cycle=t%256;
return cycle<dc;
}
int main(int argc, char *argv[])
{
unsigned t;
unsigned dc=128;
if (argc==1)
    {
      fprintf(stderr,"equal PWM demo by Al Williams "
        "Next time, specify duty cycle (0-255) "
              "This time, using 128");
    }
else
    dc=(unsigned)atoi(argv[1]);
dc&=0xFF; // force to byte
for (t=0;t<512;t++)
    {
      printf("%c",pwm(t,dc)?'-':'_');
    }
putchar(' ');
return 0;
}

Ans2

Setup values acoordingly in the above figure for V1, R1, R2 and R3 for solving parts (1),(2) and (3) of the problem.

Ans3

#include <avr/interrupt.h>
#include <avr/io.h>
#include <avr/sleep.h>

#include "project.h"

volatile uint16_t pwm_incoming;
volatile struct
{
uint8_t pwm_received: 1;
}
intbits;

void
ioinit(void)
{
counter_hi = 0;
flags = 0;

/*
   * Timer 0 runs as phase-correct PWM at full clock, OC0B connects to
   * the PWM engine.
   */
TCCR0A = (1 << COM0B1) | (1 << WGM00);
TCCR0B = (1 << CS00);
OCR0A = 255;

#if defined(__AVR_ATtiny13__)
TIMSK0 = (1 << TOIE0) | (1 << OCIE0A);

# define F_CPU 1200000ul
/* Minimal PWM pulse width is 920 us. */
# define MIN_PWM_VAL ((920ul * F_CPU) / 1000000ul)
/* Maximal PWM pulse width is 2120 us */
# define MAX_PWM_VAL ((2120ul * F_CPU) / 1000000ul)

#elif defined(__AVR_ATtiny25__) ||
   defined(__AVR_ATtiny45__) ||
   defined(__AVR_ATtiny85__)

# define F_CPU 1000000ul
/*
   * We use a prescaler of 16 here to avoid the 32-bit calculations
   * below.
   */
/* Minimal PWM pulse width is 920 us. */
# define MIN_PWM_VAL ((920ul * F_CPU) / 16 / 1000000ul)
/* Maximal PWM pulse width is 2120 us */
# define MAX_PWM_VAL ((2120ul * F_CPU) / 16 / 1000000ul)

#else
# error "Don't know how to run on your MCU_TYPE."
#endif

PCMSK = (1 << 4);
GIFR = (1 << PCIF);
GIMSK = (1 << PCIE);

DDRB = (1 << PB1);
PORTB = 0;

sei();
}

#if defined(__AVR_ATtiny25__) ||
   defined(__AVR_ATtiny45__) ||
   defined(__AVR_ATtiny85__)
ISR(PCINT0_vect)
{
uint8_t tcnt1;

if (PINB & (1 << 4))
    {
      /* Start timer 1 with a prescaler of 16. */
      TCNT1 = 0;
      TCCR1 = (1 << CS12) | (1 << CS10);
      return;
    }

/* Stop timer 1, current value is pulse width. */
tcnt1 = TCNT1;
TCCR1 = 0;
GIMSK &= ~(1 << PCIE);

pwm_incoming = tcnt1;
intbits.pwm_received = 1;
}
#endif /* ATtinyX5 */

int
main(void)
{

ioinit();

for (;;)
    {
      if (intbits.pwm_received)
   {
      intbits.pwm_received = 0;
#if defined(__AVR_ATtiny13__)
      if (pwm_incoming < MIN_PWM_VAL)
        pwm_incoming = MIN_PWM_VAL;
      else if (pwm_incoming > MAX_PWM_VAL)
        pwm_incoming = MAX_PWM_VAL;
      OCR0B = (pwm_incoming - MIN_PWM_VAL) * 255ul / (MAX_PWM_VAL - MIN_PWM_VAL);
#else
      OCR0B = (pwm_incoming - MIN_PWM_VAL) * 255u / (MAX_PWM_VAL - MIN_PWM_VAL);
#endif
      GIFR = (1 << PCIF);
      GIMSK |= (1 << PCIE);
   }
      sleep_mode();
    }
}

Ans4

Assuming an 8 MHz bus clock and left-aligned waveforms, the longest period is achieved using an 8-bit PWMPER register and the slowest Clock S. The slowest Clock SA or SB is formed by dividing the bus clock by 128 to give Clock A or B and then by setting PWSCAL to $00 which divides Clock A or B by 512. The period is PWMPER times this clock period.

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote