PWM e saída em rampa

Ver o tópico anterior Ver o tópico seguinte Ir em baixo

PWM e saída em rampa

Mensagem  Henriquec em Seg Maio 03, 2010 3:34 pm

Olá,

estou precisando fazer um controle de iluminação usando um PIC. Na verdade, no projeto usarei um 16F628A, mas como tenho a plataforma do curso, estou fazendo os testes no 18F4550.
Primeira coisa que gostaria de perguntar, se eu fizer o projeto para o 18, será muito complicado passar para o 16?

Ah, para explicar melhor o projeto. Preciso que o LED ligado ao pic tenha uma saída em pulso, degrau e rampa. Não comecei a projetar a entrada de dados, que será por UART, mas vou deixar isso para depois que fizer as saídas comportarem exatamente como gostaria.

O meu código que fiz até agora segue abaixo (não coloquei tudo, somente o main e a ConfiguraSistema):
"
void main(void)
{
unsigned int dc;
unsigned int duty;
unsigned int tempo;

tempo = 0;
duty = 127;

// Configura as portas e periféricos do PIC.
ConfiguraSistema();


//OpenTimer2(TIMER_INT_ON & T2_PS_1_1 & T2_POST_1_Cool;
//OpenPWM2(48000); // periodo = (PR2 + 1) * 4 * TOSC * TMR2 prescaler


// Laço infinito que executa a operação principal do projeto.
while (1)
{
/*//PULSO
dc = duty*255/100;
tempo = tempo*12;
SetDCPWM1(dc);
Delay1KTCYx(tempo);*/

if (BOTAO_1 == 1){
//RAMPA
for (dc = 0; dc <= duty*255/100; dc++){
SetDCPWM1(dc);
Delay1KTCYx(tempo*12); //tempo em ms
} //fim for
} //fim if

else{
//DEGRAU
dc = duty*255/100;
SetDCPWM1(dc);
Delay1KTCYx(tempo*12);
} //fim else

}//end while(1)

}//end main

void ConfiguraSistema (void)
{
// Desabilita todas as 13 portas analógicas ANx (portas do conversor A/D) assim
//as mesmas fucionam como pinos digitais
ADCON1 |= 0x0F;

//Habilita a porta RE1 (botão da placa) como entrada digital
TRISEbits.TRISE1 = 1;

//Configura o timer (verificar exatamente a conversão de tempo)
OpenTimer2(TIMER_INT_OFF & T2_PS_1_1 & T2_POST_1_1);

OpenPWM1(0xFF); //PWM period = [(period) + 1] x 4 x Tosc x TMR2 prescaler
//SetOutputPWM1 (HALF_OUT, PWM_MODE_1);
}
"
Outras dúvidas que estou tendo são a respeito das bibliotecas que estou usando, no caso a <timers.h> e <pwm.h>
1. Quando uso a função Delay, qual o tempo que está sendo usado por ela, a do timer2 ou a do cristal (48MHz)?
2. O que é Postscale e Enable Timer2 interrupt? <timer.h>
3. O que faz o SetOutputPWM? <pwm.h>
4. O que muda na minha saída quando altero o período do OpenPWM? <pwm.h>
5. O que muda na minha saída quando mudo o Duty do SetDCPWM? <pwm.h>
6. Porque quando mudo o Prescaler do timer2, não muda o PWM period?

Fiz alguns testes variando alguns valores, e vi a diferença, mas não consegui interpretar essa variação de forma a enxergar a teoria.

Agradeço desde já.

Henrique Carneiro
avatar
Henriquec

Mensagens : 2
Data de inscrição : 03/05/2010
Idade : 29

Ver perfil do usuário

Voltar ao Topo Ir em baixo

Re: PWM e saída em rampa

Mensagem  Bruno S. Avelar em Ter Maio 11, 2010 1:07 pm

Olá Henrique Carneiro,

