Neste exemplo vou demostrar como criar 3 pwm que podem por exemplo acionar leds RGB,como eu não tinha nenhum led aqui RBG peguei 3 leds de alto brilho (azul,verde,vermelho) coloquei todos juntos e para dar um efeito mais homogêneo encostei eles em uma barra da cola de silicone(dessa de cola quente), o resultado fica próximo ao de um led RGB.
Para a montagem física coloquei 3 valores diferente de resistor devido as diferença de brilho de cada led(isso depende da potencia de cada led), o circuito funciona com 5V. O microcontrolador usado é o PIC16F648 mas o código pode ser usado também no PIC16F628.
A ideia é criar uma variável("tamanho_periodo") que irá controlar a largura do pulso em todas as três saídas ,e mais três variáveis que fará a variação da largura do pulso("larg_pwm1","larg_pwm2" e"larg_pwm2") em cada pino.Veja que neste exemplo limitei a largura máxima em 20 incrementos(mas isso pode ser alterado) .
Veja a demontração:
O esquemático:
O código fonte :
/* * Gerando pwm sem usar o modulo CCP - MPlab XC8 * * Compilador : MPlabXC8 * Microcontrolador: 16F648A * Autor: aguivone * Versão: 1 * Data : 21 de março de 2014 */ #include <stdio.h> #include <string.h> #include <stdlib.h> #include <xc.h> ////////////////////////defines///////////////////////////////////////////////////////////////////////////////////////// #define PWM1 PORTBbits.RB5 #define PWM2 PORTBbits.RB6 #define PWM3 PORTBbits.RB7 /////////////////////////////////////////////////////////configuraçôes////////////////////////////////////////////////// #pragma config FOSC = INTOSCIO // Oscillator Selection bits (INTOSC oscillator: I/O function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN) #pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled) #pragma config PWRTE = ON // Power-up Timer Enable bit (PWRT enabled) #pragma config MCLRE = OFF // RA5/MCLR/VPP Pin Function Select bit (RA5/MCLR/VPP pin function is digital input, MCLR internally tied to VDD) #pragma config BOREN = OFF // Brown-out Detect Enable bit (BOD disabled) #pragma config LVP = OFF // Low-Voltage Programming Enable bit (RB4/PGM pin has PGM function, low-voltage programming enabled) #pragma config CPD = OFF // Data EE Memory Code Protection bit (Data memory code protection off) #pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off) /////////////////////////////////////variaveis utilizadas/////////////////////////////////////////////////////////////////// int larg_pwm1 = 5; //a largura de pulso é limitada ao valor maximo do periodo(no caso 20) int larg_pwm2 = 5; int larg_pwm3 = 5; int tamanho_periodo = 20; //incrementos máximos int temporizador = 0; unsigned long tempo_mudar = 0; int cor = 0; ///////////////////////////////////////////////////interrupção////////////////////////////////////////////////////////////// void interrupt interrupcao(void)//vetor de interrupção { if (T0IF) {//interrupção do timer0 - estoura quando atinge 255(0XFF) temporizador++; if (temporizador >= larg_pwm1) {PWM1 = 0;} if (temporizador >= larg_pwm2) {PWM2 = 0;} if (temporizador >= larg_pwm3) {PWM3 = 0;} if (temporizador >= tamanho_periodo) { //fim de periodo todos vão para nivel alto // o periodo é de 2,49ms aprox. 401hz PWM1 = 1; PWM2 = 1; PWM3 = 1; temporizador = 0; tempo_mudar++; if (tempo_mudar >= 40) { //100ms = 40; //(tempo = valor em ms/2,49) tempo_mudar = 0; switch (cor) { case 0: { if (larg_pwm1 >= tamanho_periodo) { larg_pwm1 = 5; cor++; } else { larg_pwm1++; } } break; case 1: { if (larg_pwm2 >= tamanho_periodo) { larg_pwm2 = 5; cor++; } else { larg_pwm2++; } } break; case 2: { if (larg_pwm3 >= tamanho_periodo) { larg_pwm3 = 5; cor++; } else { larg_pwm3++; } } break; case 3: { if (larg_pwm1 >= tamanho_periodo) { larg_pwm1 = 5; larg_pwm2 = 5; cor++; } else { larg_pwm1++; larg_pwm2++; } } break; case 4: { if (larg_pwm1 >= tamanho_periodo) { larg_pwm1 = 5; larg_pwm3 = 5; cor++; } else { larg_pwm1++; larg_pwm3++; } } break; case 5: { if (larg_pwm3 >= tamanho_periodo) { larg_pwm3 = 5; larg_pwm2 = 5; cor++; } else { larg_pwm3++; larg_pwm2++; } } break; case 6: { if (larg_pwm1 >= tamanho_periodo) { larg_pwm1 = 5; larg_pwm2 = 5; larg_pwm3 = 5; cor = 0; } else { larg_pwm1++; larg_pwm2++; larg_pwm3++; } } break; } } } TMR0 = 250; //reinicia timer com o valor calculado T0IF = 0; } } void inicializa_timer0() { OPTION_REG = 0; //timer0 com prescaler dividido por 2 T0IE = 1; //habilita interrupção do timer0 TMR0 = 250; //zera registrador de contagem PEIE = 1; //habilita interrupção de perifericos do pic GIE = 1; //GIE: Global Interrupt Enable bit } //////////////////////////////////////////////////////Rotina principal/////////////////////////////////////////////////////////////// void main(void) { TRISB = 0; //configura como saida TRISA = 0X00; //configura portA como saida PORTB = 0; // limpar as portas que estão configuradas como saidas inicializa_timer0(); CMCON = 7; // desliga todos os comparadores for (;;) {//faz nada }//loop infinito }
Plá, gostei da ideia, porém sou novo em microcontroladores, sempre que encontro códigos que me poderia ser útil, da erro nos includes, exemplo: pwm.h - xc.h, não sei como resolver isso.
ResponderExcluirO que preciso é controlar um servo nas pocisões de 90º e 0º, me ajude por favor.
Muito obrigado!!