Página 1 de 1

Não consegui piscar 2 leds independentes, CCS

MensagemEnviado: 10 Mai 2020 22:14
por erpgc82
Olá pessoal, esta é minha primeira postagem!
Trabalho com eletrônica desde 1996 em manutenção, produção e desenho de placas, só não sei programar firmware.

Comecei a estudar um livro em Abril, a IDE é o CCS, aproveitando essa quarentena.
Já passei mais da metade dos capítulos, mais da metade do livro, com bastante atenção e anotações e decidi então repetir desde o ínicio para aprender melhor.
Porem hoje ao praticar uma mudança num código e já não conseguir fiquei frustrado, gostaria da ajuda de vocês por aqui, se puderem!

O exemplo do livro, é o Exemplo 1, é para piscar apenas um led, ao ligar o circuito, esse eu fiz e funcionou perfeitamente.
Porem ao tentar piscar 2 leds, já não consegui, veja abaixo como fiz nos exemplos 2, 3 e 4:




//Exemplo 1: Funciona 1 LED ok
#include <16f628a.h>
#use delay(clock=4000000)
#fuses INTRC_IO //Irá utilizar clock interno, e os 2 pinos do cristal ficarão disponiveis para Entrada e Saída;
#fuses NOWDT //Whatchdog interno, desabilitado;
#fuses PUT //Aguarda 72ms para estabiliar o circuito e então ligar o PIC;
#fuses BROWNOUT //Monitora se o circuito cair pra menos de 4.5v e resetar o PIC;
#fuses NOLVP //Não efetua gravação por baixa voltagem;
#fuses NOMCLR //Não habilita MASTER CLEAR MOCLR desabilitado, pode usar o PINO MCLR como Entrada e Saída;

void main() //Função principal (corpo principal do programa)
//main() //tambem funciona digitar o comando somente: main()
{ //início do bloco de comandos da função principal;
int tempo; //Variável tempo de 8 bitsl;
tempo = 100; //atribui o valor 100 à variável tempo;
// tambem pode ser escrito: "int tempo=100;"


while(true) //se verdadeiro, fica repetindo, loop infinito. Declara que o bloco de comandos a ser iniciado abaixo, fica repetindo
{ //***** início do bloco de comandos para piscar o led. BLOCO DE INSTRUÇÕES A SEREM REPETIDAS;
output_high(pin_b0); //levanta o pino B0, liga o led;
delay_ms(tempo); //aguarda o valor da variável tempo;
output_low(pin_b0); //abaixa o pino B0, desliga o led;
delay_ms(tempo); //aguarda o valor da variável tempo;
} //***** fim do bloco de comando para piscar o led. BLOCO DE INSTRUÇÕES A SEREM REPETIDAS;
} //Fim do bloco de comandos da função principal;




/*Exemplo 2: Funciona 2 LEDs, porem atrasa a piscada do LED, pois tem que percorrer todos os comandos para
voltar no primeiro e não é isso que eu queria testar; */
#include <16f628a.h>
#use delay(clock=4000000)
#fuses INTRC_IO //Irá utilizar clock interno, e os 2 pinos do cristal ficarão disponiveis para Entrada e Saída;
#fuses NOWDT //Whatchdog interno, desabilitado;
#fuses PUT //Aguarda 72ms para estabiliar o circuito e então ligar o PIC;
#fuses BROWNOUT //Monitora se o circuito cair pra menos de 4.5v e resetar o PIC;
#fuses NOLVP //Não efetua gravação por baixa voltagem;
#fuses NOMCLR //Não habilita MASTER CLEAR MOCLR desabilitado, pode usar o PINO MCLR como Entrada e Saída;