Primeiramente respondendo sua pergunta: "...se eu fizer o projeto para o 18, será muito complicado passar para o 16?"
Certamente existirão complicações. Reparei que você está usando a biblioteca de PWM do compilador C18. Você pode ver a documentação desta biblioteca em "C:\MCC18\doc\periph-lib\PWM.html". Se você deseja implementar o PWM com a família 16 você deve procurar saber se existe uma biblioteca do compilador que voce vai usar ou de usuário na internet que já implemente o PWM.
Quando mudamos de família de microcontroladores a lógica (solução) do firmware existente continua a mesma, mas alguns detalhes da linguagem (por causa do compilador) e os registradores de função especial mudam. No seu caso, que está mexendo com bibliotecas do compilador C18, é muito importante fazer uma pesquisa das ferramentas que você terá com o compilador para familia 16 para avaliar quão difícil será a migração do código.

Sobre suas outras dúvidas:
1) Quando uso a função Delay, qual o tempo que está sendo usado por ela, a do timer2 ou a do cristal (48MHz)?
A função Delay nao é da biblioteca <timer.h> e sim da <delays.h>. Ela não trabalha com o clock diretamente e sim com ciclos de instrução TCY. Eu postei um bom tutorial de como usar ela em http://picminas.forumeiros.com/linguagem-c-f6/a-funcao-delay-t14.htm. Da uma olhada lá.

2) O que é Postscale e Enable Timer2 interrupt? <timer.h>

Postscale é para possibilitar a divisão do tempo.
Enable Timer2 interrupt é para habilitar a interrupção pelo timer2. Caso você deseje, toda vez que o Timer2 estourar a contagem ele gera uma interrupção no microcontrolador que pode ser tratada em uma rotina de tratamento de interrupções. Isso permite que o controlador nao precise ficar fazendo pulling no timer para saber como esta a contagem.

3) O que faz o SetOutputPWM? <pwm.h>
Serve para configurar a saida, recebe dois parametros outputconfig e outputmode.

outputconfig pode ser:
SINGLE_OUT single output
FULL_OUT_FWD full-bridge output forward
HALF_OUT half-bridge output
FULL_OUT_REV full-bridge output reverse
outputmode pode ser:

PWM_MODE_1 P1A and P1C active-high,
P1B and P1D active-high
PWM_MODE_2 P1A and P1C active-high,
P1B and P1D active-low
PWM_MODE_3 P1A and P1C active-low,
P1B and P1D active-high
PWM_MODE_4 P1A and P1C active-low,
P1B and P1D active-low

Da uma estudada na teoria de PWM. Vou ver se preparo um material para postar no forum e te ajudar daqui umas semanas.

Abraços,
Bruno S. Avelar
avatar
Bruno S. Avelar
Admin

Mensagens : 74
Data de inscrição : 26/07/2009
Idade : 33
Localização : Belo Horizonte MG

Ver perfil do usuário http://picminas.forumeiros.com

Voltar ao Topo Ir em baixo

Avanço no programa

Mensagem  Henriquec em Ter Maio 25, 2010 3:15 pm

Bruno,

agora que consegui fazer a parte em PWM gostaria de tirar uma dúvida sobre UART, pois agora parti para uma segunda etapa no programa, que deverei fazer a placa comunicar com um computador que terá um software feito também por mim.

Essa porta UART somente receberá informação, e será um byte único com um número que será o tempo que o PWM ficará ligado. Para isso, fiz uma interrupção para receber a informação da UART e uma para ativar o PWM, que temporariamente está no PORTB, para testar com mais facilidade.

O problema que quando dou Load no programa, não acontece nada no PIC. Estou tentando resolver o problema, mas até agora não obtive sucesso e gostaria de saber se você conseguiria me ajudar nisso.

Uma dúvida que também ficou é a respeito do Bound Rate, pois encontrei na internet gente me recomendando deixá-lo como 9600Kbps, mas não sei se está certo. Como faço para defini-lo?

Segue o programa abaixo:

/******************************************************************************
* Nome do Arquivo: main.c
* Dependencias: Veja a seção INCLUDES abaixo
* Processador: PIC18F4550
* Opção de Clock: HS 20MHz (externo) - CPU:48MHz
* Compilador: C18 v3.20 ou superior
* Empresa: Invent Vision - UFMG
*
* Plataforma: Kit PICMINAS v3.0
* Descrição: Programa que controla a saída de iluminação da plataforma de
teste do projeto de normalização de cameras digitais.
Saída: - rampa
- degrau
- pulso
*
*****************************************************************************/

