Ir ao conteúdo
  • Cadastre-se

Motor, PWM e PIC


kelsjc

Posts recomendados

Olá pessoal,

Estou com uma dúvida básica em PWM, se alguém puder me ajudar eu agradeço pois não manjo de PWM. Seguinte, gostaria de saber como definir a frequencia do PWM no PIC..

Pelo o que andei lendo, é necessário saber a frequencia que vai trabalhar o PWM, mas como eu determino essa frequencia? A frequencia do meu pwm tem que ser a mesma do motor (rpm), é isso? Alguém poderia me explicar e exemplificar?

Obrigado!

Kelson

Link para o comentário
Compartilhar em outros sites

Bom, para começar, você precisa saber o que seria o PWM. Como eu não tenho uma didática muito boa. Recomendo que leia a 2º apostila q apareceu no goole quando digitei PWM:

O que é PWM?

Depois q você leu a apostila, verá q você não precisa necessariamente de um PIC para poder reproduzir tal sinal.

No entanto, se você precisa usar um PIC, eu preciso saber qual PIC você vai utilizar e qual linguagem de programação você está acostumado. Eu uso a linguagem C no PCW da CCS.

Respondendo sua pergunta. Não, a frequencia de PWM não é a a mesma que a rotação de um motor.

Para que seja eficaz, um PWM da ordem de uns 60Hz já é suficiente para acionar um motor. Mas tem várias peculiaridades em relação a isso.

Poste o que você deseja fazer com o sinal. Eu costumo usar a frequencia de 100~150hz para acionar fans.

Falou

Link para o comentário
Compartilhar em outros sites

Olá matheus!

Desculpe a demora p responder, pois estava na correria esses dias.

Bom, vamos lá .. eu entendo de pwm e pic... rs... o que eu não sei é como funciona o pwm no pic para rodar um motor!! Eu estou usando a saida CCP1 para pwm no pic 16F877. Estava fazendo meu codigo em PIC Basic, mas agora to escrevendo em C. O que eu sei ate agora é que para produzir o pwm só precisa basicamente dos comandos: setup timer2 e setup ccp1... e sei que tem que calcular um monte de coisa, isso q nao entendo, e acho que depende do motor tb, nao sei. Como eu defino os valores para usar em meu codigo?

Pra começar: Se a frequencia do seu codigo pwm nao tem nada a ver com o motor, como você decidiu usar frequencia de 100 e 150Hz para um fan? Poderia me mostrar os calculos e como ficou seu setup timer2 ?

Outra coisa: pra que serve o prescaler e o postscaler. Eu sei que é para dividir a frequencia de entrada, mas para que isso? Se eu faço um pre=2 e post=2 é a mesma coisa que pre=4 e post=1 ???

Valeu!!!

Só respondendo sua outra duvida, eu preciso usar PIC pois é um pwm controlado por comando ... só preciso entender como "casar" o pwm com meu motor ... como fazer os cálculos..

Link para o comentário
Compartilhar em outros sites

Vi sua msg só hj pois estava viajando no feriadão. Vamos lá então.

Pra começar: Se a frequencia do seu codigo pwm nao tem nada a ver com o motor, como você decidiu usar frequencia de 100 e 150Hz para um fan?

Como você deve saber, o sinal PWM é um sinal de frequencia constante onde temos uma onda quadrada q fica ON-OFF. E seu duty cycle é a razão entre o tempo de duração da onda ON e o tempo total do período.

Imagine q a frequncia de comutação seja de 1Hz. você consegue ver q nessa frequencia tão baixa, o motor não terá um giro contínuo. Ele ligará e desligará. certo? Então você precisa de uma frequencia q a carga q será alimentada não note esse ON-OFF do sinal.

Não tem uma fórmula para se estabelcer a frequencia necessária. Costuma-se usar 100-150hz para motores. Já é suficiente para fazer com ele gire sem dar trancos.

Outra coisa: pra que serve o prescaler e o postscaler. Eu sei que é para dividir a frequencia de entrada, mas para que isso? Se eu faço um pre=2 e post=2 é a mesma coisa que pre=4 e post=1 ???

Não. Com o Prescaler você vai diminuir o valor do clock interno do Timer, ele pode ser 2, 4, 8, 16 e assim por diante dependendo do Timer.

O Postcaler é um número de 1-16 que determina quantas vezes o Timer irá estourar para chamar um interrupção: (1 é uma vez, 2 é duas vezes, e assim por diante).

Poderia me mostrar os calculos e como ficou seu setup timer2 ?

O Timer2 é usado como base de tempo para a modulação PWM com o módulo CCP.

Exemplo:

Gerar um sinal quadrado de 1Khz utilizando o Timer2 e o módulo CCP1 no PIC C da CCS.

Solução:

Para gerar um sinal de 1Khz, é necessário, T=(1/1000)/2=500uS, um semiperíodo de 500uS (micro-segundos). Onde T=período.

Temos uma equação para cálculo do overflow (estouro) do Timer2. Que é:

T=1/clock*4*Prescaler*(carga Timer2+1)*Postcaler]

Usando a fórmula, temos:

500uS=1/4000000*4*4*(X+1)*1], onde X=124.

Então devemos começar o código configurando o Timer2. De modo geral fica assim:

setup_timer_2 (mode, period, postscale)

Onde o mode, pode ser: T2_DISABLED, T2_DIV_BY_1, T2_DIV_BY_4, T2_DIV_BY_16.

Período foi calculado (124).

Postcaler já foi explicado.

Para o nosso exemplo, fica assim:

setup_timer_2(T2_DIV_BY_4,124,1);

Para ajuste do duty cicle, usamos:

set_pwm1_duty(512);

Mas porq 512? O módulo aceita valores de 8 ou 16 bits. Uso 16bits, ou seja, 2^16=1024. Então 512 é 50%.

Nosso programa completo para o 16F877 fica assim:

#INCLUDE <16F877.h>
#use delay(clock=4000000)
#fuses XT,NOWDT

void main() {
setup_timer_2(T2_DIV_BY_4,124,1);
setup_ccp1(CCP_PWM);
set_pwm1_duty(512);

while (1); //para evitar sleep
}

Uma vez q você consegue compreender esses calculos, fica fácil você determinar uma frequência de trabalho.

Qualquer dúvida posta aí.

Falou

Link para o comentário
Compartilhar em outros sites

Fala Matheus!

Como você deve saber, o sinal PWM é um sinal de frequencia constante onde temos uma onda quadrada q fica ON-OFF. E seu duty cycle é a razão entre o tempo de duração da onda ON e o tempo total do período.

Imagine q a frequncia de comutação seja de 1Hz. você consegue ver q nessa frequencia tão baixa, o motor não terá um giro contínuo. Ele ligará e desligará. certo? Então você precisa de uma frequencia q a carga q será alimentada não note esse ON-OFF do sinal.

Não tem uma fórmula para se estabelcer a frequencia necessária. Costuma-se usar 100-150hz para motores. Já é suficiente para fazer com ele gire sem dar trancos.

Certo, entendi o que você disse. Então seguindo esse pensamento, eu posso ter um pwm de 100 a 4MHz (fosc), ou seja, tanto faz frequencias altas pois o ciclo será suficiente rápido para o ON-OFF, correto?

Não. Com o Prescaler você vai diminuir o valor do clock interno do Timer, ele pode ser 2, 4, 8, 16 e assim por diante dependendo do Timer.

Pode dar um exemplo? Seria por exemplo dividir a freq do osc? Qual a intenção de diminuir o clock?

O Postcaler é um número de 1-16 que determina quantas vezes o Timer irá estourar para chamar um interrupção: (1 é uma vez, 2 é duas vezes, e assim por diante).

Outra dúvida, qual a diferença se o timer estourar 1 ou 16 vezes? Não vai estourar de qualquer forma?!

O Timer2 é usado como base de tempo para a modulação PWM com o módulo CCP.

Exemplo:

Gerar um sinal quadrado de 1Khz utilizando o Timer2 e o módulo CCP1 no PIC C da CCS.

Solução:

Para gerar um sinal de 1Khz, é necessário, T=(1/1000)/2=500uS, um semiperíodo de 500uS (micro-segundos). Onde T=período.

Temos uma equação para cálculo do overflow (estouro) do Timer2. Que é:

T=1/clock*4*Prescaler*(carga Timer2+1)*Postcaler]

Usando a fórmula, temos:

500uS=1/4000000*4*4*(X+1)*1], onde X=124.

Na fórmula T não deveria ser 1ms? por que 500us é meio-período...

O que seria essa "carga Timer 2" e na fórmula setup_timer , é chamado de período... não entendi... se puder esclarecer eu agradeço.

Então devemos começar o código configurando o Timer2. De modo geral fica assim:

setup_timer_2 (mode, period, postscale)

Onde o mode, pode ser: T2_DISABLED, T2_DIV_BY_1, T2_DIV_BY_4, T2_DIV_BY_16.

Período foi calculado (124).

Postcaler já foi explicado.

Para o nosso exemplo, fica assim:

setup_timer_2(T2_DIV_BY_4,124,1);

Para ajuste do duty cicle, usamos:

Por que Prescaler = 4 e Postscaler = 1? Você mesmo que decidiu diminuir o clock e acusar overflow apenas 1 vez? Esse Pre e Post ainda não caiu a ficha. Eu posso colocar qualquer valor?!

set_pwm1_duty(512);

Mas porq 512? O módulo aceita valores de 8 ou 16 bits. Uso 16bits, ou seja, 2^16=1024. Então 512 é 50%.

Aonde eu defino se é 8 ou 16 bits?

Uma vez q você consegue compreender esses calculos, fica fácil você determinar uma frequência de trabalho.

Isso que tá pegando ainda... rsss

Valeu!!!

Link para o comentário
Compartilhar em outros sites

