1
\$\begingroup\$

I want to generate a software PWM signal for 5 millisecond. using GPIO with 50 percent duty cycle and 100 KHz.

While(5ms)
{
 PIN = 1;
 delay_micro(10);
 PIN = 0;
 delay_micro(5);
 PIN = 1;
}

Is this correct or I want to do any thing else.

\$\endgroup\$
  • 2
    \$\begingroup\$ You haven't mentioned a particular microcontroller / compiler but on most the I/O pins default to being inputs, so you may also have to set the pin as an output at the start. \$\endgroup\$ – PeterJ Sep 8 '14 at 7:28
  • \$\begingroup\$ @peter-After making that port_pin as output. \$\endgroup\$ – rock_buddy Sep 8 '14 at 7:42
1
\$\begingroup\$

I'm not a big fan of the "delay" functions because they delay your whole program. I have also made this recently and to get a proper PWM I used the timer0 interrupt to toggle the outputpin every time an interrupt occurs. You can also work with a counting-loop so by example the interrupt has to occur 10 times before the output toggles.

Here is an example which worked fine for me with a PWM frequency of 1kHz. (timer0 is 8-bit timer)

 
void interrupt interrupts(void) {
    if (INTCONbits.TMR0IF == 1) {           //interrupt from timer0
        TMR0 = 0x06;                        //reload timer0
        PIN1 = !PIN1;
        if (timer0_tick_count >= speed) {     //count-loop with variable speed
            timer0_tick_count = 0;

} else { timer0_tick_count++; } INTCONbits.TMR0IF = 0; }

}

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

Your code includes an invalid while-clause, a redundant PIN = 1 statement and the duty cycle would be 2/3 since you wait 10us in on-state and 5us in off-state.

Assuming that you want to use avr-gcc and have the output at PA2 the code would look like that:

#define PRT PORTA
#define PIN PA2

while (1) {
    PRT |= 1 << PIN;
    _delay_us(5);
    PRT &= ~(1 << PIN);
    _delay_us(5);
}

Note, that this will not be exactly 100kHz due to the fact that the setting of the pin will take some time too.

As maike1 stated, it is always better to use interrupts or - for PWM - compare units to do this since you are busy waiting and can't do anything else while generating a PWM.

| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ It should also be noted that the loop will take some time to execute. There is a JMP after each loop execution. \$\endgroup\$ – Connor Wolf Sep 8 '14 at 7:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.