Página 1 de 2
simulador x pratica

Enviado:
04 Nov 2009 15:32
por thiaguinho_le
ola pessoal,
bem pessoal, resolvi o problema da variação do pwm, faltava uma variavel float e resolvi tambem a questão do pwm se perdendo a 5 volts, mas agora quando ele chega a zera o timer se perde e minha porta onde ta o pwm vai para 5 volts... alguem poderia me dar um help?
- Código: Selecionar todos
#include "ad.h"
unsigned int k;
float x;
void conv(void);
void main()
{
ANSEL = 0b00000001; // configura gp0 como analogica e prescaler em fosc/64
CMCON0 = 7; //configura cin e cout como portas i/o e desabilita comparador
TRISIO = 0b00000001; // gp0 como entrada, todas as outras como saida
// configura ad, GP 0
ADCON0 = 0b10000001; // configura o A/D, utiliza o canal an0, VREF interno, admr a direita
// pino de PWM
GPIO = 0; // gp2 é o pino do pwm
// configurando timer0
OPTION_REG = 0b10000111; //Atribui prescaler de 1:256 ao TMR0
TMR0 = 99; // começa a contagem a partir de 99 ate 256, equivale a 20ms
INTCON = 0b11100000; //Hab. a int. do TMR0, conf. os registros GIE e T0IE
// desabilita os modos de pwm, comparação e captura e habilita gp2 = i/o
CCP1CON = 0;
while(1)
{
if (TMR0==k) // faz o controle de carga do PWM
{
GP2_bit = 1;
}
}
}
void interrupt (void) //rotina de interrupção
{
TMR0 = 99; // determina o periodo do PWM
GP2_bit = 0; // inicializa o PWM em alto
INTCON = 0b11100000; //Configura T0IE e limpa T0IF, em bin 0b00100000
ADCON0 = 0b10000001; // configura ad
Delay_us(5); // 5us necessarios para a leitura do adc
GO_DONE_bit = 1; // seta o bit para se fazer a leitura
while(GO_DONE_bit); // quando o bit retorna para zera é feito a leitura do ad
x = ((ADRESH<<8)+ADRESL); // guarda na variavel x o valor lido no adc
k = 99+(x*156)/1024; // valor de carga ja com a conversão para a comparação com o timer
}
valeu ai
abraço
obs... erros aconttecem nas melhores familias... to quase conseguindo

Enviado:
04 Nov 2009 15:42
por xultz
Quando postar código aqui, coloca ele entre tags "code" prá não perder a indentação, fica mais fácil de entender o código.

Enviado:
04 Nov 2009 16:28
por tcpipchip
Tenta transformar ints em floats
Em vez de 1024, algo do tipo 1024.0, ou (cast float)

Enviado:
04 Nov 2009 16:32
por Djalma Toledo Rodrigues
O Princípio do PWM por Soft:
Da partida ao Contador
Set o pino de saída do PWM
Compara com o Contagem com Valor do Duty Cicle
Se igual (ou maior)
Clear o pino de Saída PWM
Continua a contagem, já que esta é o Periodo do PWM.
.
Observar quer por Hardware é o mesmo princípio.
.

Enviado:
04 Nov 2009 16:34
por xultz
Eu fiquei meio preocupado porque na rotina conv você opera com x que é float e depois joga o valor para dentro do k que é int, isso pode dar todo tipo de problema do mundo.
Aliás, eu adoro código que não comenta o motivo de fazer várias contas, até descobrir o que o programador que com
x = 256 - ( ( ( (5 * x)/1024 ) * 157 ) / 5 )
demora um bocado de tempo


Enviado:
04 Nov 2009 17:05
por Djalma Toledo Rodrigues
Pois é Xults
Justo na hora necessária falta o // Comentário
.

Enviado:
04 Nov 2009 17:31
por thiaguinho_le
bem, valeu as dicas ate aqui pessoal,
so estou tendo esse probleminha agora de ad em zero o timer se perde e vai para 5 o valor do meu pwm... alguem ja passo por isso?
não estou conseguindo simular no proteus pq o proteus naum tem esse pic q estou utilizando.... 12f615... to programando em mikroc
abraço

Enviado:
04 Nov 2009 17:47
por Djalma Toledo Rodrigues
Simula com o PIC12F675
.

Enviado:
04 Nov 2009 17:50
por MOR_AL
Peguei o "bonde andando", não estou bem certo se é isso. Caso não seja, desconsidere.
Introduza limites (inferior e superior).
Se AD < = Limite_Inferior, então TIMER0 = T0_Max (ou T0_Min, vai depender de seu referencial).
Se AD >= Limite_Superior, então TIMER0 = T0_Min (ou T0_Max, vai depender de seu referencial).
MOR_AL