/** I N C L U D E S **********************************************************/
#include <p18cxxx.h> // Inclui as funçoes do PIC18f4550
#include <delays.h> // Inclui as funções de delay
#include <timers.h> // Inclui as funções de timer
#include <pwm.h> // Inclui as funçoes da saída PWM
#include<usart.h> // Inclui as funções da USART

/** D E F I N E S ************************************************************/
// LED's do Kit PICMINAS: saida digital
//atribuição: 0 = LED desligado
// 1 = LED ligado
#define LED_AMARELO PORTDbits.RD0

// Toca o Buzzer
//atribuição: 0 = não toca
// 1 = toca
#define BUZZER PORTCbits.RC1

// Botões do Kit PICMINAS: entradas digitais
//atribuição: 0 = botao não pressionado
// 1 = botao pressionado
#define BOTAO_1 PORTEbits.RE1
#define BOTAO_2 PORTEbits.RE2

// O Botão de BOOT tem lógica invertida
//atribuição: 0 = botao pressionado
// 1 = botao não pressionado
#define BOTAO_BOOT PORTBbits.RB4


/** V A R I A V E I S G L O B A I S ****************************************/
unsigned char tempo_exposicao = 10; //atribuo um valor padrão somente para teste, sem a entrada USART

/** P R O T O T I P O S P R I V A D O S ***********************************/
void ConfiguraSistema (void);
void Toca_Buzina(void);
void ConfiguraPWM(void);
void ConfiguraEUSART(void);

/** P R O T O T I P O S D A S F U N Ç Õ E S D E I N T E R R U P Ç Ã O*/
void ConfiguraInterrupcao(void);
void Tratamento_High_Interrupt(void);
void Tratamento_Low_Interrupt(void);

/** F U N C O E S ************************************************************/

/******************************************************************************
* Funcao: void main(void)
* Entrada: Nenhuma (void)
* Saída: Nenhuma (void)
* Descrição: Função principal do programa. O termo "main" significa principal,
* pois esta é a primeira a ser chamada após o reset do
* microcontrolador.
* Todas as outras funções sao chamadas a partir da "main".
*****************************************************************************/
void main(void)
{
// Configura as portas e periféricos do PIC.
ConfiguraSistema();

//Desliga todos os LED's
//LED_AMARELO=0;

INTCONbits.GIE=1; // Habilita TODAS as interrupções

// Laço infinito que executa a operação principal do projeto.
while (1)
{
// O laço infinito fica vazio, o programa é controlado pela interrupção

}//end while
}//end main

/******************************************************************************
* Funcao: void ConfiguraSistema(void)
* Entrada: Nenhuma (void)
* Saída: Nenhuma (void)
* Descrição: ConfiguraSistema é a rotina de configuração principal do projeto.
* Seu objetivo é configurar as portas de I/O e os demais periféricos
* do microcontrolador para que operem da maneira desejada no projeto.
*****************************************************************************/
void ConfiguraSistema (void)
{
// Desabilita todas as 13 portas analógicas ANx (portas do conversor A/D) assim
//as mesmas fucionam como pinos digitais
ADCON1 |= 0x0F;

// Configura LED's do Kit PICMINAS: saida digital
http://TRISCbits.TRISC2=0; // RC2: saida digital - LED_VERDE (controlado pelo PWM)
TRISDbits.TRISD0=0; // RD0: saida digital - LED_AMARELO

// Buzina (buzzer): saida digital
TRISCbits.TRISC1=0; // RC1: saida digital - BUZZER

// Configura Botões do Kit PICMINAS: entradas digitais
TRISEbits.TRISE1=1; // RE1: entrada digital - BOTAO_1
TRISEbits.TRISE2=1; // RE2: entrada digital - BOTAO_2
TRISBbits.TRISB4=1; // RB4: entrada digital - BOTAO_BOOT

// Configura portas necessárias para USART
TRISCbits.TRISC6=1; // RC6: entrada digital - USART
TRISCbits.TRISC7=1; // RC7: entrada digital - USART

// Função que configura as interrupções do sistema
ConfiguraInterrupcao();
// Função que configura a saída PWM
ConfiguraPWM();
// Função que configura a EUSART
ConfiguraEUSART();

}//end ConfiguraSistema


