Ir ao conteúdo
  • Cadastre-se

PIC Trabalho de Relógio Microcontrolador


Posts recomendados

Boa Tarde.

 

Tenho um trabalho para realizar com base em Microcontroladores. O objetivo é fazer um relógio no programa Proteus com base no Microcontrolador PIC18F45K22 e a programação é feita no programa MicroC. O relógio tem de ser capaz de dar as horas e os minutos, além de se conseguir alterar as horas e os minutos consoante a vontade do utilizador.

Alguém poderia me ajudar neste trabalho? Só preciso de ajuda, eu próprio irei realizar o trabalho. Estou disposto a pagar pela ajuda.

 

Obrigado.

  • Amei 1
Link para o comentário
Compartilhar em outros sites

6 minutos atrás, Bisão1976 disse:

@Maurinho0 Amigo , tem modulo Rtc já prontos. Só faz o Pic se comunicar com ele e pegar os dados e jogar num display e fazer alteração para por botão de ajustes  . Tem bibliotecas prontas no Mikroc . 


Eu já tenho o modelo no Proteus com o display prontos. Tudo no proteus já está conectado. Contudo, tenho dificuldade com a programação e preciso de ajuda para conseguir fazer a programação certa para colocar o relógio a funcionar.

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

  • Membro VIP

Claro amigo. Estamos aqui pra te ajudar. Mas acho que você deve achar tudo isso (e muito+) semi pronto na net bastando usar as palavras mágicas corretas. Assim que achar, tentar fazer, adaptar ou algo assim, mostre o que fez, o que deu certo, errado, o que deveria dar e etc que há possibilidade de a gente te ajudar com alguma personalização, ok? Concordemos que sua dúvida é superficial e genérica o que dificulta sua condução entende? E receber pela ajuda não nos é uma opção, tá? 😉

  • Curtir 2
Link para o comentário
Compartilhar em outros sites

@.if Neste momento eu tenho um código simples. Consigo apenas colocar os números no display. Contudo, não faço ideia de como programar para que funcione como um relógio.

 

 

 

Aqui a minha programação:

 

//Variáveis

int milhar=0x00;
int centena=0x00;
int dezena=0x00;
int unidade=0x00;

//Configuração do TIMER0
void InitTimer0(){
  T0CON         = 0xC2;
  TMR0L         = 0x06;
  GIE_bit         = 1;
  TMR0IE_bit         = 1;
}

//Interrupção do TIMER0
void Interrupt(){
  if (TMR0IF_bit){
    TMR0IF_bit = 0;
    TMR0L         = 0x06;
         
      while(1){
      
         unidade = 0x3F;
         
          PORTC = 0b00000111;
          PORTD = unidade;
          delay_ms(1);
          PORTC = 0b00001011;
          PORTD = 0x06;
          delay_ms(1);
          PORTC = 0b00001101;
          PORTD = 0x5B;
          delay_ms(1);
          PORTC = 0b00001110;
          PORTD = 0x4F;
          delay_ms(1);
          PORTC = 0b00001111;
          PORTD = 0x4F;


      }
  }
}

   void main() {

   //Portas

   TRISC = 0b00000000;
   TRISD = 0b00000000;
   TRISB.F1 = 1;
   TRISB.F2 = 1;
   TRISB.F3 = 1;
   InitTimer0();
   
   ANSELC = 0;
   ANSELD = 0;
   ANSELB = 0;

}

imagem_2022-06-10_131821445.png

@.if Neste momento eu tenho um código simples. Consigo apenas colocar os números no display. Contudo, não faço ideia de como programar para que funcione como um relógio.

 

 

 

Aqui a minha programação:

 

//Variáveis

int milhar=0x00;
int centena=0x00;
int dezena=0x00;
int unidade=0x00;

//Configuração do TIMER0
void InitTimer0(){
  T0CON         = 0xC2;
  TMR0L         = 0x06;
  GIE_bit         = 1;
  TMR0IE_bit         = 1;
}

//Interrupção do TIMER0
void Interrupt(){
  if (TMR0IF_bit){
    TMR0IF_bit = 0;
    TMR0L         = 0x06;
         
      while(1){
      
         unidade = 0x3F;
         
          PORTC = 0b00000111;
          PORTD = unidade;
          delay_ms(1);
          PORTC = 0b00001011;
          PORTD = 0x06;
          delay_ms(1);
          PORTC = 0b00001101;
          PORTD = 0x5B;
          delay_ms(1);
          PORTC = 0b00001110;
          PORTD = 0x4F;
          delay_ms(1);
          PORTC = 0b00001111;
          PORTD = 0x4F;


      }
  }
}

   void main() {

   //Portas

   TRISC = 0b00000000;
   TRISD = 0b00000000;
   TRISB.F1 = 1;
   TRISB.F2 = 1;
   TRISB.F3 = 1;
   InitTimer0();
   
   ANSELC = 0;
   ANSELD = 0;
   ANSELB = 0;

}

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

  • Membro VIP
6 horas atrás, Maurinho0 disse:

Neste momento eu tenho um código simples.

Tá simples e ligeiramente enganado: você coloca o loop principal dentro da interrupt: o while(1) deve ficar no main()..Também falta-lhe a noção de varredura, indexação de tabela e alguns etc. São conceitos básicos que não tenho muita paciên... ops! preparo pra te explicar ok? .o importante é que  acho  que você tentou. De novo, vá de @Bisão1976 e busque por algo pronto e se baseie nele.

  • Curtir 3
Link para o comentário
Compartilhar em outros sites

  • Membro VIP
15 horas atrás, Maurinho0 disse:

Eu preciso de fazer o relógio apenas com a programação em C no MicroC.

Amigo ṕra esta façanha basta entender o relogio e como o tempo passa. Crie as variáveis (ano, mes, dia,) hora, minuto, segundo e as apresente ... ou melhor ... apresente seus 'desenhos' nos ports correspondentes. Como é só pra simular, use um mc com mais pinos e ports: você pode desenhar direto neles sem precisar (ainda) de usar o sistema de varredura que falei lá atrás.  Ou não mostre os segundos: deixe 1 led piscando. O pulo do gato é você saber incrementar as variáveis segundo, minuto, hora (e etc) dentro de uma interrupção de ... 1 segundo 😁 e nela algo como:

