Using timer for PWM

2020-02-08 12:29发布

many low-end PICs (or other MCUs) don't have pwm functionality. One way to create pwm on those chips would be to use a timer interrupt.

here is an example to create a pair of complimentary pwm output on a 16f684 - the same approach works for other chips too.

=========================

//using tmr0 to generate pwm output
#include <htc.h>                                                        //we use picc
#include "gpio.h"
#include "delay.h"

__CONFIG(MCLRDIS & BORDIS & WDTDIS & PWRTEN & HS);

//hardware configuration
#define PWM_PORT                        PORTC
#define PWM_DDR                                TRISC
#define PWM_P                                (1<<0)                        //complementary pwm output pins
#define PWM_N                                (1<<1)
//#define PWM_DC                                0x2f                        //pwm duty cycle
#define PWM_DC_MIN                        0x01                        //minimum dc
#define PWM_DC_MAX                        0xfe                        //maximum dc

#define PWM_DLY                                500                                //how long to run each pwm sequence, in ms
//end hardware configuration

volatile unsigned char _pwm_dc=PWM_DC_MIN;                                //pwm duty cycle

void interrupt isr(void) {
        //use tmr0 for pwm
        TMR0IF=0;                                                                //turn off the flag
        TMR0+= _pwm_dc;                                                        //load the offset
        //_pwm_dc^=0xff;                                                        //find its complementary
        _pwm_dc=-_pwm_dc;                                                //find the complementary
        IO_FLP(PWM_PORT, PWM_P | PWM_N);                //flip the output
}

void pwm_init(void) {                                                //initialize the tmr0 for pwm
        //set up the io pins
        IO_OUT(PWM_DDR, PWM_P | PWM_N);                        //led as output
        IO_SET(PWM_PORT, PWM_P);                                //clear spi indicator
        IO_CLR(PWM_PORT, PWM_N);

        T0CS=0;                                                                        //tmr0 on f_cpu
        PSA=0;                                                                        //prescaler assigned to tmr0
        PS2=0, PS1=1, PS0=1;                                        //prescaler = 1:16
        TMR0=_pwm_dc;                                                        //reset tmr0 counter
        TMR0IE=1;                                                                //enable tmr0 interrupt
}
       
#define pwm_dc(n)                                {_pwm_dc=(n);
                                                                IO_SET(PWM_PORT, PWM_P);
                                                                IO_CLR(PWM_PORT, PWM_N);}        //update the duty cycle

void mcu_init(void) {
        ANSEL=0x00;                                                                //all pins gpio
        CMCON0=0x07;                                                        //all analog comparators off
        IRCF2=1, IRCF1=1, IRCF0=1;                                //running at 4mhz
}

int main(void) {
        unsigned char dc;
       
        mcu_init();                                                                //initilaize the mcu
        pwm_init();                                                                //initialize pwm
        ei();                                                                        //enable interrupt
       
        while (1) {
                for (dc=PWM_DC_MIN; dc<PWM_DC_MAX; dc+=1) {
                        pwm_dc(dc);                                                //uddate the dc
                        delay_ms(PWM_DLY);                                //wait for the new dc to take effect
                }
                //t=_25LC_read(_25LC_WIPER1, _25LC_CMD_READ);
                //IO_FLP(PWM_PORT, PWM_P);
        }
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。