void main() //Função principal (corpo principal do programa)
//main() //tambem funciona digitar o comando somente: main()
{ //início do bloco de comandos da função principal;
int tempo; //Variável tempo de 8 bitsl;
tempo = 100; //atribui o valor 100 à variável tempo;
// tambem pode ser escrito: "int tempo=100;"
int tempo2; // MEU TESTE
tempo2=250; // MEU TESTE


while(true) //se verdadeiro, fica repetindo, loop infinito. Declara que o bloco de comandos a ser iniciado abaixo, fica repetindo
{ //***** início do bloco de comandos para piscar o led. BLOCO DE INSTRUÇÕES A SEREM REPETIDAS;
output_high(pin_b0); //levanta o pino B0, liga o led;
delay_ms(tempo); //aguarda o valor da variável tempo;
output_low(pin_b0); //abaixa o pino B0, desliga o led;
delay_ms(tempo); //aguarda o valor da variável tempo;

output_high(pin_b2); //levanta o pino B2, liga o led; MEU TESTE
delay_ms(tempo2); //aguarda o valor da variável tempo2; MEU TESTE
output_low(pin_b2); //abaixa o pino B2, desliga o led; MEU TESTE
delay_ms(tempo2); //aguarda o valor da variável tempo2; MEU TESTE
} //***** fim do bloco de comando para piscar o led. BLOCO DE INSTRUÇÕES A SEREM REPETIDAS;
} //Fim do bloco de comandos da função principal;





//Exemplo 3: Como imaginei que funcionaria, mas apenas o LED do rb0 funciona corretamente;
#include <16f628a.h>
#use delay(clock=4000000)
#fuses INTRC_IO //Irá utilizar clock interno, e os 2 pinos do cristal ficarão disponiveis para Entrada e Saída;
#fuses NOWDT //Whatchdog interno, desabilitado;
#fuses PUT //Aguarda 72ms para estabiliar o circuito e então ligar o PIC;
#fuses BROWNOUT //Monitora se o circuito cair pra menos de 4.5v e resetar o PIC;
#fuses NOLVP //Não efetua gravação por baixa voltagem;
#fuses NOMCLR //Não habilita MASTER CLEAR MOCLR desabilitado, pode usar o PINO MCLR como Entrada e Saída;

void main() //Função principal (corpo principal do programa)
//main() //tambem funciona digitar o comando somente: main()
{ //início do bloco de comandos da função principal;
int tempo; //Variável tempo de 8 bitsl;
tempo = 100; //atribui o valor 100 à variável tempo;
// tambem pode ser escrito: "int tempo=100;"
int tempo2; // MEU TESTE
tempo2=250; // MEU TESTE


while(true) //se verdadeiro, fica repetindo, loop infinito. Declara que o bloco de comandos a ser iniciado abaixo, fica repetindo
{ //***** início do bloco de comandos para piscar o led. BLOCO DE INSTRUÇÕES A SEREM REPETIDAS;
output_high(pin_b0); //levanta o pino B0, liga o led;
delay_ms(tempo); //aguarda o valor da variável tempo;
output_low(pin_b0); //abaixa o pino B0, desliga o led;
delay_ms(tempo); //aguarda o valor da variável tempo;
} //***** fim do bloco de comando para piscar o led. BLOCO DE INSTRUÇÕES A SEREM REPETIDAS;

{ //***** início do SEGUNDO bloco de comandos para piscar o led do RB2. BLOCO DE INSTRUÇÕES A SEREM REPETIDAS; MEU TESTE
output_high(pin_b2); //levanta o pino B2, liga o led; MEU TESTE
delay_ms(tempo2); //aguarda o valor da variável tempo2; MEU TESTE
output_low(pin_b2); //abaixa o pino B2, desliga o led; MEU TESTE
delay_ms(tempo2); //aguarda o valor da variável tempo2; MEU TESTE
} //***** fim do SEGUNDO bloco de comando para piscar o led. BLOCO DE INSTRUÇÕES A SEREM REPETIDAS; MEU TESTE
} //Fim do bloco de comandos da função principal;





//Exemplo 4: outra tentativa de piscar o outro led;
#include <16f628a.h>
#use delay(clock=4000000)
#fuses INTRC_IO //Irá utilizar clock interno, e os 2 pinos do cristal ficarão disponiveis para Entrada e Saída;
#fuses NOWDT //Whatchdog interno, desabilitado;
#fuses PUT //Aguarda 72ms para estabiliar o circuito e então ligar o PIC;
#fuses BROWNOUT //Monitora se o circuito cair pra menos de 4.5v e resetar o PIC;
#fuses NOLVP //Não efetua gravação por baixa voltagem;
#fuses NOMCLR //Não habilita MASTER CLEAR MOCLR desabilitado, pode usar o PINO MCLR como Entrada e Saída;