/******************************************************************************
* Funcao: void ConfiguraEUSART(void)
* Entrada: Nenhuma (void)
* Saída: Nenhuma (void)
* Descrição: Função que configura a EUSART
*****************************************************************************/
void ConfiguraEUSART(void)
{
OpenUSART(USART_RX_INT_ON // Habilita interrupções de recebimento
& USART_TX_INT_OFF // Desabilita interrupções de transferência
& USART_ASYNCH_MODE // Coloca no módulo assíncrono
& USART_EIGHT_BIT // Seleciona transmissão de 8bits
& USART_SINGLE_RX // Single reception
& USART_BRGH_HIGH, 312); // Bound Rate High -> (Fosc / (16 * (spbrg + 1)) = 9584,66 ~ 9600
} //end ConfiguraEUSART

/******************************************************************************
* Funcao: void ConfiguraPWM(void)
* Entrada: Nenhuma (void)
* Saída: Nenhuma (void)
* Descrição: Função que configura a saída PWM
*****************************************************************************/
void ConfiguraPWM(void)
{
OpenTimer2(TIMER_INT_OFF // Desabilita interrupções
& T2_PS_1_1); // Prescaler = 1
OpenPWM1(0xff); //PWM_Period = [(PR2) + 1] * 4 * Tosc *(TM2 prescaler)
} //end ConfiguraPWM

/******************************************************************************
* Funcao: void ConfiguraInterrupcao(void)
* Entrada: Nenhuma (void)
* Saída: Nenhuma (void)
* Descrição: Função que configura as interrupções utilizadas no projeto
*****************************************************************************/
void ConfiguraInterrupcao(void)
{
RCONbits.IPEN=1; // Habilita prioridade de interrupção
INTCONbits.GIE=0; // Desabilita TODAS as interrupções

// INTERRUPÇÃO EUSART
INTCONbits.PEIE=1; // Habilita interrupção de periféricos
PIE1bits.RCIE = 1; // Habilita interrupção da EUSART Reciver
IPR1bits.RCIP = 1; // Define EUSART Reciver como High Priority
PIR1bits.RCIF = 0; // Zera o flag da EUSART Reciver

// INTERRUPÇÃO PORTB
INTCONbits.RBIE=1; // Habilita interrupção de mudança de estado nos pinos do PORTB de RB7 a RB4
INTCON2bits.RBPU=1; // Desabilita pull-up dos pinos de RB7 a RB4
INTCON2bits.RBIP=1; // Define o PORTB como High Priority
INTCONbits.RBIF=0; // Zera o flag do PORTB
}// end ConfiguraInterrupcao

/******************************************************************************
* Funcao: void Tratamento_High_Interrupt(void)
* Entrada: Nenhuma (void)
* Saída: Nenhuma (void)
* Descrição: Função de tratamento das interrupções de ALTA prioridade
*****************************************************************************/
#pragma interrupt Tratamento_High_Interrupt
void Tratamento_High_Interrupt(void)
{
// variavel usada para ler PORTB e corrigir ERRATA citada no cabeçalho
char temp;

if(INTCONbits.RBIF)
{
//Declaração de variáveis temporária
char dc;
char period;
char delta;
char i;

period = (0xff + 1)*83e-9;
delta = period / 100;


//ERRATA: ler o PORTB antes de limpar o INTCONbits.RBIF
temp=PORTB;
//Limpa flag da interrupção do PORTB
INTCONbits.RBIF = 0;

//SAÍDA EM RAMPA -> temporariamente somente saída em rampa (pensar em como o usuário escolher a saída) [povavelmente USART]
for (dc = 0; dc < 100; dc+=delta)
{
//Varia o DutyCicle do PWM
SetDCPWM1(dc);
//Mantem por um tempo o novo DutyCicle -> depende do tempo de exposição
for (i = tempo_exposicao; i > 0; i--)
{
Delay10TCYx(12); //10us
} //end for
} //end for

}// end tratamento da interrupção do PORTB (INTCONbits.RBIF)


// Verifica se o motivo da chamada da interrupção foi mudança de estado no PORTB
if(PIR1bits.RCIF)
{
// Avisa que o processo de leitura começou
Toca_Buzina();
LED_AMARELO = 1;

//Limpa flag da interrupção da EUSART
PIR1bits.RCIF = 0;

//PROCESSO DE LEITURA
tempo_exposicao = ReadUSART();
//VERIFICAR SE VALE A PENA GRAVAR NA EEPROM

// Apaga LED amarelo para indicar que processo terminou
LED_AMARELO = 0;

}// end tratamento da interrupção do PORTB (INTCONbits.RBIF)

}// end Tratamento_High_Interrupt