Que bom q você voltou com dúvidas. Isso me fez reler o que disse no post anterior e pesquisar um pouco mais a fundo aqui e percebi q escrevi algumas coisas erradas. Vou corrigí-las lá mas as suas dúvidas serão respondidas corretamente aqui nesse pot mesmo.

Certo, entendi o que você disse. Então seguindo esse pensamento, eu posso ter um pwm de 100 a 4MHz (fosc), ou seja, tanto faz frequencias altas pois o ciclo será suficiente rápido para o ON-OFF, correto?

Quase correto. Veja que a frequência de saída é dada por:

                     Frequencia do Cristal
PWM Freq = -----------------------------------------------
(Carga do timer2 + 1) * (Timer2 Prescaler) * 4

O prescaler do Timer2 pode ser 1, 4 ou 16.

A carga do Timer2 ou pode chamar de período pode ser 0 a 255.

Considerando q você usa um cristal de 4Mhz:

Valor mínimo:

        4 MHz                  4,000,000
----------------------- = --------------- = 244 Hz
(255 + 1) * 16 * 4 16,384

Valor Máximo:

        4 MHz                  4,000,000
----------------------- = --------------- = 500000 Hz
(1 + 1) * 1 * 4 8

São valores teóricos.

Seria por exemplo dividir a freq do osc? Qual a intenção de diminuir o clock?

Sim, você irá diminuir, na verdade dividir o relógio interno do Timer2. Dessa forma, fica mais fácil de você ajustar para uma frequencia necessária. Veja na fórmula ali em cima q a frequencia depende do Prescaler.

Outra dúvida, qual a diferença se o timer estourar 1 ou 16 vezes? Não vai estourar de qualquer forma?!

Estourar ele vai, no entanto imagine q você queira fazer um relógio. Para controlar esse relógio você precisa de uma interrupçao q acontece a cada 1s para fazer o relógio funcionar, então você vai configurar seu Timer para q estoure a cada 1s e incremente a variável de segundos. Agora, imagine q você queira q ele estoure a cada 2s. Simples não? Só você configurar para q ele chame a interrupção só depois q o timer estourar 2 vezes.

Exemplo simples. Mas acredito q dê para entender.

Na fórmula T não deveria ser 1ms? por que 500us é meio-período...

O que seria essa "carga Timer 2" e na fórmula setup_timer , é chamado de período... não entendi... se puder esclarecer eu agradeço.

Carga Timer2 e periodo são a mesma coisa.

Quando você me fez essa pergunta aí de cima, pensei comigo mesmo: Ele tem razão!

Sim o período seria de 1mS. Fazendo os cálculos novamente, temos q a carga do Timer 2 ou seu Periodo será:

1mS=1/4000000*4*4*(X+1)*1], onde X=249.

Corrigindo o que disse antes. O Timer 2 fica assim:

setup_timer_2(T2_DIV_BY_4,249,1);

Por que Prescaler = 4 e Postscaler = 1? Você mesmo que decidiu diminuir o clock e acusar overflow apenas 1 vez? Esse Pre e Post ainda não caiu a ficha. Eu posso colocar qualquer valor?!

Mais uma vez você terá q fazer o uso da fórmula lá de cima.

Veja essa parte do datasheet do 16f876A:

Note:

The Timer2 postscaler (see Section 7.1) is not used in the determination of the PWM frequency. The postscaler could be used to have a servo update rate at a different frequency than the PWM output.

Para o Prescaler você usa o que você quiser. Mas vamos supor q você queira uma frequencia X. E CHUTE o valor do prescaler. você vai usar a formula, mas o periodo ou carga do timer 2 talvez pode ficar fora do intervalo de 1-255. Aí você acaba tendo q ajustar o Prescaler.

Aonde eu defino se é 8 ou 16 bits?

Essa era a parte q falei besteira lá em cima. Faltou complementar.

Lembra q eu disse q o duty cycle é configurado por: set_pwm1_duty(valor);

Então, depois de umas 2 horas lendo aqui pois meus tentes estavam dando errado, encontrei uma explicação bem interessante para isso.

O conteudo de "valor" NÃO dever ser maior do q o periodo (ou carga do timer 2).

Exemplo:

Para valores de 16 Bits:

Temos que setup_timer_2(T2_DIV_BY_4,249,1) e com isso temos um periodo de 249. Se fizermos set_pwm1_duty(124L) (note o "L") temos que:

   16-bit Duty cycle                  124          124
--------------------------- = ------------ = ------ = 12.4%
(Timer 2 periodo +1) * 4 (249 +1) * 4 1000

Para valores de 8 Bits:

Agora se ao invés de set_pwm1_duty(124L) usarmos set_pwm1_duty(124) sem o "L", quer dizer q estamos no modo 8 bits. Isso nos dá:

   8-bit Duty cycle                  124
--------------------------- = ------------ = 49.6%
(Timer 2 periodo +1) 250

Acredito q dessa vez não cometi nenhum erro.

Foi útil esse tópico que pude reaprender alguns detalhes da programação.

EDIT:

Criei um aplicativo aqui para você poder facilitar o cálculo do Timer2. Lembre-se q é melhor você aprender a calcular e não depender do programa.

OBS: O programa é Promo-version. Quer dizer q tem bug. Programei ele rapidin aqui só pra teste mesmo. Se for útil diz aí.

O programa tem 3 tipos. 1 para o net framework 3. Para o netframawork 3.5 e para o 4.0. Se você tiver o 4.0 instalado, funciona os outros. Recomendo o 4.0.

Se o programa não funcionar ou der erro, é porq você precisa baixar e instalar o net framework aqui ó:

Download details: Microsoft .NET Framework 4 (Standalone Installer)

Programa:

http://www.4shared.com/file/FQNm2rHx/Timer2_Calc_NF_30.html

http://www.4shared.com/file/cjGZ-dR5/Timer2_Calc_NF35.html

http://www.4shared.com/file/fVLvxHZp/Timer2_Calc_NF_40.html (RECOMENDADO)

Falou

Link para o comentário
Compartilhar em outros sites

Só na correria.. rs.. e mais uma vez obrigado pelo post Matheus

Vamos lá ...

Considerando q você usa um cristal de 4Mhz:

Valor mínimo:

        4 MHz                  4,000,000
----------------------- = --------------- = 244 Hz
(255 + 1) * 16 * 4 16,384

Bom, isso quer dizer que sua previsão para PWM em motores entre 100 a 150Hz não faz sentido, uma vez que o mínimo PWM de 244Hz é para um cristal de 4MHz e acho que não existe PIC trabalhando com menos de 4MHz, pelo menos o PIC16F877, não que eu saiba. Por exemplo, para um PWM de 122Hz (na sua faixa de 100-150) precisaria de um cristal de 2MHz, e o PIC16F877 não trabalha nessa faixa, ou estou errado?! Faz sentido?

Sim, você irá diminuir, na verdade dividir o relógio interno do Timer2. Dessa forma, fica mais fácil de você ajustar para uma frequencia necessária. Veja na fórmula ali em cima q a frequencia depende do Prescaler.

Certo, ajuste da frequência de trabalho do pwm. Agora entendi :)

Estourar ele vai, no entanto imagine q você queira fazer um relógio. Para controlar esse relógio você precisa de uma interrupçao q acontece a cada 1s para fazer o relógio funcionar, então você vai configurar seu Timer para q estoure a cada 1s e incremente a variável de segundos. Agora, imagine q você queira q ele estoure a cada 2s. Simples não? Só você configurar para q ele chame a interrupção só depois q o timer estourar 2 vezes.

Exemplo simples. Mas acredito q dê para entender.

Certo, entendi sim ..

Sim o período seria de 1mS. Fazendo os cálculos novamente, temos q a carga do Timer 2 ou seu Periodo será:

1mS=1/4000000*4*4*(X+1)*1], onde X=249.

Corrigindo o que disse antes. O Timer 2 fica assim:

setup_timer_2(T2_DIV_BY_4,249,1);

Estou fazendo os cálculos mas ainda assim não estou chegando no valor de 249. Está certo? X=(1/64000)-1

Para o Prescaler você usa o que você quiser. Mas vamos supor q você queira uma frequencia X. E CHUTE o valor do prescaler. você vai usar a formula, mas o periodo ou carga do timer 2 talvez pode ficar fora do intervalo de 1-255. Aí você acaba tendo q ajustar o Prescaler.

Entendi, mas tá confuso ainda. Se o prescaler eu uso para ajustar a frequencia de trabalho e o postscaler eu uso para gerar a interrupção, tá entrando em conflito nessa teoria pois um depende do outro. Se eu ajusto um, muda o outro ... ou seja, ou eu trabalho na frequencia X ou por X interrupções. Ex. no caso do "relógio" eu defino a interrupção (postscaler), e assim vou ter que achar um prescaler para que o resultado fique menor que 255 seja qual for a frequencia. Tá certo esse raciocínio?

Para valores de 16 Bits:

Temos que setup_timer_2(T2_DIV_BY_4,249,1) e com isso temos um periodo de 249. Se fizermos set_pwm1_duty(124L) (note o "L") temos que:

   16-bit Duty cycle                  124          124
--------------------------- = ------------ = ------ = 12.4%
(Timer 2 periodo +1) * 4 (249 +1) * 4 1000

Para valores de 8 Bits:

Agora se ao invés de set_pwm1_duty(124L) usarmos set_pwm1_duty(124) sem o "L", quer dizer q estamos no modo 8 bits. Isso nos dá:

   8-bit Duty cycle                  124
--------------------------- = ------------ = 49.6%
(Timer 2 periodo +1) 250

É só esse "L" que me diz se é 8 ou 16 bits?? Não depende de mais nada? Se for assim, vou sempre trabalhar com 16 bits pela precisão...

Acredito q dessa vez não cometi nenhum erro.