if (segundo>59) {segundo=0; minuto++...
if (minuto>59) {minuto=0; hora++...
if (hora>23) {hora=0; //dia++;... 

e colocar o desenho indexado vindo de uma tabela em cada port

PORTA=tabela[segundo/10];
PORTB=tabela[segundo%10];
PORTC=tabela[minuto/10];
PORTD=tabela[minuto%10];
PORTE=tabela[hora/10];
PORTF=tabela[hora%10];
...

São conceitos da linguagem c que não tenho pac... preparo pra lhe explicar ok?

Agora pra acertar horas e minutos e tal vai ter , claro, que criar rotinas pra isso.

 

Mas vem cá... serio que você prefere não clicar em  relogio com pic18f em c?? (clique) 🤪... Ah sim... o que você leu acima não deve achar na busca pois é criação 100% original...   bem... agora vai achar ...😁

 

  • Curtir 3
  • Haha 1
Link para o comentário
Compartilhar em outros sites

@Maurinho0 ,

 

Ou seja, se desligar a alimentação seu relógio começa do zero, certo ?

Use um dos Timers do seu Pic para gerar uma base de tempo, e escolha um cristal oscilador adequado para lhe facilitar a vida no software.

Ou use um cristal oscilador de 32768 Hz numa das portas adequadas para clocks de baixa velocidade, assim fica independente do cristal oscilador principal do Pic.

 

Paulo

  • Curtir 4
Link para o comentário
Compartilhar em outros sites

  • Membro VIP
13 horas atrás, aphawk disse:

se desligar a alimentação seu relógio começa do zero

Boa Paulão. Mas parece que o garoto só quer simular. deve ter sido o que lhe pediu seu professor.

 

Caso ele (ou alguém) 'caia na real'...:

Pra algo de verdade uma alternativa é alimentar o mc com bateria também e usar o tal xtal de relogio. Uma rotina que detecta a queda da fonte pode desligar os display ou sem rotina: alimente o display com a V da fonte. Outra: Não sei quanto a este mas tem mc que o timer continua rodando com o xtal 32768 mesmo quando a cpu dorme.

+ um devaneio: alimentando só com pilha: aperte 1 botão e mostre a hora por 1 segundo. Agora é sério.. o último: sensor de presença: só mostra a hora com alguém se mexendo por perto 🤪...

Enfim... você leu toda esta baboseira pois um relógio normal qualquer 1 faz... é pra você fazer  e ser diferente...🙃

Mas uma coisa de cada vez pra o autor não ter congestão

obs: editei o post lá atrás com orientações complementares...

  • Curtir 2
  • Haha 1
Link para o comentário
Compartilhar em outros sites

@.if @Bisão1976 Olá amigos. Não vim aqui ontem porque não tive tempo, mas pode-se dizer que tive um pouco de progresso!

 

Falando do relógio, acho que consegui fazer um programa que simula o mesmo. O programa que eu fiz, consegue fazer com que o relógio funcione autonomamente, avançando o tempo, contudo tenho um problema. Eu utilizo os Delays para poder mostrar os números no Display, ou seja, para que os números sejam todos mostrados nos displays (as unidades, dezenas, centenas e milhares) é preciso que o delay seja muito baixo, visto que o display não consegue mostrar eles ao mesmo tempo. Contudo, com um delay baixo, os cálculos necessários que o programa faz para mostrar os segundos e minutos por exemplo, também são feitos muito rápidos, fazendo assim com que o relógio passe o tempo muito rápido e não no tempo real. Poderiam dar-me uma ajuda de como resolver esse problema??

 

Aqui têm o programa abaixo:

 

while(1){

       valoru = uni;
       valord = dez;
       valorc = cen;
       valorm = mil;

       if(uni == 10){   // Utilizado para reiniciar as unidades
         uni = 0;
         dez++;
         valord = dez;
        }
        
        if(dez == 6){   // Utilizado para reiniciar as dezenas
        
           cen++;
           valorc = cen;
           dez = 0;
           valord = dez;
        }
        
        if(cen == 10){    // Utilizado para reiniciar as centenas
           cen = 0;
           mil++;
           valorm = mil;

        }
        
        if (cen == 4 && mil == 2){        // Utilizado para reiniciar os milhares

           cen = 0;
           mil = 0;
           valorc = cen;
           valorm = mil;
        }

        //Unidades
        PORTD = hexcod[valoru%10];      // Codigo Hexadecimal para mostrar o número no display
        PORTC = 0b00000111;       // Liga o Display
        Delay_ms(10);              // Delay para mostras o número
        PORTC = 0b00001111;       //Desliga o Display
        valoru/=10;                // Divide a variável por 10

        //Dezenas
        PORTD = hexcod[valord%10];     // Codigo Hexadecimal para mostrar o número no display
        PORTC = 0b00001011;       // Liga o Display
        Delay_ms(10);              // Delay para mostras o número
        PORTC = 0b00001111;       //Desliga o Display
        valord/=10;                // Divide a variável por 10
        
        //Centenas
        
        PORTD = hexcod[valorc%10];     // Codigo Hexadecimal para mostrar o número no display
        PORTC = 0b00001101;       // Liga o Display
        Delay_ms(10);              // Delay para mostras o número
        PORTC = 0b00001111;       //Desliga o Display
        valorc/=10;                // Divide a variável por 10
        
        //Milhares
        
        PORTD = hexcod[valorm%10];       // Codigo Hexadecimal para mostrar o número no display
        PORTC = 0b00001110;       // Liga o Display
        Delay_ms(10);              // Delay para mostras o número
        PORTC = 0b00001111;       //Desliga o Display
        valorm/=10;                // Divide a variável por 10

        uni++;
    }



Display: 

 

imagem_2022-06-12_133204221.png

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

@Maurinho0 ,

 

Você precisa ter uma base de tempo que seja totalmente independente dos tempos que o seu programa perde para fazer as contas e cuidar dos displays multiplexados .....

 

A solução clássica sempre é usar um dos Timers via interrupção para fazer a contagem para você, por exemplo gerando 100 interrupções por segundo, contando elas até chegar a 100, e ir incrementando os segundos, minutos e horas dentro da interrupção, zerando novamente a contagem e saindo, e o seu programa apenas faria o tratamento dos botões e displays, pegando os resultados prontos das variáveis para mostrar no display.

 

É muito bom ver que você percebeu o problema que está acontecendo, é um excelente aprendizado !

 

Não posso te ajudar nessa linguagem, espere alguém com mais conhecimento aparecer ....

 

Paulo

  • Curtir 2
Link para o comentário
Compartilhar em outros sites

@aphawk@Bisão1976@.if

Olá amigos, tenho boas notícias!!

 

O relógio já funciona!!!! Consegui configurar o timer com a ajuda de um amigo, e por isso a interrupção funciona com 1s. Juntando isso ao meu programa, o relógio funciona normalmente!

 

Agora, tenho outro problema. Eu quero fazer o selecionador. Ou seja, quero os botões para que o utilizador possa escolher a hora e os minutos que deseja!! Eu já consegui fazer isso noutro programa, e funcionava bem. Tenho um botão que se estiver ativado, mudará apenaas as horas e se estiver desativado, mudará apenas os minutos. Depois tenho 2 botões, para aumentar e para diminuir.

 

O problema é juntar esse programa do selecionador ao programa das horas. Eu juntei eles normalmente, e adicionei outro botão, fazendo com que cada vez que esse botão fosse pressionado, o relógio entrasse num "modo de mudança de hora" e o utilizador pudesse então mudar as horas. O problema, é que quando clico nesse botão, o relógio não para o tempo que tem, ele volta ao 0. E depois é que o selecionador pode mudar as horas. E também, quando o selecionador acaba de mudar as horas, e desliga o botão do modo de mudança de horas, o relógio volta ao tempo que estava a contar antes, ignorando as horas que o selecionador colocou.

 

Acham que conseguem ajudar-me nesse sentido?

 

O meu código atualmente:

 

 

       
  //TODO O TIPO DE VARIÁVEIS!!!!!
        //Variável que apresenta os números no display
                         //"0"   "1"  "2"  "3"  "4"  "5"  "6"  "7"  "8" "9"  "0"
 unsigned char hexcod[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x3F};
 
          //Variáveis SELECIONADOR

       unsigned char bot_aumenta;   //Variável para aumentar as horas
       unsigned char bot_diminui;   //Variável para diminuir as horas
       unsigned char bot_selec;     //Variável do selecionador
       unsigned char cntdru, cntdrd, cntdrc, cntdrm;        //Variável de armazenamento do contador
         
         //Variáveis RELÓGIO

       int uni, dez, cen, mil, valoru = 0, valord = 0, valorc = 0, valorm = 0;

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -


        //DECLARAÇÃO PARA O INTERRUPT!!!
        
void InitHardware(void){

     //TRISD=0x00;
    //IRQ
    INTCON.GIE=1; // Enable interrupts
    INTCON.PEIE=0; // Enable internal peripherical interrupts
    INTCON.TMR0IE=1; // Enable IRQ timer0
    INTCON.TMR0IF=0; // Disable Timer0 flag
    //Timer0
    TMR0H=0x0B;
    TMR0L=0xDC;
    T0CON.T08BIT=0; // set as 16 bit timer
    T0CON.T0CS=0; // set as internal clock
    T0CON.PSA=0; // prescaler is enable
    T0CON.T0PS2=1;
    T0CON.T0PS1=0;
    T0CON.T0PS0=0;
    T0CON.TMR0ON=1; // start timer
    /*INTCON3.INT1IE=1; // =1 Enables the INT1 external interrupt.
    INTCON2.INTEDG1=1; // External interrupt 1- IRQ on rising edge 0 - falling edge
    INTCON3.INT1IF=0;
    INTCON.GIE=1; // activar as IRQ's*/
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

void Interrupt(void){

     if(INTCON.TMR0IF==1){
      T0CON.TMR0ON=0;
      TMR0H=0x0B;
      TMR0L=0xDC;
      T0CON.TMR0ON=1;
      INTCON.TMR0IF=0;
      
       uni++;

       if(uni == 10){   // Utilizado para reiniciar as unidades
         uni = 0;
         dez++;
         valord = dez;
        }


        if(dez == 6){   // Utilizado para reiniciar as dezenas
           cen++;
           valorc = cen;
           dez = 0;
           valord = dez;
        }


        if(cen == 10){    // Utilizado para reiniciar as centenas
           cen = 0;
           mil++;
           valorm = mil;
        }


        if (cen == 4 && mil == 2){        // Utilizado para reiniciar os milhares
           cen = 0;
           mil = 0;
           valorc = cen;
           valorm = mil;
        }
        
    }

}


   void main(void) {
   
   //Inicializar as variáveis com 0

         bot_aumenta=0;
         bot_diminui=0;
         bot_selec=0;
         cntdru=0;
         cntdrd=0;
         cntdrc=0;
         cntdrm=0;

    InitHardware();
   //Portas

   TRISC = 0b00000000;  //Saída dos displays
   TRISD = 0b00000000;  // Saída dos números nos displays
   TRISB.F0 = 1;    // Botão para ativar o modo mudança de hora
   TRISB.F1 = 1;   //  Botão do Selecionador
   TRISB.F2 = 1;   // Botão para diminuir as horas
   TRISB.F3 = 1;   // Botão para aumentar as horas
   ANSELC = 0;
   ANSELD = 0;
   ANSELB = 0;
   
   while(1){
   
           while(PORTB.F0 == 1){

                      //SELECIONADOR DOS MINUTOS

                  //Se o selecionador não estiver ligado, muda os minutos

                   if((PORTB.F3==0)&& (PORTB.F1==0) &&(bot_aumenta==0)){   //Se clicar no botão, aumenta uma vez
                      bot_aumenta=1;
                      cntdru++;
                     }

                   if((PORTB.F3==1)&& (PORTB.F1==0) &&(bot_aumenta==1)){   //Para continuar a aumentar
                      bot_aumenta=0;
                   }

                   if((PORTB.F2==0)&& (PORTB.F1==0) && (bot_diminui==0)){   //Se clicar no botão, aumenta uma vez
                      bot_diminui=1;
                      cntdru--;
                   }

                   if((PORTB.F2==1) && (PORTB.F1==0) &&(bot_diminui==1)){   //Para continuar a aumentar
                      bot_diminui=0;
                   }

                   if(cntdru == 60){       // Para reiniciar os minutos ao chegar ao 60
                     cntdru = 0;
                   }

                   valoru = cntdru; //Valor fica com o conteúdo do contador

                   //Mostrar a unidade

                   PORTD = hexcod[valoru%10]; //Faz a conta do resto da divisão por 10, para associar ao código Hexa respetivo
                   PORTC = 0b00000111;       // Liga o Display
                   Delay_ms(2);              // Delay para mostras o número
                   PORTC = 0b00001111;       //Desliga o Display
                   valoru/=10;                // Divide a variável por 10
                   valord = valoru;

                   if(valord ==6) {
                      valord = 0;
                   }

                   //Mostrar a dezena

                   PORTD = hexcod[valord%10]; //Faz a conta do resto da divisão por 10, para associar ao código Hexa respetivo
                   PORTC = 0b00001011;       // Liga o Display
                   Delay_ms(2);              // Delay para mostras o número
                   PORTC = 0b00001111;       //Desliga o Display
                   valord/=10;                // Divide a variável por 10


                   //SELECIONADOR DAS HORAS

                   //Se o selecionador estiver ligado muda as horas

                   if((PORTB.F3==0)&& (PORTB.F1==1) &&(bot_aumenta==0)){   //Se clicar no botão, aumenta uma vez
                      bot_aumenta=1;
                      cntdrc++;
                     }

                   if((PORTB.F3==1)&& (PORTB.F1==1) &&(bot_aumenta==1)){   //Para continuar a aumentar
                      bot_aumenta=0;
                   }

                   if((PORTB.F2==0)&& (PORTB.F1==1) && (bot_diminui==0)){   //Se clicar no botão, aumenta uma vez
                      bot_diminui=1;
                      cntdrc--;
                   }

                   if((PORTB.F2==1) && (PORTB.F1==1) &&(bot_diminui==1)){   //Para continuar a aumentar
                      bot_diminui=0;
                   }

                   if(cntdrc == 24){       // Para reiniciar os minutos ao chegar ao 60
                     cntdrc = 0;
                   }

                   valorc = cntdrc; //Valor fica com o conteúdo do contador

                   //Mostrar a centena

                   PORTD = hexcod[valorc%10]; //Faz a conta do resto da divisão por 10, para associar ao código Hexa respetivo
                   PORTC = 0b00001101;       // Liga o Display
                   Delay_ms(2);              // Delay para mostras o número
                   PORTC = 0b00001111;       //Desliga o Display
                   valorc/=10;                // Divide a variável por 10
                   valorm = valorc;

                   if(valorm == 3){
                     valorm=0;
                   }

                   //Mostrar o milhar

                   PORTD = hexcod[valorm%10]; //Faz a conta do resto da divisão por 10, para associar ao código Hexa respetivo
                   PORTC = 0b00001110;       // Liga o Display
                   Delay_ms(2);              // Delay para mostras o número
                   PORTC = 0b00001111;       //Desliga o Display
                   valorm/=10;                // Divide a variável por 10//
                   valorm = valorc;

                   if(valorm == 3){
                     valorm=0;
                   }

            }

   
       valoru = uni;
       valord = dez;
       valorc = cen;
       valorm = mil;
   
        //Unidades
        PORTD = hexcod[valoru%10];      // Codigo Hexadecimal para mostrar o número no display
        PORTC = 0b00000111;       // Liga o Display
        Delay_ms(1);              // Delay para mostras o número
        PORTC = 0b00001111;       //Desliga o Display
        valoru/=10;                // Divide a variável por 10

        //Dezenas
        PORTD = hexcod[valord%10];     // Codigo Hexadecimal para mostrar o número no display
        PORTC = 0b00001011;       // Liga o Display
        Delay_ms(1);              // Delay para mostras o número
        PORTC = 0b00001111;       //Desliga o Display
        valord/=10;                         // Divide a variável por 10

        //Centenas
        PORTD = hexcod[valorc%10];     // Codigo Hexadecimal para mostrar o número no display
        PORTC = 0b00001101;       // Liga o Display
        Delay_ms(1);              // Delay para mostras o número
        PORTC = 0b00001111;       //Desliga o Display
        valorc/=10;                         // Divide a variável por 10

        //Milhares
        PORTD = hexcod[valorm%10];       // Codigo Hexadecimal para mostrar o número no display
        PORTC = 0b00001110;       // Liga o Display
        Delay_ms(1);              // Delay para mostras o número
        PORTC = 0b00001111;       //Desliga o Display
        valorm/=10;                         // Divide a variável por 10
    }

}

 

 

PIC:

 

imagem_2022-06-12_181145781.png

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

  • Membro VIP

Amigo que interessante que ...

9 horas atrás, Maurinho0 disse:

com a ajuda de um amigo, e por isso a interrupção funciona com 1s

... qualquer coincidência é mera semelhança com o que dissemos Paulão e eu que claro ficamos felizes com seu progresso mesmo assim.

Infelizmente o restante de sua problemática não tem como dar dicas genéricas pois é meio que dedicado ao seu projeto, ideias e hw, Mas mais uma vez lhe digo que buscas, análises, adaptações podem lhe direcionar ao sucesso.

 

 

  • Haha 1
Link para o comentário
Compartilhar em outros sites

  • Membro VIP

Parabéns mano! Que teu professor te dê boa nota. Algo me diz que não vai mencionar nossa contribuição no trabalho mas tudo bem.. Pra tirar um dez conosco eu ia sugerir que publicasse a solução completa mas pensando bem pode não ser muito interessante pra aprendizes do futuro.

Sucessos. :aplausos:

  • Curtir 3
Link para o comentário
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisa ser um usuário 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 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...

 

GRÁTIS: ebook Redes Wi-Fi – 2ª Edição

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!