/******************************************************************************
* Funcao: void Tratamento_High_Interrupt(void)
* Entrada: Nenhuma (void)
* Saída: Nenhuma (void)
* Descrição: Função de tratamento das interrupções de BAIXA prioridade
*****************************************************************************/
#pragma interruptlow Tratamento_Low_Interrupt
void Tratamento_Low_Interrupt(void)
{

}//end Tratamento_Low_Interrupt



/******************************************************************************
* Funcao: void Toca_Buzina(void)
* Entrada: Nenhuma (void)
* Saída: Nenhuma (void)
* Descrição: Aciona o buzzer (RC1) com dois bip's curtos
*****************************************************************************/
void Toca_Buzina(void)
{
BUZZER=0; // desliga BUZZER
BUZZER=1; // liga BUZZER
Delay10KTCYx(100); // espera 83ms
BUZZER=0; // desliga BUZZER
Delay10KTCYx(100); // espera 83ms
BUZZER=1; // liga BUZZER
Delay10KTCYx(100); // espera 83ms
BUZZER=0; // desliga BUZZER
}


/** V E C T O R R E M A P P I N G ******************************************/
// Seção necessária para informar ao compilador C18 onde são os novos endereços
//da memória de programa que ele deve alocar as rotinas de tratamento do "reset"
//do microcontrolador e das rotinas de tratamento de interrupção.

//
//ATENÇÃO: COPIAR ESTA SEÇÃO DO CODIGO PARA TODO ARQUIVO "main.c" DOS PROJETOS QUE
//UTILIZAM O BOOTLOADER PARA GRAVAÇÃO IN-CIRCUIT.

// protótipo usado pelo compilador C18
extern void _startup (void); // See c018i.c in your C18 compiler dir

// Alocação da função de tratamento do "reset" da aplicação principal
// no endereço 0x800 da memória de programa
#pragma code REMAPPED_RESET_VECTOR = 0x000800
void _reset (void)
{
_asm goto _startup _endasm
}

// Alocação da função de tratamento das interrupções de ALTA prioridade
// no endereço 0x808 da memória de programa.
//
#pragma code REMAPPED_HIGH_INTERRUPT_VECTOR = 0x000808
void _high_ISR (void)
{
_asm goto Tratamento_High_Interrupt _endasm
}

// Alocação da função de tratamento das interrupções de BAIXA prioridade
// no endereço 0x818 da memória de programa
#pragma code REMAPPED_LOW_INTERRUPT_VECTOR = 0x000818
void _low_ISR (void)
{
_asm goto Tratamento_Low_Interrupt _endasm
}

#pragma code // Diretiva que retorna a alocação dos endereços
// da memória de programa para seus valores padrão

/** F I M D A S E Ç Ã O D E V E C T O R R E M A P P I N G *************/

/** EOF main.c ***************************************************************/

agradeço desde já,

Henrique Carneiro
avatar
Henriquec

Mensagens : 2
Data de inscrição : 03/05/2010
Idade : 29

Ver perfil do usuário

Voltar ao Topo Ir em baixo

Re: PWM e saída em rampa

Mensagem  Conteúdo patrocinado


Conteúdo patrocinado


Voltar ao Topo Ir em baixo

Ver o tópico anterior Ver o tópico seguinte Voltar ao Topo


 
Permissão deste fórum:
Você não pode responder aos tópicos neste fórum