Datasheet capítulo 15 (PWM)
O que é PWM (MEC071)
Modulação por Largura de Pulso - UDESC
PULSE WIDTH MODULATION CONCEITOS E CIRCUITO-EXEMPLO
EletrônicaDigital PWM - Modulação Por Largura de Pulso - Mecaweb
Exemplo de funcionamento
Código de exemplo para acionamento das saídas 1 e 2
/*
* File: PWM_1_exemplo.c
* Author: Pilger
*
* Created on 16 de Novembro de 2017, 08:35
*/
#define _XTAL_FREQ 48000000
#define TMR2PRESCALE 16
// relação de frequencia x prescaler para xtal de 48M
// para reslução de 1000 -> 2^10 = 1023
// ps F pwm
// 1 48KHz
// 4 12KHz
// 16 3 KHz
#include <xc.h>
#include "C:\h\config_PIC18F4550.h"
//variáveis globais
long freq;
// protótipos de funções
void delay_ms(int i);
int PWM_Max_Duty(void);
void PWM1_Init(long fre);
void PWM2_Init(long fre);
void PWM1_Duty(unsigned int duty);
void PWM2_Duty(unsigned int duty);
void PWM1_Start(void);
void PWM1_Stop(void);
void PWM2_Start(void);
void PWM2_Stop(void);
void main(){
unsigned int i=0,j=0;
PWM1_Init(3000);
PWM2_Init(3000);
TRISD = 0xFF;
TRISC = 0;
PWM1_Duty(0);
PWM2_Duty(0);
PWM1_Start();
PWM2_Start();
while (1) {
if(PORTDbits.RD0 == 0 && i<1000){
while(PORTDbits.RD0==0);
i=i+100;
}
if(PORTDbits.RD1 == 0 && i>0){
while(PORTDbits.RD1==0);
i=i-100;
}
if(PORTDbits.RD2 == 0 && j<1000){
while(PORTDbits.RD2==0);
j=j+100;
}
if(PORTDbits.RD3 == 0 && j>0){
while(PORTDbits.RD3==0);
j=j-100;
}
PWM1_Duty(i);
PWM2_Duty(j);
delay_ms(10); // 10ms
}
}
// função que gera atraso em mlisegundos
void delay_ms(int i){
for ( int x = 0; x < i; x++ ) {
__delay_ms(1);
}
}
int PWM_Max_Duty(void){
return(_XTAL_FREQ/(freq*TMR2PRESCALE);
}
void PWM1_Init(long fre){
PR2 = (_XTAL_FREQ/(fre*4*TMR2PRESCALE)) - 1;
freq = fre;
}
void PWM2_Init(long fre){
PR2 = (_XTAL_FREQ/(fre*4*TMR2PRESCALE)) - 1;
freq = fre;
}
void PWM1_Duty(unsigned int duty){
if(duty<1024) {
duty = ((float)duty/1023)*PWM_Max_Duty();
CCP1CONbits.DC1B1 = duty & 2;
CCP1CONbits.DC1B0 = duty & 1;
CCPR1L = duty>>2;
}
}
void PWM2_Duty(unsigned int duty){
if(duty<1024) {
duty = ((float)duty/1023)*PWM_Max_Duty();
CCP2CONbits.DC2B1 = duty & 2;
CCP2CONbits.DC2B0 = duty & 1;
CCPR2L = duty>>2;
}
}
void PWM1_Start(void) {
CCP1CONbits.CCP1M3 = 1;
CCP1CONbits.CCP1M2 = 1;
#if TMR2PRESCALE == 1
T2CONbits.T2OUTPS0 = 0;
T2CONbits.T2OUTPS1 = 0 ;
#elif TMR2PRESCALE == 4
T2CONbits.T2OUTPS0 = 1;
T2CONbits.T2OUTPS1 = 0 ;
#elif TMR2PRESCALE == 16
T2CONbits.T2OUTPS0 = 1;
T2CONbits.T2OUTPS1 = 1 ;
#endif
T2CONbits.TMR2ON = 1;
TRISCbits.TRISC2 = 0;
}
void PWM1_Stop(void) {
CCP1CONbits.CCP1M3 = 0;
CCP1CONbits.CCP1M2 = 0;
}
void PWM2_Start(void){
CCP2CONbits.CCP2M3 = 1;
CCP2CONbits.CCP2M2 = 1;
#if TMR2PRESCALE == 1
T2CONbits.T2OUTPS0 = 0;
T2CONbits.T2OUTPS1 = 0;
#elif TMR2PRESCALE == 4
T2CONbits.T2OUTPS0 = 1;
T2CONbits.T2OUTPS1 = 0;
#elif TMR2PRESCALE == 16
T2CONbits.T2OUTPS0 = 1;
T2CONbits.T2OUTPS1 = 1;
#endif
T2CONbits.TMR2ON = 1;
TRISCbits.TRISC1 = 0;
}
void PWM2_Stop(void){
CCP2CONbits.CCP2M3 = 0;
CCP2CONbits.CCP2M2 = 0;
}
* File: PWM_1_exemplo.c
* Author: Pilger
*
* Created on 16 de Novembro de 2017, 08:35
*/
#define _XTAL_FREQ 48000000
#define TMR2PRESCALE 16
// relação de frequencia x prescaler para xtal de 48M
// para reslução de 1000 -> 2^10 = 1023
// ps F pwm
// 1 48KHz
// 4 12KHz
// 16 3 KHz
#include <xc.h>
#include "C:\h\config_PIC18F4550.h"
//variáveis globais
long freq;
// protótipos de funções
void delay_ms(int i);
int PWM_Max_Duty(void);
void PWM1_Init(long fre);
void PWM2_Init(long fre);
void PWM1_Duty(unsigned int duty);
void PWM2_Duty(unsigned int duty);
void PWM1_Start(void);
void PWM1_Stop(void);
void PWM2_Start(void);
void PWM2_Stop(void);
void main(){
unsigned int i=0,j=0;
PWM1_Init(3000);
PWM2_Init(3000);
TRISD = 0xFF;
TRISC = 0;
PWM1_Duty(0);
PWM2_Duty(0);
PWM1_Start();
PWM2_Start();
while (1) {
if(PORTDbits.RD0 == 0 && i<1000){
while(PORTDbits.RD0==0);
i=i+100;
}
if(PORTDbits.RD1 == 0 && i>0){
while(PORTDbits.RD1==0);
i=i-100;
}
if(PORTDbits.RD2 == 0 && j<1000){
while(PORTDbits.RD2==0);
j=j+100;
}
if(PORTDbits.RD3 == 0 && j>0){
while(PORTDbits.RD3==0);
j=j-100;
}
PWM1_Duty(i);
PWM2_Duty(j);
delay_ms(10); // 10ms
}
}
// função que gera atraso em mlisegundos
void delay_ms(int i){
for ( int x = 0; x < i; x++ ) {
__delay_ms(1);
}
}
int PWM_Max_Duty(void){
return(_XTAL_FREQ/(freq*TMR2PRESCALE);
}
void PWM1_Init(long fre){
PR2 = (_XTAL_FREQ/(fre*4*TMR2PRESCALE)) - 1;
freq = fre;
}
void PWM2_Init(long fre){
PR2 = (_XTAL_FREQ/(fre*4*TMR2PRESCALE)) - 1;
freq = fre;
}
void PWM1_Duty(unsigned int duty){
if(duty<1024) {
duty = ((float)duty/1023)*PWM_Max_Duty();
CCP1CONbits.DC1B1 = duty & 2;
CCP1CONbits.DC1B0 = duty & 1;
CCPR1L = duty>>2;
}
}
void PWM2_Duty(unsigned int duty){
if(duty<1024) {
duty = ((float)duty/1023)*PWM_Max_Duty();
CCP2CONbits.DC2B1 = duty & 2;
CCP2CONbits.DC2B0 = duty & 1;
CCPR2L = duty>>2;
}
}
void PWM1_Start(void) {
CCP1CONbits.CCP1M3 = 1;
CCP1CONbits.CCP1M2 = 1;
#if TMR2PRESCALE == 1
T2CONbits.T2OUTPS0 = 0;
T2CONbits.T2OUTPS1 = 0 ;
#elif TMR2PRESCALE == 4
T2CONbits.T2OUTPS0 = 1;
T2CONbits.T2OUTPS1 = 0 ;
#elif TMR2PRESCALE == 16
T2CONbits.T2OUTPS0 = 1;
T2CONbits.T2OUTPS1 = 1 ;
#endif
T2CONbits.TMR2ON = 1;
TRISCbits.TRISC2 = 0;
}
void PWM1_Stop(void) {
CCP1CONbits.CCP1M3 = 0;
CCP1CONbits.CCP1M2 = 0;
}
void PWM2_Start(void){
CCP2CONbits.CCP2M3 = 1;
CCP2CONbits.CCP2M2 = 1;
#if TMR2PRESCALE == 1
T2CONbits.T2OUTPS0 = 0;
T2CONbits.T2OUTPS1 = 0;
#elif TMR2PRESCALE == 4
T2CONbits.T2OUTPS0 = 1;
T2CONbits.T2OUTPS1 = 0;
#elif TMR2PRESCALE == 16
T2CONbits.T2OUTPS0 = 1;
T2CONbits.T2OUTPS1 = 1;
#endif
T2CONbits.TMR2ON = 1;
TRISCbits.TRISC1 = 0;
}
void PWM2_Stop(void){
CCP2CONbits.CCP2M3 = 0;
CCP2CONbits.CCP2M2 = 0;
}
Atividade 1
1.1 Entendendo o PWM
- Criar um projeto e compilar o exemplo
- Observar no simulador
- Colocar no hardware
- Ligar um led na saída e observar
- Ligar um osciloscópio e analisar a saída
1.2 Adicionando recursos de informação
- Modificar o programa para
- Adicionar o módulo LCD e indicar o percentual de PWM em cada sinal
- Modificar o incremento e decremento para saltos de 1%
1.3 Ligando uma carga
- Ligar uma carga em uma das saídas, um motor DC de 12V (pode ser uma ventoinha de fonte de computador)
Nenhum comentário:
Postar um comentário