void main() //Função principal (corpo principal do programa)
//main() //tambem funciona digitar o comando somente: main()
{ //início do bloco de comandos da função principal;
int tempo; //Variável tempo de 8 bitsl;
tempo = 100; //atribui o valor 100 à variável tempo;
// tambem pode ser escrito: "int tempo=100;"
int tempo2; // MEU TESTE
tempo2=250; // MEU TESTE


while(true) //se verdadeiro, fica repetindo, loop infinito. Declara que o bloco de comandos a ser iniciado abaixo, fica repetindo
{ //***** início do bloco de comandos para piscar o led. BLOCO DE INSTRUÇÕES A SEREM REPETIDAS;
output_high(pin_b0); //levanta o pino B0, liga o led;
delay_ms(tempo); //aguarda o valor da variável tempo;
output_low(pin_b0); //abaixa o pino B0, desliga o led;
delay_ms(tempo); //aguarda o valor da variável tempo;
} //***** fim do bloco de comando para piscar o led. BLOCO DE INSTRUÇÕES A SEREM REPETIDAS;

} //Fim do bloco de comandos da função principal;

void piscaled2() //Função piscaled2
//main() //tambem funciona digitar o comando somente: main()
{ //início do bloco de comandos da função principal;
int tempo2; //Variável tempo de 8 bitsl;
tempo = 250; //atribui o valor 100 à variável tempo2;


while(true) //se verdadeiro, fica repetindo, loop infinito. Declara que o bloco de comandos a ser iniciado abaixo, fica repetindo
{ //***** início do bloco de comandos para piscar o led. BLOCO DE INSTRUÇÕES A SEREM REPETIDAS;
output_high(pin_b2); //levanta o pino B2, liga o led;
delay_ms(tempo2); //aguarda o valor da variável tempo2;
output_low(pin_b2); //abaixa o pino B2, desliga o led;
delay_ms(tempo2); //aguarda o valor da variável tempo2;
} //***** fim do bloco de comando para piscar o led do portB, pino 2. BLOCO DE INSTRUÇÕES A SEREM REPETIDAS;
}




Onde está o meu erro, pois consigo compilar corretamente mas não consigo piscar 2 leds de forma independentes?

Re: Não consegui piscar 2 leds independentes, CCS

MensagemEnviado: 11 Mai 2020 07:15
por Red Neck Guy
Para referenciarmos a seguir:
cpp code
//Exemplo 4: outra tentativa de piscar o outro led;
#include <16f628a.h>
#use delay(clock=4000000)
#fuses INTRC_IO //Irá utilizar clock interno, e os 2 pinos do cristal ficarão disponiveis para Entrada e Saída;
#fuses NOWDT //Whatchdog interno, desabilitado;
#fuses PUT //Aguarda 72ms para estabiliar o circuito e então ligar o PIC;
#fuses BROWNOUT //Monitora se o circuito cair pra menos de 4.5v e resetar o PIC;
#fuses NOLVP //Não efetua gravação por baixa voltagem;
#fuses NOMCLR //Não habilita MASTER CLEAR MOCLR desabilitado, pode usar o PINO MCLR como Entrada e Saída;

void main() //Função principal (corpo principal do programa)
//main() //tambem funciona digitar o comando somente: main()
{ //início do bloco de comandos da função principal;
int tempo; //Variável tempo de 8 bitsl;
tempo = 100; //atribui o valor 100 à variável tempo;
// tambem pode ser escrito: "int tempo=100;"
int tempo2; // MEU TESTE
tempo2=250; // MEU TESTE


while(true) //se verdadeiro, fica repetindo, loop infinito. Declara que o bloco de comandos a ser iniciado abaixo, fica repetindo
{ //***** início do bloco de comandos para piscar o led. BLOCO DE INSTRUÇÕES A SEREM REPETIDAS;
output_high(pin_b0); //levanta o pino B0, liga o led;
delay_ms(tempo); //aguarda o valor da variável tempo;
output_low(pin_b0); //abaixa o pino B0, desliga o led;
delay_ms(tempo); //aguarda o valor da variável tempo;
} //***** fim do bloco de comando para piscar o led. BLOCO DE INSTRUÇÕES A SEREM REPETIDAS;

} //Fim do bloco de comandos da função principal;

void piscaled2() //Função piscaled2
//main() //tambem funciona digitar o comando somente: main()
{ //início do bloco de comandos da função principal;
int tempo2; //Variável tempo de 8 bitsl;
tempo = 250; //atribui o valor 100 à variável tempo2;


while(true) //se verdadeiro, fica repetindo, loop infinito. Declara que o bloco de comandos a ser iniciado abaixo, fica repetindo
{ //***** início do bloco de comandos para piscar o led. BLOCO DE INSTRUÇÕES A SEREM REPETIDAS;
output_high(pin_b2); //levanta o pino B2, liga o led;
delay_ms(tempo2); //aguarda o valor da variável tempo2;
output_low(pin_b2); //abaixa o pino B2, desliga o led;
delay_ms(tempo2); //aguarda o valor da variável tempo2;
} //***** fim do bloco de comando para piscar o led do portB, pino 2. BLOCO DE INSTRUÇÕES A SEREM REPETIDAS;
}

Re: Não consegui piscar 2 leds independentes, CCS

MensagemEnviado: 11 Mai 2020 07:20
por Red Neck Guy
Welcome on bord erpgc82!!!

Resumidamente:
A função main é a primeira a ser chamada após a inicialização do sistema. No seu programa, dentro dela existe um loop infinito e você nunca faz nenhuma chamada para pisca_led2.
O que você precisa entender é que a execução é sequencial - não vamos entrar em interrupções por agora, então a partir de main é que as coisas serão executadas.
Não ocorrem erros na compilação pois não existe erro de sintaxe, aqui o que ocorre é um erro de lógica. Compiladores mais sérios como o GCC e o IAR informam que essa função nunca é chamada.

Re: Não consegui piscar 2 leds independentes, CCS

MensagemEnviado: 11 Mai 2020 07:23
por Red Neck Guy
cpp code
//Exemplo 3: Como imaginei que funcionaria, mas apenas o LED do rb0 funciona corretamente;
#include <16f628a.h>
#use delay(clock=4000000)
#fuses INTRC_IO //Irá utilizar clock interno, e os 2 pinos do cristal ficarão disponiveis para Entrada e Saída;
#fuses NOWDT //Whatchdog interno, desabilitado;
#fuses PUT //Aguarda 72ms para estabiliar o circuito e então ligar o PIC;
#fuses BROWNOUT //Monitora se o circuito cair pra menos de 4.5v e resetar o PIC;
#fuses NOLVP //Não efetua gravação por baixa voltagem;
#fuses NOMCLR //Não habilita MASTER CLEAR MOCLR desabilitado, pode usar o PINO MCLR como Entrada e Saída;

void main() //Função principal (corpo principal do programa)
//main() //tambem funciona digitar o comando somente: main()
{ //início do bloco de comandos da função principal;
int tempo; //Variável tempo de 8 bitsl;
tempo = 100; //atribui o valor 100 à variável tempo;
// tambem pode ser escrito: "int tempo=100;"
int tempo2; // MEU TESTE
tempo2=250; // MEU TESTE


while(true) //se verdadeiro, fica repetindo, loop infinito. Declara que o bloco de comandos a ser iniciado abaixo, fica repetindo
{ //***** início do bloco de comandos para piscar o led. BLOCO DE INSTRUÇÕES A SEREM REPETIDAS;
output_high(pin_b0); //levanta o pino B0, liga o led;
delay_ms(tempo); //aguarda o valor da variável tempo;
output_low(pin_b0); //abaixa o pino B0, desliga o led;
delay_ms(tempo); //aguarda o valor da variável tempo;
} //***** fim do bloco de comando para piscar o led. BLOCO DE INSTRUÇÕES A SEREM REPETIDAS;

{ //***** início do SEGUNDO bloco de comandos para piscar o led do RB2. BLOCO DE INSTRUÇÕES A SEREM REPETIDAS; MEU TESTE
output_high(pin_b2); //levanta o pino B2, liga o led; MEU TESTE
delay_ms(tempo2); //aguarda o valor da variável tempo2; MEU TESTE
output_low(pin_b2); //abaixa o pino B2, desliga o led; MEU TESTE
delay_ms(tempo2); //aguarda o valor da variável tempo2; MEU TESTE
} //***** fim do SEGUNDO bloco de comando para piscar o led. BLOCO DE INSTRUÇÕES A SEREM REPETIDAS; MEU TESTE
} //Fim do bloco de comandos da função principal;

