Olá! Preciso gerar uma onda PWM com uma frequência não fixa, ou seja, vou variando ela conforme necessário, pensei em utilizar um potenciômetro, mas também podem ser botões. A frequência deve variar entre 50kHz até 100kHz. Também preciso variar o duty cycle, mas isso é bem mais fácil (de fato, usarei outro potenciômetro). Alguém tem alguma ideia do que e como utilizar para fazer essa tarefa? Obrigado!

Exibições: 4881

Responder esta

Respostas a este tópico

Oi Pessoal,

passei o dia estudando  o PWM, e montei uma planilha em excel para melhor entender como variar a

freqüência e o duty cycle.

Na planilha tem duas tabelas:,

A primeira é em função da variação da freqüência.

Estabelecendo uma freqüência fixa para o microcontrolador.  Por ex: 16.000.000 hz  (16MHz),

Para variar a freqüência do PWM, será necessário variar os valores do registrador PR2

e os bits do prescaler no registrador TMR2.

Em azul está a freqüência do microcontrolador, caso voce queira testar com outros valores basta

digitar os novos clocks aí.

 

A segunda tabela é para determinar o Duty Cycle (Tempo em Hi) em valores e percentuais.

Para isto varia-se os valores do registrador CCPRL1 e os Bits 4 e 5 do registrador CCP1CON.

Rui

Planilha anexa

Anexos
Legal Rui, bom saber q uma simples coisa pode nos trazer um enorme conhecimento. Acho q tenho vários modelos de pic16 aqui, vou ver o mais semelhante e vou dar uma estudada também.

Fala galera, muito obrigado pelas respostas até agora, mas com tantos posts me confundi um pouco hehe. Afinal, qual PIC me recomendam usar para fazer essa tarefa e qual o código? utilizo um cristal ou não? lembrando que a frequência deve variar de 50 até 100 kHz. abraço!!

Então Tales, para mais de 10khz você vai precisar de um pic da familia 16f e com cristal de 32mhz.

Segue oque o Rui falou na pagina passada.

[quote]

Estou reaprendedo o PWM.

Com o PIC16F1847 com  clock de 32Mhz, voce consegue PWM de até 333Khz,

O clock interno dele pode ser configurado até 32Mhz, tem A/D e a pinagem é igual

a do PIC16F628A (18 pinos).     (R$ 14,00 no ML)  (US$ 1,98 Mouser)

O clock dele tb pode ter a frequencia trocada mesmo com ele em operação. 

Estou escrevendo o código para ele.  Por sorte eu tenho 2 dele para teste no proto.

Rui[/quote]

 

Oi Tales, bom dia.

Ainda estou trabalhando no PWM do PIC, mas de uma olhada na planilha em excel que eu anexei em um post

para entender melhor as variavéis envolvidas com o PWM.

Rui

Certo! vou aguardar então, muito obrigado!

Oi Pessoal boa noite.

Passei de sexta até hoje me divertindo com o PWM do PIC.

E está no seguinte pé.

O código está escrito para PIC16F818/9 e PIC16F1847, (testei em ambos), basta comentar as

linhas que não indicam o seu PIC.

Com pequenas modificações, ele pode ser usado em vários PIC's que tenha A/D e PWM nele,

já que os registradores  usados pelo PWM são "quase padrões"na linha PIC.

Eu utilizei 2 Pots de 10K  de 10 voltas e liguei um resistor de 1k do pino central dos pots

para as entrada analógicas do PIC.

No osciloscópio eu notei uma variação de freqüência ao variar o pot do Duty.

Isto não deveria acontecer baseada na teoria do calculo do duty disponibilizado

em AN da microchip para PWM.

Vou continuar pesquisando para descobrir porque a freqüência varia.

 

Estou anexando um file com o arquivo C e a planilha que mostras as fórmula das freqüências,

como eu defini as decisões do  "Switch",  e com os calculos do Duty.

Lembre-se. Não existe versão sem bug.  kkkk

Rui

Anexos

Oi Pessoal,  

esta versão (V03) esta melhor.

Rui

Anexos

Oi Pessoal,

segue a versão para PIC16F690.

Inclui tb o Hexa.

PIC16F690  AN0 pino 19, AN1 pino 18, saída PWM pino RC5 pino5.

Rui

Anexos

Oi pessoal, boa tarde.
O Tales me reportou que usando o código que escrevi, qdo ele variava o duty, a freqüência tb variava.
Ele disse também que não consegui chegar à freqüência máxima que eu projetei (100KHz)
Fui rever o código e descobri que eu tinha esquecido um detalhe.

No PIC (e acredito que me outros microcontroladores também), ao usar o ADC, eu defini o tempo de
conversão corretamente. Mas como eu trocava de entrada analógica, lendo o valor de AN0 para freqüência
e AN1 para duty, precisava dar um tempo para carregar o capacitor interno do PIC.
Este tempo está em torno de 10us. TACQ = TAMP + TC + TCOFF 10.61 s à 25 oC
Como eu não esperava este tempo, o valor do ajuste de um potenciômetro afetava o valor da outra medida.
Isto causava erro de medida da entrada analógica.
E assim, o ajuste do duty afetava o valor da freqüência, e vise versa.

Reescrevi o código e estou disponibilizando a versão para PIC16F690.

Testei no proto e observei com oscloscopio.  Funcinou Ok

A frequência do PWM varia de 250Hz até 100Khz   (como PIC em 4MHz).

Rui


// PIC16F690.
// PWM Pino 5
// ADC Frequencia Pino 19
// ADC Duty Pino 18

#include <htc.h>

#define _XTAL_FREQ 4000000

__CONFIG(FOSC_INTRCCLK & WDTE_OFF & PWRTE_OFF & BOREN_OFF & CP_OFF & CPD_OFF);

unsigned int adc, abspwm;
float ratio;

//*****************************************************************************
void main(void)
{
TRISA = 0b00000011; // Initialise Port A (R A2-7:Out, RA 0,1:In)
TRISB = 0b11001111; // Initialise Port B (RB 0-3:In: RB 4,5:Out RB 6,7 In)
TRISC = 0b11010000; // Initialise Port C (RC 0-3,5:Out, RC 2,4,6-7:In)

OSCCON = 0x60; // 4Mhz

ANSEL = 0b00000011; // Pot on RA0/AN0 e RA1/AN1
ANSELH = 0;

CCPR1L = 0b00000000; // PWM Duty cycle (8 MSbs. Note 2 LSbs in CCP1CON)
CCP1CON = 0b00001100; // 00 00 1100 (Configure CCP1 peripheral for PWM)
ADCON1 = 0b00010000; // (0 001 0000) Fosc/8

while (1)
{
// Rotina para ler um Pot em AN0 e calcular a frequencia do PWM
ADCON0 = 0x81; // (1 0 00-00 0 1) AN1 Pino 18

__delay_us(15);; // Acquisition Time

GO_nDONE=1; // Inicia Conversão A/D
while(GO_nDONE){} // Aguarda fim de conversão

switch(ADRESH) // Seleciona frequência
{
case 0x00:
if (ADRESL < 247)
{
PR2 = ADRESL + 9; // 9 Menor valor para 4Mhz
T2CON = 0x04; // Presc 1
break;
}
else
{
PR2 = ADRESL -183; // 64 Menor valor
T2CON = 0x05; // Presc 4
break;
}
case 0x01:
if (ADRESL < 183)
{
PR2 = ADRESL + 73; // 64 Menor valor
T2CON = 0x05; // Presc 4
break;
}
else
{
PR2 = ADRESL -119; // 64 Menor valor
T2CON = 0x06; // Presc 16
break;
}
case 0x02:
if (ADRESL < 119)
{
PR2 = ADRESL + 137; // 64 Menor valor
T2CON = 0x06; // Presc 16
break;
}
else
{
PR2 = 255; // Máximo valor
T2CON = 0x06; // Presc 16
break;
}
case 0x03:
PR2 = 255; // Máximo valor
T2CON = 0x06; // Presc 16
break;
}

// Le segundo potenciometro e define o % de Duty.

ADCON0 = 0x85; // (1 0 00-01 0 1) AN1 Pino 19

__delay_us(15); // Acquisition Time

GO_nDONE=1; // Inicia Conversão A/D
while(GO_nDONE); // Aguarda conversão

adc = ADRESH; // Le registrador de conversão H
adc = 8; // Desloca 8 bits para esquerda
adc |= ADRESL ; // Le registrador de conversão L or com H deslocado

ratio = adc;
ratio = ratio/1023; // Calcula razão da leitura
ratio = ratio*100; // Multiplica para melhorar precisã0

adc = (int)ratio; // Calcula valor inteiro do % de duty

// abspwm = 4*(PR2+1)*adc/100; = abspwm = (PR2+1)*adc/25;
abspwm = (PR2+1)*adc/25; // Calcula duty ratio

CCPR1L = abspwm >> 2; // 8 MSbs of Duty Cycle de 2 a 9
DC1B1 = abspwm & 0x02 ? 1 : 0; // CCP1CON<5> LSb bit 1
DC1B0 = abspwm & 0x01 ? 1 : 0; // CCP1CON<4> LSb bit 0
}
}

Anexos

Oi pessoal, boa tarde.

O Tales me informou que ele estava usando potenciometros de 50k e que a  frequência estava instavél.

Eu informei ele que o valor do potenciometro recomendado pelo fabricante do chip, deverá ser no máximo de 10K, mas eu recomendei 4k7.

E informou novamente que com esta alteração, está funcionando como esperado.

Rui

RSS

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço