Ir ao conteúdo
  • Cadastre-se
sergiotronic

PIC pisca led com tempo errado

Posts recomendados

Prezados, estou a programar um 12f675 apenas para piscar um led no pino 5, quero que ele fique aceso por 60 segundos e apagado por 500 ms. Não entendo, eu coloco 60000ms no tempo ON e ele não respeita, coloquei 100000ms e deu só 23s marcando num cronômetro. Não quero usar cristal externo. Não preciso de precisão, mas esperraria erro de no máximo 1 segundo + ou -. O que pode estar errado ? Como seria para dar certo ? (estou usando meu velho e funcional gravador JDM com programador PICPgm). Grava com sucesso.

 

Grato

 

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *                 Definição e inicialização das variáveis               *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

# include <12F675.h>

#use   delay(internal = 4000000) // Oscilador interno de 4MHz

#fuses intrc_io
#fuses nowdt
#fuses put
#fuses mclr
#fuses nobrownout
#fuses noprotect
#fuses nocpd

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *                      Definicao das portas                           *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#define PINOLED PIN_A2 //Pino ao qual o led esta ligado

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *                           Rotina Principal                         *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void main()
{
while (1)
 {
  output_bit(PINOLED, TRUE); // Liga o Led
  delay_ms(110000); // Ligado por 1 minuto
  output_bit(PINOLED, FALSE); // Desliga o Led
  delay_ms(700); // Desligado por meio segundo
 }
}

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá meu amigo.

Essa variável que é inserida no delay se não me engano é do tipo int, logo não aceita valores muito altos. Sugiroe

 

1) teste com tempos pequenos (para ver se fuses e xtal estão ok)

2) para contar 1 minuto, crie uma função que chame 60 vezes um delay(1000).

 

Ex:

 

conta minuto(1) // 1 min

 

void contaminuto (int minutos){

for (i = 0; i< 60; i++)

   delay_ms(1000);

   

}

 

Aproveito pra pedir que se inscreva em meu canal. Lá darei dicas sobre programação.

 

https://www.youtube.com/channel/UCI336k2CSm_yZgafEGjjFBA

 

Vamos trocar experiências. Obrigado!

Compartilhar este post


Link para o post
Compartilhar em outros sites
1 hora atrás, sergiotronic disse:

O que pode estar errado ?

A função delay mastigada do ccs ou alguma perdição dele ou algo do gênero.

 

Este mc é muito simples e seu timer também. Domine o hw de um timer e tenha excelente precisão.  Tenho a impressão que é o mesmo do pic16f628... confirme no d.s.

pic8_41e.gif

Ah sim... de fato se for tipo int só permite até 65535...

Compartilhar este post


Link para o post
Compartilhar em outros sites

@Isadora Ferraz

Nem sempre. Eu domino os timers porém esbarro na instabilidade de xtal/capacitores de filtro chineses kkkkk

Compartilhar este post


Link para o post
Compartilhar em outros sites

Caro Delpitec, como seria incluir este trecho no código no CCS ? Tentei de algumas formas aqui mas deu erro. Para não reconhecer a variável i

 

Compartilhar este post


Link para o post
Compartilhar em outros sites
3 horas atrás, Isadora Ferraz disse:

Domine o hw de um timer e tenha excelente precisão. 

O oscilador interno dos chips costumam ter precisão entre 1% e 2%, vai do modelo.

No modelo acima a frequência é de 4MHz. Logo de cara tem um divisor de 4 o que te dá um clock efetivo de 1MHz para o sistema inteiro. Na entrada do timer já se tem um divisor que vai de 1 a 8. Utilizando 8 a frequência cai para 125kHz. O contador vai até 65535, se utilizarmos 62500 teremos 2 reloads por segundo (500ms). Então se setar o valor de top no qual o contador fará o reload, basta setar a geração de um interrupt a cada reload. Para a geração dos 60s vai ter que contar até 120.

Em tese as bibliotecas de alto nível devem fazer essas tarefas por nós evitando as tarefas de se cair no assembler. Quando não se acha tal biblioteca assembler é a saída.

Compartilhar este post


Link para o post
Compartilhar em outros sites
5 minutos atrás, sergiotronic disse:

Caro Delpitec, como seria incluir este trecho no código no CCS ? Tentei de algumas formas aqui mas deu erro. Para não reconhecer a variável i

 

Declarar i

Não esqueça da inscrição hehehe

 

https://www.youtube.com/channel/UCI336k2CSm_yZgafEGjjFBA

 

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

'Outra forma menos traumática: se a função delay500ms estiver funcionando a contento utilize-a numa função FOR para geração dos 60s.

Compartilhar este post


Link para o post
Compartilhar em outros sites

@Sérgio Lembo

 

Se quiser te inscrever lá meu amigo.

Sempre bom ter alguém com conhecimento na troca de ideia

 

https://www.youtube.com/channel/UCI336k2CSm_yZgafEGjjFBA

 

Eu fazia meus timers contando os bits restantes de cada, não tenho aqui agora de cabeça o nome da técnica, mas não usava asy pra resolver. Vou procurar pois faz tempo que somente uso rtc

Compartilhar este post


Link para o post
Compartilhar em outros sites

Caramba, eu não sou programador, estava usando um 555 mas perdi ele e para avançar num outro circuito eu só preciso de 1 led no pino 5 do 12f675 ficando 60 segundos aceso logo ao ligar e 500 ms apagado repetindo isso indefinidamente sem cristal. O tempo OFF 500ms tá funcionando pois eu vejo o led apagar e tornar a acender. Mas falta os 60 segundos. E o máximo qu eu sei fazer é abrir o CCS, abrir um código, compilar, e só...acho que sei também alterar um ou outro pino.

 

Lembo, meu caro, essa sua ideia do FOR parece boa ein. Como ficaria o código ? ali depois do void main pra baixo ? 

Compartilhar este post


Link para o post
Compartilhar em outros sites

vamos mexer naquilo que está dentro do WHILE:

 

while (1) {

output_bit(PINOLED, TRUE); // Liga o Led

for (i = 0; i< 120; i++)  //  Mantem o led ligado por 60s

{

   delay_ms(500);

}

 

output_bit(PINOLED, FALSE); // Desliga o Led

delay_ms(500); // mantem o led desligado por meio segundo

Compartilhar este post


Link para o post
Compartilhar em outros sites

Lembo, como faço para definir o i pois deu undefined identifier

Compartilhar este post


Link para o post
Compartilhar em outros sites

A imprecisão deste método: o tempo gasto será de 120x 500ms + 60x o tempo de processamento da estrutura FOR. Por ser muito rápido o processamento quando comparado a cada 500ms que há no ciclo de repetição o erro pode ser aceitável, depende da aplicação. Outra forma muito mais precisa consiste em colocar os timers em cascata e gerar um PWM na saída. Nessa forma mais precisa a CPU só trabalha na configuração e depois pode ser colocada em sleep, o hardware dos timers trabalham sozinhos e a precisão passa a ser a origem da base de tempo (RC interno ou cristal externo).

adicionado 2 minutos depois

Cada compilador é uma estória diferente. Antes do WHILE declare uma variável e use a variável declarada no lugar do i.

adicionado 4 minutos depois

Assista a esse vídeo sobre a estrutura FOR, vai entender onde está se metendo e aproveitar melhor a ferramenta.

 

Compartilhar este post


Link para o post
Compartilhar em outros sites
agora, sergiotronic disse:

para definir o i pois deu undefined identifier

 

1 hora atrás, sergiotronic disse:

eu não sou programador

percebe-se kk

 

Logo abaixo do main()

{

unsigned char i; //valor máximo = 255

...

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

Sérgio Lembo e Isadora F rs), gravou sem erro mas no cronômetro o LED pisca com 38 segundos. Veja como ficou o código:

 

 

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *                      Definicao das portas                           *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#define PINOLED PIN_A2 //Pino ao qual o led esta ligado

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *                           Rotina Principal                         *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void main()
{ 
unsigned char i; //valor máximo = 255

while (1)
 {
   output_bit(PINOLED, TRUE); // Liga o Led
   for (i = 0; i< 120; i++)  //  Mantem o led ligado por 60s
   {
   delay_ms(500);
   }

output_bit(PINOLED, FALSE); // Desliga o Led
delay_ms(500); // mantem o led desligado por meio segundo

 }
}

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Faça um teste pra um segundo

while (1) {
output_bit(PINOLED, TRUE); // Liga o Led
delay_ms(500);
output_bit(PINOLED, FALSE); // Desliga o Led
delay_ms(500);
}

Não deu? então faça um segundo teste

while (1) {
output_bit(PINOLED, TRUE); // Liga o Led
delay_ms(250);delay_ms(250);
output_bit(PINOLED, FALSE); // Desliga o Led
delay_ms(250);delay_ms(250);
}

E aí...?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Isadora, então era para não usar mais a função for, nem unsight char, e tal. E usar somente este novo código. Se foi isso eu gravei com sucesso mas aí o led fica piscando rápido sem parar acho que 1 vez a cada meio segundo. Amanhã eu volto aqui pra ver se há mais sugestões.

Compartilhar este post


Link para o post
Compartilhar em outros sites

@Isadora Ferraz , desconfio que o RC do chip tá mais rápido do que deveria. Como só consegue cronometrar o tempo grande não se percebe que o tempo curto tb está mais rápido do que deveria.

Compartilhar este post


Link para o post
Compartilhar em outros sites
1 hora atrás, Sérgio Lembo disse:

@Isadora Ferraz , desconfio que o RC do chip tá mais rápido do que deveria. Como só consegue cronometrar o tempo grande não se percebe que o tempo curto tb está mais rápido do que deveria.

Sei que o pic12f675 tem um registrador que vem setado de fábrica com a calibração do cristal interno.

Pode ser uma solução

Compartilhar este post


Link para o post
Compartilhar em outros sites

@DELPITEC , onde que o autor vai ter uma base de tempo confiável para calibrar isso? Não li o datasheet desse modelo mas estou achando que a diferença está muito grande até mesmo para o range dessa calibração o clock está dando 58% a mais. Posso estar errado.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bdia. para ser mais exato tá dando 40 segundos quase (41). Criei um novo projeto no CCS 5 para usar o código num 12f629 que também tenho aqui. Gravou sem erro e os 40-41 segundos continuam. Criei 30 delay_ms(2000); um atrás do outro e nada mudou. Minha montagem é banal capacitor entre os pinos 1 e 8 e 10K do pino 4 ao +5 volts. Mudei o pino de A2 para A0 mas não resolveu. Uso o mesmo hardware-gravador de sempre JDM e o programador PICPGM, aliás esta dupla comigo nunca deu problema.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Tem que ver se o argumento da delay() é tipo char ou int. Como você não é programador e eu não vou com a cara do ccs, há um impasse. Um teste caminho do meio...
 

while (1) {
output_bit(PINOLED, TRUE);
delay_ms(256); //<-!!
output_bit(PINOLED, FALSE);
delay_ms(255);
}

Nos informe...

Se ficar mais apagado do que aceso, é porque é tipo char. Neste caso valor máximo=255

 

E sim a calibração do osc tem um pouco a ver (pero no mucho). Leia o conteúdo do mc e veja/mostre o que está no final da área de programa [no buffer do seu programador]

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

@sergiotronic , se tiver outro PIC na mão repita o procedimento. Estou desconfiado que o problema está no clock do seu 12F675. Se a base de tempo está errada o resultado acompanha o erro. Caso tenha um osciloscópio (pode ser daqueles baratinhos) ler o tempo ligado e o tempo desligado. Caso a proporção esteja em 1:120 isso confirmará que o programa está correto e o clock interno fora de parâmetro.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Sérgio eu usei o 629 veja minha mensagem anterior. 

Isadora, o led pisca rápido mas agora fica mais aceso do que apagado, diferença bem pouca. No final do programa tem 3FA4 e no osccal = 0x34FF. Mas quando o oscilador interno está com algum problema o programador PicPgm nem aceita abrir, digo nem reconhece o PIC, e por enquanto está tudo certo tanto com o 12f675 quanto o 12f629...são os únicos que eu tenho.

Compartilhar este post


Link para o post
Compartilhar em outros sites
1 hora atrás, sergiotronic disse:

o led pisca rápido mas agora fica mais aceso do que apagado, diferença bem pouca

Segundo minhas expectativas, você não notaria diferença alguma ou ela seria brutal. delay(256) seria o mesmo que delay(1)... mas enfim. De fato o osciloscópio te daria uma mãozona. Tenta simular no proteus e usa o osciloscopio dele.

E por fim.. esquece esta ***** do delay bugado do ccs. Dá uma estudadinha básica no timer deste mc que como te disse, é bem simples. Infelizmente temos o impasse do compilador e não vou poder te dar microaula...mas olha de novo que fofo

pic-timer-1_block_diag.png

Imagine entrando 1Mhz (4Mhz/4) no prescaler. /8 você vai ter 125Khz na saída. Pode conseguir 2Hz com boa precisão no ultimo bit do TMR1H se dividir por 62500. Pra gerar uma interrupção de 2Hz, carregue TMR1H e  TMR1L com 65535-62500= 0x0bdb => TMR1H=0b;TMR1L=0xdb; e...

... complicado ? por enquanto. Em breve isso pode não lhe ser totalmente inútil. Retorne pra mais uma microaula ou melhor picoaula...

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora





Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas publicações 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...

Aprenda_a_Ler_Resistores_e_Capacitores-capa-3d-newsletter.jpg

ebook grátis "Aprenda a ler resistores e capacitores", de Gabriel Torres

GRÁTIS! BAIXE AGORA MESMO!