Não consegui piscar 2 leds independentes, CCS

Software e Hardware para uC PIC

Moderadores: andre_luis, 51, guest2003, Renie

Não consegui piscar 2 leds independentes, CCS

Mensagempor erpgc82 » 10 Mai 2020 22:14

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?
erpgc82
Bit
 
Mensagens: 18
Registrado em: 03 Mai 2020 01:54
Localização: Brazil

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

Mensagempor Red Neck Guy » 11 Mai 2020 07:15

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;
}
ASM51 descanse em paz!
Avatar do usuário
Red Neck Guy
Dword
 
Mensagens: 1968
Registrado em: 12 Out 2006 22:24

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

Mensagempor Red Neck Guy » 11 Mai 2020 07:20

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.
ASM51 descanse em paz!
Avatar do usuário
Red Neck Guy
Dword
 
Mensagens: 1968
Registrado em: 12 Out 2006 22:24

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

Mensagempor Red Neck Guy » 11 Mai 2020 07:23

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;
ASM51 descanse em paz!
Avatar do usuário
Red Neck Guy
Dword
 
Mensagens: 1968
Registrado em: 12 Out 2006 22:24

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

Mensagempor Red Neck Guy » 11 Mai 2020 07:25

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.
ASM51 descanse em paz!
Avatar do usuário
Red Neck Guy
Dword
 
Mensagens: 1968
Registrado em: 12 Out 2006 22:24

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

Mensagempor Guri » 29 Nov 2020 14:11

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
Você não está autorizado a ver ou baixar esse anexo.
DEUS SEJA LOUVADO
GURI (VonNilmam)
Guri
Byte
 
Mensagens: 457
Registrado em: 25 Abr 2010 09:05
Localização: Minas Gerais

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

Mensagempor vtrx » 29 Nov 2020 16:10

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);
Avatar do usuário
vtrx
Dword
 
Mensagens: 2239
Registrado em: 20 Abr 2008 21:01

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

Mensagempor andre_luis » 29 Nov 2020 18:09

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
    }
  }
"Por maior que seja o buraco em que você se encontra, relaxe, porque ainda não há terra em cima."
Avatar do usuário
andre_luis
Dword
 
Mensagens: 5447
Registrado em: 11 Out 2006 18:27
Localização: Brasil - RJ

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

Mensagempor tcpipchip » 01 Dez 2020 19:15

outra opção pode ser STATE MACHINE

http://www.thebox.myzen.co.uk/Tutorial/ ... chine.html
------------------------------------------
http://www.youtube.com/tcpipchip
Avatar do usuário
tcpipchip
Dword
 
Mensagens: 6560
Registrado em: 11 Out 2006 22:32
Localização: TCPIPCHIPizinho!

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

Mensagempor Guri » 01 Dez 2020 20:21

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:
DEUS SEJA LOUVADO
GURI (VonNilmam)
Guri
Byte
 
Mensagens: 457
Registrado em: 25 Abr 2010 09:05
Localização: Minas Gerais


Voltar para PIC

Quem está online

Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante

x