A explicação está ótima, valeu pelos posts, estou entendendo mais esse processo.

Criei um aplicativo aqui para você poder facilitar o cálculo do Timer2. Lembre-se q é melhor você aprender a calcular e não depender do programa.

Usei seu programa com NF4, excelente! Só achei uns probleminhas nele:

1) Para qualquer prescaler no Modo 1, a fórmula fica sempre T2_DIV_4

2) Em alguns casos, o duty cycle fica quebrado e ACHO que não existe (ex. 127,5). Teria que ser 127 ou 128. Me corrija se eu estiver errado.

Exemplo Modo 1:

Velocidade Cristal = 4MHz

Prescaler = 16

PR2 = 255

Fórmula:


setup_timer2(T2_DIV_4,255,1);
setup_ccp1(CCP_PWM);
set_pwm1_duty(127,5); //50% duty

valeu

Link para o comentário
Compartilhar em outros sites

Opa. bão né.

EDIT: você que possui muitas duvidas e treina os codigos no PIC, recomendo que utilize o _Proteus_ para simular seus circuitos. Lá tem uma ferramenta q você mede a frequencia na saida de algum pino. Bem útil para testes.

Vamos lá:

Bom, isso quer dizer que sua previsão para PWM em motores entre 100 a 150Hz não faz sentido, uma vez que o mínimo PWM de 244Hz.

Quando comentei que uso a frequencia de 100-150hz é que quando controlo ventoinhas, não faço o uso do hardware de PWM do PIC (módulo CCP). como controlo 4 ou mais coolers independentes, crio o sinal PWM por software mesmo. Aí faço com a frequencia que eu quiser.

Lembre-se que o PIC pode funcionar com um oscilador de 32KHz também.

Estou fazendo os cálculos mas ainda assim não estou chegando no valor de 249. Está certo? X=(1/64000)-1

Temos que :

              1             
1*10^-3 = -------- * 4*4 (X+1)*1
4000000

4000 = 16X+16

16X=4000-16

X=3984
----
16

X=249

Entendi, mas tá confuso ainda. Se o prescaler eu uso para ajustar a frequencia de trabalho e o postscaler eu uso para gerar a interrupção, tá entrando em conflito nessa teoria pois um depende do outro. Se eu ajusto um, muda o outro ... ou seja, ou eu trabalho na frequencia X ou por X interrupções. Ex. no caso do "relógio" eu defino a interrupção (postscaler), e assim vou ter que achar um prescaler para que o resultado fique menor que 255 seja qual for a frequencia. Tá certo esse raciocínio?

Não. O Prescaler determina o tempo da interrupção. O Postcaler apenas diz quantas vezes o Timer2 tem q estourar para chamar a interrupção. Se você determina com o Prescaler e o Periodo do Timer2 o tempo de 1s para ele estourar mas quer 2s, você seta 2 como Postcaler.

É só esse "L" que me diz se é 8 ou 16 bits?? Não depende de mais nada? Se for assim, vou sempre trabalhar com 16 bits pela precisão

SIM!

Usei seu programa com NF4, excelente! Só achei uns probleminhas nele.

Sim. você está correto!

Na verdade quando fiz aparecer o código, originalmente era só para o Modo 2. Fiz para o Modo 1 mas pelo visto não tinha visto esses erros.

Como disse antes, ele está cheio de bugs. Se você colocar alguma palavra ao invés de numero.. acho q ele quebra. Dá p consertar.. claro mas agora estou meio preguisoso. uhahuahua

Falou

Link para o comentário
Compartilhar em outros sites

EDIT: você que possui muitas duvidas e treina os codigos no PIC, recomendo que utilize o _Proteus_ para simular seus circuitos. Lá tem uma ferramenta q você mede a frequencia na saida de algum pino. Bem útil para testes.

Eu já utilizo o Proteus e já monitoro a frequência.

Só precisava mesmo entender, calcular, projetar realmente meu circuito.

Lembre-se que o PIC pode funcionar com um oscilador de 32KHz também.

Vou dar uma estudada sobre isso, valeu.

Temos que :

              1             
1*10^-3 = -------- * 4*4 (X+1)*1
4000000

4000 = 16X+16

16X=4000-16

X=3984
----
16

X=249

Estava dividindo 1 por todo o resto, por isso não dava certo. Agora está claro, obrigado novamente.

Não. O Prescaler determina o tempo da interrupção. O Postcaler apenas diz quantas vezes o Timer2 tem q estourar para chamar a interrupção. Se você determina com o Prescaler e o Periodo do Timer2 o tempo de 1s para ele estourar mas quer 2s, você seta 2 como Postcaler.

Ficou claro, valeu.

Matheus, obrigado por seus posts, foram muito úteis!

Link para o comentário
Compartilhar em outros sites

  • 2 anos depois...

por enquanto 16f877a, mais pra frente pretendo migrar pra ums pics mais parrudos, vi um programa que você fez pra 3 saidas pwm, mas fiquei com umas duvidas quanto a ele. por exemplo eu fiz umas contas e la parece que a frequencia de pwm ficava em torno de 840 hz, é isso mesmo, outra coisa você utilizou o periodo indo até 255, isso era valor de quanto o duty cicle podia variar? se sim poderia altera-lo pra 100, e caso fizesse isso teria uma diferença muito significativa?

Link para o comentário
Compartilhar em outros sites

  • 2 semanas depois...

Felipeetec,

Não ví o programa, mas o valor de 255 utilizado deve ser devido ao fato de o timer/pwm utilizado é de 8 bits apenas; portanto o duty do sinal gerado pode ir de 0 a 100% conforme o valor do timer/pwm varie entre 0 e 255.

Se voce utilizar um timer/pwm de 16 bits, para variar o duty entre 0 e 100% voce usaria valores entre 0 e 65535, entendeu ? Isto permite uma precisão muito maior.

No caso de sua pergunta, se voce utilizar um valor máximo de 100 voce só poderá varia o duty entre 0 e 39,2 % .

Paulo

Link para o comentário
Compartilhar em outros sites

  • 4 semanas depois...

Demorei mas voltei....XD

entaom aphawk, esse 255 realmente era a resolução do pwm, como o matheus faz o pwm por software essa resolução pode ser determinada por ele mesmo, eu pensei em utilizar de 0 a 100, pra ficar fácil asimilar com porcentagem.

Agora vamos aos problemas:

Meu software ira fazer a leitura de 2 canais pwm, utilizando modulos ccp's, e a leitura desses canais irao me indicar como deverei proceder com 4 saidas pwm.

Estou utilizando o timer1 como base dos ccp's, e estou utilizando o timer2 pra criar uma rotina de escaneamento e proteção das entradas ccps.

Para as saídas pwm estou utilizando o timer0, mas só consegui chegar numa frequencia de 195 hz, gostaria de chegar em uma frequencia entre 1Khz e 10Khz, para isso tentei setar o timer0 em 206 todas vez qe ocorre uma interrupção, mas mesmo assim ainda n sai dos 195hz, tentei utilizar valores maiores e mais proximos de 255 (que é o "limite"), mas na hora de rodas a simulação n funciona, as saidas todas param de funcionar.

Obs: estou utilizando o proteus para simular.

meu timer0 esta setado da seguinte maneira:

setup_timer_0(RTCC_DIV_2|RTCC_INTERNAL);

opa, alterando um pequeno erro:

é DIV 1, malz ae tava testando pra ver se conseguia alguma coisa, mas nda.

setup_timer_0(RTCC_DIV_1|RTCC_INTERNAL);

Link para o comentário
Compartilhar em outros sites

Colega felipeetec, um dos entraves do PWM por software seria esse mesmo: baixa frequencia. Se precisa de alta frequencia, nao tem jeito, precisa usar o hardware.

Se você deixar o timer muito próximo do limite, o PIC trava mesmo. Não sobra tempo paar ele executar mais nada além da interrupção.

veja que estamos trabalhando com C. Os problemas aumentam nessa linguagem no quesito tempo crítico.

Posso sugerir um PIC mais parrudo que tenha mais canais PWM via hardware que é o caso do 18F4431. Custa R$20 na farnell a última vez que vi.

Falou

Link para o comentário
Compartilhar em outros sites

felipeetec, veja que esse PIC possui 4 canais Power PWM (PPWM), ou seja, ele possui 4 canais PWM e mais 4 complementares......

São usados em inversores por exemplo.

Quando o PPWM 1 estiver em 1 o complementar estará em 0.

No seu caso, você poderia usar os 4 PPWM + os 2 PWM normais via CCP1 e CCP2. Mas veja se realmente precisa de um PIC desse tamanho.

Exemplo que fiz:

j8lsv.jpg

#include<18F4431.h>

#fuses HS, NOWDT, NOPROTECT, NOBROWNOUT, PUT, NOLVP
#use delay(clock=8000000)

#define POWER_PWM_PERIOD 1600 // 1 KHz pwm freq with 8 MHz osc.

//=======================================
void main()
{
// Setup the 4 Power PWM channels as ordinary pwm channels.
setup_power_pwm_pins(PWM_COMPLEMENTARY,PWM_COMPLEMENTARY,PWM_COMPLEMENTARY,PWM_OFF);

// Mode = Free Run
// Postscale = 1 (1-16) Timebase output postscaler
// TimeBase = 0 (0-65355) Initial value of PWM Timebase
// Period = 2000 (0-4095) Max value of PWM TimeBase
// Compare = 0 (Timebase value for special event trigger)
// Compare Postscale = 1 (Postscaler for Compare value)
// Dead Time

setup_power_pwm(PWM_DEAD_CLOCK_DIV_16|PWM_FREE_RUN, 1, 0, POWER_PWM_PERIOD, 0, 1,63);

set_power_pwm0_duty((int16)((POWER_PWM_PERIOD *4) * .5)); // 50%
set_power_pwm2_duty((int16)((POWER_PWM_PERIOD *4) * .5)); // 50%
set_power_pwm4_duty((int16)((POWER_PWM_PERIOD *4) * .5)); // 50%
set_power_pwm6_duty((int16)((POWER_PWM_PERIOD *4) * .5)); // 50%

while(1);
}

Falou

Link para o comentário
Compartilhar em outros sites

Na vdd esse pic parece ser ideal para minha aplicação pois ja projetei a placa para o pic 16f877a e a pinagem bate perfeitamente com o 18f4431, quais sao os pinos dos 4 PWM e dos 4 complementares, eles tem diferença ou isso eu determino por software, amanha a tarde começarei a tentar desenvolver alguns testes, assim que conseguir alguma coisa posto os resultados.

Link para o comentário
Compartilhar em outros sites

Sim, os pinos possuem diferença. Como mencionei acima, ele possui 4 PPWM e + 4 complemetares. Os ocmplementares funcionam ao contrário do comum. Se por exemplo eu tiver 90% de duty cicle no PPWM 1, seu complemento terá 10%.

Veja os pinos abaixo:

18F4431_out_PPWM.png

repare no osciloscópio que os complementares estão ao contrário do normal. Acredito que você usaria somente os normais. Mas você ainda pode configurar o PWm comum via CCP usando o timer 2 ainda. Dessa forma, no final você terá 6 canais PWM via hardware.

Caso precise de mais canais, você ainda pode agora criar mais via software (mais lento) sendo que eles ficarão mais folgados já que temos 6 via hardware.

Falou

Link para o comentário
Compartilhar em outros sites

Entaom matheus, primeiramente obrigado pela ajuda que você ta me dando, acabei de montar no proteus o circuitinho e testei a programação que você me passou, funcionou exatamente como previsto, agora qero entender oqe ocorre na programação:

Minhas dúvidas:

1º-

O que significa essa configuração abaixo, eu entendi que é a maneira qe os pinos pwm irao trabalhar, correto? mas que opções eu tenho de config pra eles? e quais as diferenças entre elas?

setup_power_pwm_pins(PWM_COMPLEMENTARY,PWM_COMPLEMENTARY,PWM_COMPLEMENTARY,PWM_OFF);

2º-

O que é o modo free run? tem outros modos que ele trabalha?

Como funciona esse período descrito na programação?Eu entendi que variando ele eu vario a frequencia, mas essa é sua utilidade realmente sua utilidade?

setup_power_pwm(PWM_DEAD_CLOCK_DIV_16|PWM_FREE_RUN, 1, 0, POWER_PWM_PERIOD, 0, 1,20);

3º-

Eu li no datasheet que esses pwm tem resolução de 14 bits, correto? entaom a função abaixo serve pra indicar o duty cicle da saída pwm.

set_power_pwm0_duty((int16)"VALOR DE 0 a 16383"); isso esta correto?

4º-

Como eu preciso de 4 saídas pwm independente, eu teria que utilizar os pinos:

33-PWM0

35-PWM2

38-PWM4

29-PWM6

correto?

Caso eu quisesse usar os PWM0,PWM1,PWM2,PWM3, de modos independente seria possível utilizando o hardware do pic?

Por enquanto essas são minhas dúvidas...

Link para o comentário
Compartilhar em outros sites

Bom, não tenho muito conhecimento desse PIC em especial pois não cheguei a usá-lo. Mas para te ajudar dei umas pesquisada aqui de umas duas horas. Encontrei muita coisa legal. esse PIC é muito interessante.

Veja que passarei o que encontrei até agora. No datasheet tem tudo. Lá explica cada função ao pé da letra.

O que significa essa configuração abaixo, eu entendi que é a maneira qe os pinos pwm irao trabalhar, correto? mas que opções eu tenho de config pra eles? e quais as diferenças entre elas?

setup_power_pwm_pins(PWM_COMPLEMENTARY,PWM_COMPLEMENTARY,PWM_COMPLEMENTARY,PWM_OFF);

Bom, no CCS temos essas opções:

PWM_ODD_ON: Não entendi para que serve.

PWM_BOTH_ON: Essa achei muito legal e eu não sabia. Ela habilita todos os canais como PWM comuns. Sem ser complementares. Dessa forma podemos ter 10 (dez) canais PWM contando com os 2 CCPs (que podem trabalhar em frequencia diferente) em um mesmo PIC. Show de bola.

PWM_COMPLEMENTARY: Esse seria o padrão. 4 canais e 4 complementares.

O que é o modo free run? tem outros modos que ele trabalha?

PWM_OFF: Desliga o PPWM correspondente.

PWM_FREE_RUN: A contagem para geração do PWM funciona fa forma tradicional. variável incrementa até atingir um valor e reseta.

PWM_SINGLE_SHOT: Tem que ler o datasheet para entender melhor.

PWM_UP_DOWN: Nem sei! Tem que ler o datasheet para entender melhor.

PWM_UP_DOWN_INT: Nem sei. Tem que ler o datasheet para entender melhor.

Como funciona esse período descrito na programação?Eu entendi que variando ele eu vario a frequencia, mas essa é sua utilidade realmente sua utilidade?

Sim, esse período é para o cálculo da frequência. A fórmula é essa:

                 Fosc
----- - frequencia
4
Período = ---------------------
frequencia

Onde Fosc é o clock do PIC. A frequencia é a desejada. Isso não ficou muito claro para mim no início mas consegui pegar um pulo do gato.

Temos essa linha de configuração que postei antes:

setup_power_pwm(PWM_DEAD_CLOCK_DIV_16|PWM_FREE_RUN , 1, 0, POWER_PWM_PERIOD, 0, 1,20);

Falta nela uma opção que eu não sabia mas quando você a omite, o compilador entende que ela está lá com o valor menor, ou default. Isso que entendi até agora. As opções disponíveis e que não estão na linha acima são:

PWM_CLOCK_DIV_4: Aqui seria a padrão.

PWM_CLOCK_DIV_16: Nessa você pode dividir a frequência por 4. É por 4 mesmo e não 16 pois a padão já é 4, então de 4 para 16, você divide por 4.

PWM_CLOCK_DIV_64: Mesma coisa.

PWM_CLOCK_DIV_128: Idem.

Isso aí de cima eu que estou tirando das minhas conclusões momentâneas. Pela pesquisa que fiz.

Eu li no datasheet que esses pwm tem resolução de 14 bits, correto? entaom a função abaixo serve pra indicar o duty cicle da saída pwm.

set_power_pwm0_duty((int16)"VALOR DE 0 a 16383"); isso esta correto?

Essa parte está meio confusa para mim ainda. Sei que tem uma tabela, a 18-2 página 185 do dataheet que mostra vários valores de resolução que dependem de algums variáveis. Não entendi ainda direito.

Mas veja que tem um in16 antes dessa função. Dessa forma, imagino que possa ir até 65535.

Como eu preciso de 4 saídas pwm independente, eu teria que utilizar os pinos:

33-PWM0

35-PWM2

38-PWM4

29-PWM6

correto?

Caso eu quisesse usar os PWM0,PWM1,PWM2,PWM3, de modos independente seria possível utilizando o hardware do pic?

Bom, como disse agora pouco acima, pode usar os pinos em sequencia e independentes usando o comando PWM_BOTH_ON.

Acho que é isso por enquanto.

Falou

Link para o comentário
Compartilhar em outros sites

Matheus descobri algumas coisas, o valor do duty cicle depende do periodo que utilizarmos

Fiz os seguintes testes:

Periodo = 1000, o duty cicle aceita valores de 0 a 4000, oqe correponde a variação de 0 a 100%

Periodo = 2000, o duty cicle aceita valores de 0 a 8000, oqe correponde a variação de 0 a 100%

Link para o comentário
Compartilhar em outros sites

Tem um jeito mais fácil de controlar o duty cicle. Esqueci de comentar.

Eu postei lá no código essa linha:

set_power_pwm0_duty((int16)((POWER_PWM_PERIOD *4) * .5)); // 50%

O que varia o duty cicle na verdade, seria esse 0.5 aí de cima. Se você variar ele entre 0 e 1 você tem de 0 a 100%. Dessa forma, nem precia mexer no período.

Exemplo:

set_power_pwm0_duty((int16)((POWER_PWM_PERIOD *4) * [B].1[/B])); // 10%
set_power_pwm2_duty((int16)((POWER_PWM_PERIOD *4) * [B].4[/B])); // 40%
set_power_pwm4_duty((int16)((POWER_PWM_PERIOD *4) * [B].6[/B])); // 60%
set_power_pwm6_duty((int16)((POWER_PWM_PERIOD *4) * [B].75[/B])); // 75%

O período fica somente para regular a frequencia desejada. Somente. Na verdade isso que eu falei agora é exatamente o que você disse. Mas do jeito que eu disse acho que fica mais fácild e modificar no código. A fórmula acima ela faz exatamente isso. :D

Outra coisa que esqueci de comentar na linha:

setup_power_pwm(PWM_DEAD_CLOCK_DIV_16|PWM_FREE_RUN , 1, 0, POWER_PWM_PERIOD, 0, 1,20);

Troque o 20 po 0. Esse é o valor do dead time. Coisa que você nao irá usar.

Falou

Link para o comentário
Compartilhar em outros sites

Ah sim sim, isso eu consegui entender, entaom acabei de migrar todo meu codigo para o pic18f4431, fui simular e funcionou legal, só tem um peqeno problema, nas saidas pwm, as vezes ele gera sinal em 0 durante 50ms, isso ocorre varias vezes na mesma simulação, n sei se isso afetara de maneira muito ruim meu circuito, mas qeria descobrir o porque isso ocorre, e se possivel consertar.

tai as falhas a que me refiro.

post-527532-13884965102875_thumb.jpg

Link para o comentário
Compartilhar em outros sites

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...