Re: Não consegui piscar 2 leds independentes, CCS

MensagemEnviado: 11 Mai 2020 07:25
por Red Neck Guy
Você precisa entender a construção do comando while.
while(condições){
// bloco de código
}

No seu caso, você fez:

while(condição)
{
bloco
}

{
bloco
}

O segundo bloco não faz parte do while, você criou um bloco de código avulso.
Como o while é um loop infinito, ele ficará executando e nunca chamará seu bloco avulso.

Re: Não consegui piscar 2 leds independentes, CCS

MensagemEnviado: 29 Nov 2020 14:11
por Guri
Deixa eu dar o meu pitako aqui :mrgreen:

No intuito de ajudar, quero lembrar que aprender de forma correta! Ou umas das corretas :D
É utilizar desde cedo o conceito ''multitarefa'', e acho que é esse o termo correto, se não for me corrijam :D

Se você deseja piscar 2 leds de forma independente, com tempos independentes e que seu FW não fique preso apenas à isso, tudo de forma simples, sem interrupções e coisas quetais. Vai uma dica em mikroc, ainda estou aprendendo o conceito de C -:oops:

Utilizando esse conceito "multitarefa", você tem tempo para fazer bastante coisa "simultâneamente", ou pelo menos aparentemente, apesar das coisas estarem acontecendo sequencialmente.
Pode controlar PWMs, Ler ADCs, mostrar coisas em um LCD, enviar e receber dados pela serial e por aí vai, sua criatividade é o limite.

Segue arquivo com projeto proteus, testado :D

Exemplo _Multitarefa.zip

Re: Não consegui piscar 2 leds independentes, CCS

MensagemEnviado: 29 Nov 2020 16:10
por vtrx
No compilador CCS,a variável que se usa como argumento da função Delay,tem que ser de 16 bits.
Código: Selecionar todos
int16 tempo; //Variável tempo de 8 bitsl(tem que ser de 16 Bits);

Re: Não consegui piscar 2 leds independentes, CCS

MensagemEnviado: 29 Nov 2020 18:09
por andre_luis
Red Neck Guy,

Pra fazer o que voce quer, teria de usar uma das 2 opções, ou Interrupção por Timer, ou contador de tempo para cada LED.

O mais simples seria com contador, mas recomendo partir direto para a interrupção.
Faz primeiro com Timer0 para um LED, e depois faz pro outro LED por exemplo com Timer1

Interrupção
Código: Selecionar todos
  // no inicio do main()

  setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256);
  set_timer0(10);                // um valor qualquer, calcular, ajustar
  clear_interrupt(INT_TIMER0);   
  enable_interrupts(INT_TIMER0);
  enable_interrupts(GLOBAL);     

  // antes do main()

  #INT_TIMER0
  void timer0_isr(void)
  {
  clear_interrupt(INT_TIMER0);    // Clear timer0 interrupt flag bit
  set_timer0(10);
  i++;
  if(i > 15)  // outro valor qualquer, ajustar
    {
      i = 0;
      output_toggle(PIN_A0);   // um pino qualquer, escolher
    }
  }

Re: Não consegui piscar 2 leds independentes, CCS

MensagemEnviado: 01 Dez 2020 19:15
por tcpipchip
outra opção pode ser STATE MACHINE

http://www.thebox.myzen.co.uk/Tutorial/ ... chine.html

Re: Não consegui piscar 2 leds independentes, CCS

MensagemEnviado: 01 Dez 2020 20:21
por Guri
Porém o programinha que fiz como exemplo (facilmente traduzido para CCS, o que importa é o conceito), foi uma das formas de utilizar digamos: REAL TIME, sem o uso de interrupções. Eu explico, o uso de interrupções é sem dúvida uma boa pedida. Eu porém penso em fazer tudo através de TIMERs discretos em software, como no exemplo dado por mim e deixar a interrupção para uso crítico, como por exemplo eu tenho que controlar ou monitorar algo que exija a máxima velocidade possível de resposta e processamento de informações. Utilizando o principio que dei de exemplo, você vai entrar num modo muito interessante de CARGA de PROCESSAMENTO. É só uma opinião de um velho e cansado programador de assembler ASM :D
Que se meteu a besta em mexer com C. :mrgreen: