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!
Tags:
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
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
Oi Pessoal,
esta versão (V03) esta melhor.
Rui
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
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
}
}
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
Bem-vindo a
Laboratorio de Garagem (arduino, eletrônica, robotica, hacking)
© 2024 Criado por Marcelo Rodrigues. Ativado por