Ir ao conteúdo
  • Cadastre-se

Pic18f4550 ccp modo de captura


Posts recomendados

Bom dia todos, estou com um problema e gostaria de saber se alguém pode me ajudar, necessito fazer um programa em c (compilador ccs), que detecte uma borda de subida em um pulso de sinal digital (sinal pwm), até onde eu consegui pesquisar descobri que é necessário utilizar o ccp do pic no modo captura, mas não consegui nenhum exemplo de programas na internet, muito menos quais parâmetros tenho que utilizar e configurar, se alguém puder me ajudar me mandando um exemplo de programa, ou até mesmo o que devo configurar, agradeço bastante pois preciso saber sobre esse assunto urgentemente, obrigado.

Link para o comentário
Compartilhar em outros sites

Com o código abaixo, ele pisca o pino RB0:

#include <16F877A.h>

#FUSES NOWDT //No Watch Dog Timer
#FUSES HS //Clock <=4Mhz
#FUSES PUT //Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection

#use delay(clock=8000000)

#int_ccp1
void ccp1_int(void)
{
output_toggle (PIN_B0);
}

void main()
{
setup_ccp1(CCP_CAPTURE_RE);

enable_interrupts(int_ccp1);
enable_interrupts(global);

while (TRUE);
}

Apenas coloque um sinal quadrado no PINO CCP1.

Falou

Link para o comentário
Compartilhar em outros sites

Antes de tudo, muito obrigado pela resposta MatheusLPS, mas acabei me esquecendo de avisar que o pic que estou utilizando é o 18f4550, e gostaria de saber se este programa funciona neste pic, e se possível também saber como se faz para acionar o timer1, para que se possa saber o tempo que se passa durante cada sinal de subida (mais precisamente a cada 4 sinais, que é o que preciso para meu projeto), e também se você puder, mostrar quais são as variáveis de saída, como o tempo e a que avisa quando ocorrem o 4 sinais.

Link para o comentário
Compartilhar em outros sites

Entendi.

No caso o código funciona perfeitamenteno no 18F4550, apenas troque a primeira linha. Os pinos são compatíveis.

No caso você deseja saber qual o tempo de duraçao de 4 pulsos? Ou você quer saber quando ocorreu o primeiro pulso e o último? Pois se você quiser saber o tempo que durou cada um podemos ter várias possibilidades.

Ele pode ter durado 1 segudo e até várias horas.

Explica essa parte direito.

Falou

Link para o comentário
Compartilhar em outros sites

O meu projeto consiste em um motor motor DC Brushless que gira um disco com 4 furos em suas extremidades (posicionados em distancias iguais entre si), com um Encoder Óptico eu pretendo saber quando tempo se passa durante cada volta do disco (no caso o encoder sendo acionado 4 vezes), para saber isso pretendo contar o tempo entre o primeiro e o quarto acionamento do encoder com o timer 1, assim poderei descobrir a velocidade do motor por isso necessito de alguma variável de retorno que me mostre esse tempo.

Link para o comentário
Compartilhar em outros sites

Fiz uma abordagem diferente. Veja se a mesma será últil.

No programa abaixo, ele fica monitorando o pino CCP1 o tempo todo. O TIMER1 é configurado para gerar 1 segundo.

Dessa forma, sempre vejo em 1 segundo quantos pulsos chegaram no CCP1.

Como você terá 4 buracos, você terá 4 vezes mais pulsos. Apenas divida por 4 a quantidade no final.

/*=============================================================================
Programa exemplo para contagem de pulsos no pino CCP1.
Teste promo_version v1.0
by MatheusLPS (Koala)
=============================================================================*/

#include <18F4550.h> //O PIC utilizado, obrigatório!

#FUSES NOWDT //Sem Watch dog, evitando reset
#FUSES XT //Crystal de oscilação igual a 4mhz
#FUSES PUT //Tempo de início do PIC
#FUSES NOPROTECT //Codigo sem proteção de leitura, software livre!
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection


#use delay(clock=4000000) // Definição do clock utilizado. Obrigatório!

#include <lcd.C> //Inclusão da biblioteca de LCD. Obrigatório!

int16 pulso_total;
int16 pulsos;
int8 aux;

/*=====================
Minha Interrupção:
=======================*/

#int_TIMER1 //Interrupção do Timer1
void temp1s(void) //Funcão. O que deverá ser feiro a cada interrupão.
{
aux++;
if (aux == 2)
{
pulso_total = pulsos;
pulsos = 0;
aux = 0;
}
set_timer1 (3036); //Preload do Timer1
}

#int_ccp1
void trata_pulsos(void)
{
pulsos++;
}

/*=====================
O programa Principal:
=======================*/
void main()
{
lcd_init(); //Inicializa o LCD (obrigatório)!

setup_ccp1(CCP_CAPTURE_RE);
setup_timer_1 (T1_INTERNAL | T1_DIV_BY_8); //Configuração do Timer1 para clock interno = 1E6 dividido por 8

enable_interrupts(INT_CCP1);
enable_interrupts(INT_TIMER1); //Habilita interrupção timer1
enable_interrupts(global); //habilita interrupcão global
set_timer1 (3036); //Preload do Timer1

while(TRUE) //Loop Principal
{
printf(lcd_putc,"\f%lu\npulsos/segundo",pulso_total);
delay_ms (500);
}
}

Arquivo para simulação:

http://www.4shared.com/rar/7Ldd_PCv/Exemplo_pulsos.html

Falou

Link para o comentário
Compartilhar em outros sites

valeu pelo modelo de programa, mas não tem como me enviar esse programa em um arquivo que abra no mplab, porque não consegui utilizar esse arquivo no meu computador, quando crio um projeto em c, e copio esse programa o mplab indica muitos erros, no qual não consigo resolver.

também gostaria de saber se poderia me ajudar em outro problema, estou tentando gerar um sinal pwm no pic 18f4550, com o compilador ccs, no programa mplab, mas para a função que eu quero necessito de uma frequência de 50hz com um período de 20ms,(para poder controlar um esc, que até onde pesquisei funciona da mesma forma que um servo motor), mas só consigo uma frequência de 500hz, já tentei mexer na variável que até onde eu sei muda a frequência, mas só consegui 500Hz, nada menos que isso. Poderia me ajudar me mostrando como consigo a frequência que eu preciso?

dentro do código ta escrito onde eu acho que tem que mudar


#include<18F4550.h>
#include"microv1.h"
#include"teclado.h"
#include "flex_lcd.h"

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

unsigned char tecla='\0';
unsigned char op1, op2;
unsigned int16 duty, duty1,x;
float y,z;

void InitMain()
{

setup_ccp1 (CCP_PWM);


ADCON1 = 0x0F; // Todos pinos AN são I/O Digitais

TRISA = 0xFF; // Configura para ser Entrada
TRISB = 0x00; // Configura para ser saída
TRISC = 0x00; // Configura para ser saída

PORTA = 0x00; //Inicializa as portas
PORTB = 0x00; //Inicializa as portas

}




void main()
{
op1='\0';
op2='\0';
InitMain();
lcd_init();
setup_timer_2(T2_DIV_BY_16, 255, 1);
//até onde eu sei tem que mexer aqui pra mudar a frequência, mas eu achei //esse valor que era pra resulta em 50hz, mas quando coloco no osciloscópio //não dá

inicializa_teclado();

TRISD=0;
TRISE=0;


x=0;
y=0;
z=0;
while (1){



if (le_teclado()=='1'){
x=x+10;
y=y+9765625;
if (x>=1024)
{
x=x-10;
y=y-9765625;
}
}
if (le_teclado()=='2'){
if (x<=0)
{
y=0;
x=0;

}
x=x-10;
y=y-9765625;
}
if (x<=0)
{
y=0;
x=0;

}


z=y/10000000;

//y=x;
lcd_gotoxy (1,1);
printf(lcd_putc, "%s" , "\f");
//printf(lcd_putc, "%s" , "x");
printf(lcd_putc, "%f" , z);


if (x>=1024){
x=0;
}


set_pwm1_duty(x); // Seta valor de Duty Cicle para PWM1

delay_ms(100); // Filtra a mudança muito rápida de valores
}
}
//end while
//end void m

Link para o comentário
Compartilhar em outros sites

A noite vou tentar fazer um projeto no mplab. Nao costumo usar ele. O meu código é para o CCS, o mesmo compilador que você usa.

No caso, você não irá conseguir um pwm de 50Hz via hardware pois seria muito baixo. Tem que ser feito via software. Tenho um pronto.

Mas você disse que seria paa contralar um esc. O que seria isso?

No caso, se for igual a um servo, você precisa de pulsos entre 1ms e 2ms? Com um período total de 20mS (50hz).

Falou

Link para o comentário
Compartilhar em outros sites

valeu, é que o eu utilizo o mplab pra poder usar o gravador do pic, que é do meu colégio, por isso necessito do projeto nesse formato.

informações sobre o esc: http://en.wikipedia.org/wiki/Electronic_speed_control

esc no sentido mais amplo são PWM controladores para motores elétricos. O esc geralmente aceita uma nominal de 50 Hz PWM sinal de entrada servo cuja largura de pulso varia de 1 ms a 2 ms. Quando fornecido com uma largura de pulso de 1 ms a 50 Hz, o CES responde ao desligar o motor de corrente contínua ligada à sua saída. A 1.5 ms de largura de pulso de entrada resultados de sinal em um sinal de saída de 50% ciclo de trabalho que impulsiona o motor a cerca de metade da velocidade. Quando apresentado com 2,0 ms de sinal de entrada, o motor funciona em alta velocidade devido ao ciclo de trabalho de 100% (constantemente) de saída.

sobre a frequência de 50Hz de saída: sou obrigado a utilizar no meu pic um cristal de 8Mhz de entrada

Link para o comentário
Compartilhar em outros sites

Projeto:

http://www.4shared.com/rar/3eluw9GN/Projeto.html

Programa para controlar servos. Veja se resolve pra você:

#include <16F877.H>
#device adc=8
#fuses HS, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

#define LEFT_SERVO_PIN PIN_B0
#define RIGHT_SERVO_PIN PIN_B1

#include <servos.c>

//=========================================
void main()
{
int8 value;

setup_adc_ports(ALL_ANALOG);
setup_adc(ADC_CLOCK_DIV_32);
set_adc_channel(1);

init_servos();


while(1)
{
value = read_adc();
value = (int8)(value / 28.4); // Get value in 0 to 8 range

// printf("value = %u ", value);

if(value >= 4) // Is it 4 to 8 ?
{
// printf("Forward %u\n\r", value -4);
set_servo(LEFT, FORWARD, value - 4); // Go forward
}
else // It's in 0 to 3 range.
{
// printf("Reverse %u\n\r", 4 - value);
set_servo(LEFT, BACKWARD, 4 - value); // Go reverse
}

delay_ms(500);

}

}

Falou

Link para o comentário
Compartilhar em outros sites

Muito obrigado pelo contador de pulsos, consegui fazer ele funcionar, mas quanto a frequência do sinal pwm, não deu muito certo, e também não consegui utilizar aqueles comandos de servo motor que você utilizou como exemplo no ultimo post.

voce disse que tem um software que reduz a frequência:

No caso, você não irá conseguir um pwm de 50Hz via hardware pois seria muito baixo. Tem que ser feito via software. Tenho um pronto.

poderia me enviar esse software, e me explicar como ele funciona, ou alguma outra sugestão de como reduzir essa frequência sem ter que alterar o valor do cristal?, pois sou obrigado a utilizar um cristal de 8MHz.

valeu

Link para o comentário
Compartilhar em outros sites

  • 2 anos depois...

Fiz uma abordagem diferente. Veja se a mesma será últil.

No programa abaixo, ele fica monitorando o pino CCP1 o tempo todo. O TIMER1 é configurado para gerar 1 segundo.

Dessa forma, sempre vejo em 1 segundo quantos pulsos chegaram no CCP1.

Como você terá 4 buracos, você terá 4 vezes mais pulsos. Apenas divida por 4 a quantidade no final.

 

/*=============================================================================Programa exemplo para contagem de pulsos no pino CCP1.Teste promo_version v1.0by MatheusLPS (Koala) =============================================================================*/#include <18F4550.h>            //O PIC utilizado, obrigatório!#FUSES NOWDT                    //Sem Watch dog, evitando reset#FUSES XT                       //Crystal de oscilação igual a 4mhz#FUSES PUT                      //Tempo de início do PIC#FUSES NOPROTECT                //Codigo sem proteção de leitura, software livre!#FUSES NODEBUG                  //No Debug mode for ICD#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O#FUSES NOCPD                    //No EE protection#use delay(clock=4000000)       // Definição do clock utilizado. Obrigatório!#include <lcd.C>                //Inclusão da biblioteca de LCD. Obrigatório!int16 pulso_total;int16 pulsos;int8 aux;/*=====================Minha Interrupção:=======================*/#int_TIMER1              //Interrupção do Timer1void temp1s(void)        //Funcão. O que deverá ser feiro a cada interrupão.{     aux++;   if (aux == 2)   {         pulso_total = pulsos;      pulsos = 0;      aux = 0;   }         set_timer1 (3036);    //Preload do Timer1   }#int_ccp1void trata_pulsos(void){   pulsos++;}/*=====================O programa Principal:=======================*/void main(){   lcd_init();                   //Inicializa o LCD (obrigatório)!      setup_ccp1(CCP_CAPTURE_RE);      setup_timer_1 (T1_INTERNAL | T1_DIV_BY_8);   //Configuração do Timer1 para clock interno = 1E6 dividido por 8         enable_interrupts(INT_CCP1);   enable_interrupts(INT_TIMER1);               //Habilita interrupção timer1   enable_interrupts(global);                   //habilita interrupcão global    set_timer1 (3036);                           //Preload do Timer1         while(TRUE)                                  //Loop Principal   {      printf(lcd_putc,"\f%lu\npulsos/segundo",pulso_total);      delay_ms (500);   }}
Arquivo para simulação:

http://www.4shared.com/rar/7Ldd_PCv/Exemplo_pulsos.html

Falou

 

 Poderiam publicar novamente o exemplo acima ? Pois o link está expirado.

Link para o comentário
Compartilhar em outros sites

  • 2 semanas depois...
Visitante
Este tópico está impedido de receber 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...

Ebook grátis: Aprenda a ler resistores e capacitores!

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!