Enviado:
05 Nov 2009 13:13
por thiaguinho_le
valeu a ajuda Mor_al
so que meu problema não é bem esse, eu preciso que o pwm responda em toda a faixa de 0 a 5 volts , de carga minima a maxima, e o q ta acontecendo é que quando eu coloco na entrada do ad o 0 volts, minha saida vai toda para alto... sendo q a mesma deveria estar embaixo :/
bem... e o problema continua hahaha... valeu a ajuda djalma vou simular com o 675... simulei com o 683 e funciono perfeitamente... vai entende...
valeu

Enviado:
05 Nov 2009 15:07
por Djalma Toledo Rodrigues
thiaguinho_le
Para PWM com Duty Cycle de 0 a 100%
Basta testar se Duty = Zero :
Testar: Duty = Zero ?
Clear pino PWM ( Por segurança)
Volta a Testar
Else:
Da partida ao Contador
Set o pino de saída do PWM
Compara com o Contagem com Valor do Duty Cicle
Volta a Comparar até que igual (ou maior)
Clear o pino de Saída PWM
Continua a contagem, já que esta é o Periodo do PWM.
.

Enviado:
12 Nov 2009 09:41
por thiaguinho_le
ola pessoal,
queria vir aqui agradecer a ajuda de todos, valeu djalma pela força, consegui fazer o pwm funcionar sem problemas, estou tendo problemas de oscilação... mas os que tinha de critico esta resolvido...
grato pela ajuda
Thiaguinho

Enviado:
12 Nov 2009 10:07
por MOR_AL
thiaguinho_le escreveu:ola pessoal,
queria vir aqui agradecer a ajuda de todos, valeu djalma pela força, consegui fazer o pwm funcionar sem problemas, estou tendo problemas de oscilação... mas os que tinha de critico esta resolvido...
grato pela ajuda
Thiaguinho
Thiaguinho.
A postagem tem duas finalidades.
A de auxiliar quem solicita e de esclarecer, ou aumentar a experiência, de quem responde.
Seria interessante que você nos contasse como foi resolvida a questão. Mesmo que tenha sido devido a um erro bobo qualquer. Quem sabe poderemos evitar no futuro?
MOR_AL

Enviado:
12 Nov 2009 10:36
por thiaguinho_le
opa, desculpe...
o problema foi resolvido com uma nova equação, e forçando o excesso do limites para os meus valores minimos, utilizei no final a seguinte equação
k=(((140*d)+(107*x)-(247*y))/(x-y))
utilizei a equação da reta, e delimitei meus limites no eixo y (onde se encontra minha resolução, faixa de 140, variando de 107 ate 247), e no eixo x fica facil, deixei meus limites de variação, o sensor que estou usando me fornece uma tensão entre 0.3v ate 3.2v... o unico problema que acontece é, o valor da variavel d é a lida pelo ADC, ela é do tipo float, se coloco ela como int ou char, na pratica o microcontrolador se perde

...
em tese seria isso, desculpe a demora em responde, foi um tempo corrido aqui e acabei naum conseguindo entra no forum...
meu unico problema agora é que a impressão que da é que o timer do microcontrolador ta meio que se perdendo na pratica, ele fica oscilando o seu valor, um delta proximo de 0.3ms... ainda não consegui resolver isso...
por enquanto é isso
grato a todos
thiguinho

Enviado:
12 Nov 2009 14:35
por MOR_AL
Olá Thiaguinho.
Esta sua equação k = f(d, x, y), só é uma reta nos eixos cartesianos x e y, se:
"k" e "d" forem constantes, uma vez que a equação k = f(d, x, y), se reescreve:
y = [(k - 107) / (k - 247)] * x + (140 * d) / (247 - k).
... O que dá a forma da equação da reta y = A * x + B. A e B constantes.
Você deseja que o intervalo no eixo y seja y[107,247].
Agora. Imagino que a entrada seja uma tensão que você aplica no CAD do PIC, certo? Essa entrada produz um valor na saída do CAD entre 0 e 1024. Certo? Então:
Sua reta passa pelos pontos P0(x0,y0) = P0(0,107) e P1(1023,247)
Considerando a equação da reta: (y - y0) = m (x - x0), tem-se:
x0 = 0, y0 = 107 e.... m = (247 - 107) / (1023 - 0)
O que dá:
y = 0,1368523949 * x + 107
Conferindo:
P/ x = 0 --> y = 107 ... E
p/ x = 1023 --> y = 247
O que confere!!
O seu x é a saída do CAD e o seu y é a variável que varia entre 107 e 207.
MOR_AL