Ir ao conteúdo

Posts recomendados

Postado

    Pessoal alguem pode me ajudar por favor?

    Comecei estudar C para pic com o CCS, desde Maio/2020, consegui fazer muita coisa com sensores, LCD funcionando sozinho, funções, endereço de memória, enfim sem dificuldades...

 

     Estou programando um pic em uma placa que já existe, sem dificuldades, para aprendizado e já aproveitar e re-programar ela oficialmente corrigindo alguns erros do senhor que fez uns 15 anos atrás, porém enrrosquei em fazer o LCD e o Teclado funcionarem no mesmo port, e foi isso que ficou por último 😊.

 

    Até chegou a funcionar mas com falhas, números que não respondem, então fui tentando, tentando, tentando  até que consegui fazer funcionar, colocando aquele delay_ms(1) que está no drive do teclado, mas quando coloquei no programa principal que já está 52% utilizado do PIC, não conseguia chamar o teclado só quando precisa, ele faz o programa principal travar pois deve ser aquela função tec=proctec(), ela fica o tempo todo verificando o teclado, e não só apenas quando alguem pressiona uma tecla, chegava travar o while. Voltei então pro programa pequeno que fiz, que estou utilizando de um livro, e agora nem ele funciona mais, só alguns números, e já tentei de diversas formas, ainda acho que o problema está com a velocidade que está sendo feita a leitura das colunas, por isso coloquei aquele atraso de 1ms e deu certo na primeira vez.

    Alguem pode me ajudar por favor, o que estou fazendo errado?

 

    Estou utilizando o CCS, o PIC é o 16F876, são 12 teclas e o LCD está em 8 bits.

    As 4 linhas estão com um resistor de pull-up aos 5V, valor 100K, as 3 colunas vão direto ao PIC, sem resistor de pull-up.

 

    Segue o drive do teclado "12teclas16F876.c"    

#define  linha1 PIN_B1       // informa ao compilador que  linha1 é o mesmo que PIN_B1
#define  linha2 PIN_B2       // informa ao compilador que  linha2 é o mesmo que PIN_B2
#define  linha3 PIN_B3       // informa ao compilador que  linha3 é o mesmo que PIN_B3
#define  linha4 PIN_B4       // informa ao compilador que  linha4 é o mesmo que PIN_B4
#define coluna1 PIN_B5       // informa ao compilador que coluna3 é o mesmo que PIN_B5
#define coluna2 PIN_B6       // informa ao compilador que coluna2 é o mesmo que PIN_B6
#define coluna3 PIN_B7       // informa ao compilador que coluna1 é o mesmo que PIN_B7

char tec;                    // declara variável tec, tipo char
int1 prestec;                // declara a variável prestec como booleana

/********************************* Key e LCD *********************************/

char scantec(void)           // função scantec que determina qual a tecla foi pressionada // Varredura das teclas
{
    char tec = ' ';          // declara a variável local tec, e a inicializa com o valor ' ' (em branco)
    
    ///////////////////////////////////////////////////////////////////////////
    output_high(coluna1);    // ativa    a coluna1. Houve necessidade de ser nessa ordem para funcionar corretamente as teclas
    output_low(coluna2);     // desativa a coluna2. Houve necessidade de ser nessa ordem para funcionar corretamente as teclas
    output_low(coluna3);     // desativa a coluna3. Houve necessidade de ser nessa ordem para funcionar corretamente as teclas
    delay_ms(1);             // a primeira vez que deu certo, só com esse delay, então fui pro código grande e travava, então voltei
                             // para o código pequeno de teste, e agora os números ficaram malucos..
    
    if(!input(linha1)) tec='2';  // se o botão da linha 1 na coluna 1 for pressionado, faz tec = '1'
    if(!input(linha2)) tec='5';  // se o botão da linha 2 na coluna 1 for pressionado, faz tec = '4'
    if(!input(linha3)) tec='8';  // se o botão da linha 3 na coluna 1 for pressionado, faz tec = '7'
    if(!input(linha4)) tec='0';  // se o botão da linha 4 na coluna 1 for pressionado, faz tec = '*'
      
    ///////////////////////////////////////////////////////////////////////////
    output_high(coluna2);    // ativa    a coluna2. Houve necessidade de ser nessa ordem para funcionar corretamente as teclas
    output_high(coluna1);    // ativa    a coluna1. Houve necessidade de ser nessa ordem para funcionar corretamente as teclas
    output_low(coluna3);     // desativa a coluna3. Houve necessidade de ser nessa ordem para funcionar corretamente as teclas
    delay_ms(1);             // a primeira vez que deu certo, só com esse delay, então fui pro código grande e travava, então voltei
                             // para o código pequeno de teste, e agora os números ficaram malucos..
    
    if(!input(linha1)) tec='1';  // se o botão da linha 1 na coluna 2 for pressionado, faz tec = '2'
    if(!input(linha2)) tec='4';  // se o botão da linha 2 na coluna 2 for pressionado, faz tec = '5'
    if(!input(linha3)) tec='7';  // se o botão da linha 3 na coluna 2 for pressionado, faz tec = '8'
    if(!input(linha4)) tec='*';  // se o botão da linha 4 na coluna 2 for pressionado, faz tec = '0'
   
    ///////////////////////////////////////////////////////////////////////////    
    output_high(coluna3);    // ativa a coluna3. Houve necessidade de ser nessa ordem para funcionar corretamente as teclas
    output_high(coluna2);    // ativa a coluna2. Houve necessidade de ser nessa ordem para funcionar corretamente as teclas
    output_high(coluna1);    // ativa a coluna1. Houve necessidade de ser nessa ordem para funcionar corretamente as teclas
    delay_ms(1);             // a primeira vez que deu certo, só com esse delay, então fui pro código grande e travava, então voltei
                             // para o código pequeno de teste, e agora os números ficaram malucos..

    if(!input(linha1)) tec='3';  // se o botão da linha 1 na coluna 3 for pressionado, faz tec = '3'
    if(!input(linha2)) tec='6';  // se o botão da linha 2 na coluna 3 for pressionado, faz tec = '6'
    if(!input(linha3)) tec='9';  // se o botão da linha 3 na coluna 3 for pressionado, faz tec = '9'
    if(!input(linha4)) tec='#';  // se o botão da linha 4 na coluna 3 for pressionado, faz tec = '#'
   
    output_low(coluna1);     // desativa a coluna3. Houve necessidade de ser nessa ordem para funcionar corretamente as teclas
    output_low(coluna2);     // desativa a coluna2. Houve necessidade de ser nessa ordem para funcionar corretamente as teclas
    output_low(coluna3);     // desativa a coluna1. Houve necessidade de ser nessa ordem para funcionar corretamente as teclas
    delay_ms(1);             // a primeira vez que deu certo, só com esse delay, então fui pro código grande e travava, então voltei
                             // para o código pequeno de teste, e agora os números ficaram malucos..
    
    return(tec);             // retorna o valor de 'tec'
}

char proctec()           // função proctec para o processamento dos botões pressionados
{
    int t;                   // declara a variável 't' do tipo int 8 bits
    t=scantec();             /* chama a função scantec();
                              * verifica se há uma tecla pressionada e guarda na variável 't' o que retornar */

    
    if((t!=' ')&&(!prestec)) // se houver tecla pressionada (t!) e 'prestec' estiver em 0 (nivel baixo), faz o comando abaixo
                             /* este comando if((t!='')&&(!prestec)) tem função anti-bouncing, que aqui é feito por
                              * software. Seu objetivo é evitar os efeitos do rebatimento dos contatos das teclas */
    {
        prestec=TRUE;           // inicializa a variável prestec com o valor 1, ou seja, informa que há tecla pressionada
        if(t!=tec)           // se a tecla atual for diferente da anterior
        {
            delay_ms(10);    // atraso de 10ms
            if(scantec()==t) // lê novamente as teclas e verifica se a mesma tecla ainda está pressionada
                return (t);  // se a mesma tecla ainda estiver pressionada, retorna o caractere da tecla
        }
    }
    prestec=FALSE;               // zera a variável 'prestec'
}

 

    Segue o drive do display em 8 bits "display_8bits16f876.c"

#define rs PIN_C4   // define que o bit 4 do port C se chamará RS: 1(dado) 0(instrução)
#define en PIN_C5   // define que o bit 5 do port C se chamará EN: Descida de 5V para 0V, habilita escrita
#define data output_b // define o portB inteiro como sendo onde serão enviados os dados

void display_cmd(int cmd)   // função para envio de comandos para o display
{
    data(cmd);      // coloca o conteúdo da variável cmd no portD
    output_high(en);// leva o pino en (pino 1 do port e) para nivel alto
    output_low(en); // retorna o pino en para nível baixo
}

void display_send_byte(short int level, int data) // função para envio de dados ou escrita para o display
{
    output_bit(rs,level); // coloca o pino rs no nivel da variavel level
    delay_us(100);        // atraso de 100microssegundos
    display_cmd(data);    // chama a função display_cmd que já tem os dados a serem enviados para o port D
 }

void display_pos_xy(int x, int y)// função para o posicionamento do cursor
{
    int address; // variavel que informa o endereço(posicionamento) do cursor
    if (y!=1)    // se o valor de y for 2 (se não for 1) faz o comando abaixo
        address=0xc0;// atribui 0xc0 à address, "Primeira posição da Segunda linha"
    else        // se não ou caso contrário
        address=0x80;// atribui 0x80 à address, "Primeira posição da Primeira linha"
    
    address+= x-1;   // decrementa o valor da variavel x e o restuldado é somado ao conteudo da variavel
                     // address. Seria o mesmo que address = address + (x-1)
    display_send_byte(0,address); /* Chama a função display_send_byte com o valor 0, informando para
                                   * o display que será enviado um comando, que é a variável address.
                                   * Por exemplo: se x=0x10 (o decimal 16) e y=1, o caractere deverá
                                   * ser escrito na coluna 15(ultima coluna) da linha 1 do display, 
                                   * ou seja: 16-1=15 ou 0x8f. Por outro lado, se x=0x03 e y=2, então
                                   * o caractere deverá ser escrito na coluna 2 (terceira coluna) da
                                   * linha 2 do display, ou seja: 3-1=2 ou 0xc2. Esta função só é usada
                                   * quando se deseja escrever a partir de uma coluna que não seja a 
                                   * primeira, da 1ª ou da 2ª linha, do display. */
}

void write_display(char c)      // função para envio dos comandos e/ou dados para o display
{
    switch(c)                   //declaração de controle switch com a variável C
    {
        case '\f' : display_send_byte(0,1);   // Caso 'c' seja '\f', o dado 1 será enviado ao display
                                              // para apagar todo o seu conteúdo
                    delay_us(1600);           // atraso de 1600 microssegundos
                    break;                    // sai do switch e não testa mais nenhum outro caso
        case '\n' :                           // caso 'c' seja '\n'
        case '\r' : display_pos_xy(1,2);      // caso 'c' seja '\r' muda o cursor para a 2ª linha do display
                    break;                    // sai do switch e não testa mais nenhum outro caso            
        case '\b' : display_send_byte(0,0x10);// caso 'c' seja '\b' desloca o cursor para a esquerda
                    break;                    // sai do switch e não testa mais nenhum outro caso
          default : display_send_byte(1,c);   /* Caso 'c' seja um caractere qualquer, então esse caractere será 
                                               * escrito no display pela função "display_send_byte". note-se que o 
                                               * bit rs, desta vez, está em nível 1, pois se trata de um caractere a
                                               * ser escrito no display e não de um comando*/
    }
}

void display_ini()     // função de inicialização do display
{
    output_low(rs);    // coloca o pino rs em nivel logico baixo
    delay_ms(16);      // aguarda 16ms para garantir que a instrução anterior foi concluida
    
    display_cmd(0x30); // envia o comando 0x30 para o display
    delay_us(4500);    // aguarda 4500us para garantir que a instrução anterior foi concluida
    
    display_cmd(0x30); // envia o comando 0x30 para o display
    delay_us(110);     // aguarda 110us para garantir que a instrução anterior foi concluida
    
    display_cmd(0x30); // envia o comando 0x30 para o display
    delay_us(45);      // aguarda 45micrrosegundos para garantir que a instrução anterior foi concluida
    
    display_cmd(0x38); // envia o comando para a comunicação em 8 bits, display com 2 linhas e matriz 7x5
    
    display_cmd(0x01); // envia comando para limpar o display e enviar o cursor para 1ª coluna da 1ª linha
    delay_us(1600);    // aguarda 1,6milissegundos para garantir que a instrução anterior foi concluida
    
    display_cmd(0x0c); // envia comando para ligar o display sem cursor
    
    display_cmd(0x06); // envia comando para escrever com deslocamento para a direita
    
    // aqui deveria haver um tempo de 45us, e não foi incluida, pois foi constatado na prática, que ela 
    // introduzia falhas no funcionamento do driver
}

 

    Este é o código principal de testes, o leve, não consigo mais fazer o teclado funcionar corretamente, e já funcionou a uns dias atrás.

    Se gravo uma firmware que tenho aqui nesta placa, o teclado funciona normal, isso já descarta a placa.

#include <16F876a.h>        // diretiva que define o pic utilizado, arquivo de cabeçalho, arquivo header
//#case                     // diretiva que define a padronização ANSI
#use delay(clock=10000000)  // frequencia para calculos e atrasos


#fuses HS        // utiliza cristal >4mhz
#fuses NOWDT     // desativa reset por watch dog
#fuses PUT       // aguarda 72ms para estabilizar o circuito elétrico e então liga o PIC
#fuses BROWNOUT  // reset por tensão <4.5v
#fuses NOLVP     // desativa gravação por baixa tensão
//#fuses PROTECT   // protege a firmware contra cópia/leitura
//#fuses CPD       // progete a eeprom contra cópia
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, parity=N, bits=8, stop=1, ERRORS)

#bit tmr0if = 0x0b.2    /* define que o bit2 do registrador INTCON/Timer0 se chamará tmr0if
                         * 1 - o timer0 transbordou/estourou
                         * 0 - o timer0 não transbordou/estourou */
#bit RBPU = 0x81.7  // Bit de habilitação do pull up no port B do PIC16F876 ( não serviu pra nada)
#bit RBPB = 0x181.7
#use fast_io     (a)
//#use standard_io (b)
#use fast_io     (c)


#include "display_8bits16f876.c"    // biblioteca do display
#include "12teclas16F876.c"         // biblioteca do teclado
  
/******************************************************************************/
#define LED_RED   PIN_C0
#define LED_GREEN PIN_C1
#define RELE1     PIN_C2
#define RELE2     PIN_C3
#define BEEP      PIN_C4
/******************************************************************************/
  

////////////////////////////////////////////////////////////////////////////////
// protótipos de função ////////////////////////////////////////////////////////
void boot();    // função de exibição, beep e testes, que ocorre só ao ligar




////////////////////////////////////////////////////////////////////////////////
// variable global /////////////////////////////////////////////////////////////
int conta=0;    // variável global para posicionamento do cursor no LCD

////////////////////////////////////////////////////////////////////////////////
// Função principal ////////////////////////////////////////////////////////////
void main()
{
    setup_timer_0(RTCC_INTERNAL|RTCC_8_BIT|RTCC_DIV_256);
    set_timer0(11); // timer 0 iniciando em 11, prescaler dividindo por 256, para se ter 25.0880000 mili segundos
    
    enable_interrupts(GLOBAL);
    enable_interrupts(INT_RDA);  // inicia o leitor

        
    set_tris_a(0b10110000);
    set_tris_c(0b00000000);
    output_c(0b00000000);
    
    //port_b_pullups(TRUE); // essencial habilitar o registrador RBPU referente ao pullups no portB, se não, o teclado não funciona
    RBPU=0; /* setar o bit RBPU em 0 as teclas funcionam perfeitamente e é o mesmo que port_b_pullups(TRUE); 
            // * setar o bit RBPU em 1, os pullups são desabilitados e as teclas ficam todas desconfiguradas*/
    RBPB=0;    
        
    display_ini();  // inicializa o display
    boot(); // função de boot, versão, testes iniciais
    
    
    prestec=0;  // esta variável está na biblioteca do teclado, como do tipo booelana
    
    while(TRUE)
    {
        //display_pos_xy(1,1);
        printf(write_display,"\fTeste LCD    ");
        //display_pos_xy(1,2);
        printf(write_display,"\fDigite: Senha ");
        delay_ms(50);  // usar aqui para não ficar piscando

        
        tec=proctec();                      // chama a função proctec que está na biblioteca do teclado e guarda o resultado na variável tec
           
        if(prestec)                         // se presetec for verdadeiro, alguma tecla foi pressionada, faz o comando abaixo
        {
                        
            if(conta>=8)                    // se a variável conta for maior ou igual a 8
            {
                conta=0;                    // zera a variável conta, ou seja, se der mais de 16 caracteres, limpa o display
                display_pos_xy(9,2);        // posiciona o cursor na coluna 1, na linha 2 do lcd
                printf(write_display,"        "); // limpa onde estaria o numero digitado
                display_pos_xy(9,2);        // posiciona o cursor na coluna 1, na linha 2 do LCD
            }
            printf(write_display,"%c",tec); // escreve no display o caracter correspondente a tecla pressionada
            printf("%c",tec);               // escreve na saida serial o caractere correspondente a tecla pressionada
            conta++;                        // incrementa a variável conta

        }
        prestec=0; 
    }
}


////////////////////////////////////////////////////////////////////////////////
// Função para boot, testes, exibição de versão ////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
void boot()
{
    printf(write_display,"\f"); // começa limpando a linha 1
    printf(write_display,"\n"); // começa limpando a linha 2
    delay_ms(40);
    
    printf(write_display,"\f    Testes      ");
    printf(write_display,"\nModulo de Testes");
    
    output_high(BEEP);    
    delay_ms(100);
    output_low(BEEP);
    delay_ms(2000);
    
    printf(write_display,"\f Teclado e LCD  ");
    printf(write_display,"\nKey and LCD Port");
       
    int beep_boot;
    for(beep_boot=1; beep_boot<=3; beep_boot++)
    {
        output_high(BEEP);    
        delay_ms(80);
        output_low(BEEP);
        delay_ms(80);
    }
    delay_ms(1500);
    
    printf(write_display,"\fPega Tecla Envia");
    printf(write_display,"\nv_21.0305-2222TD");
    output_high(LED_GREEN);
    delay_ms(50);
    output_low(LED_GREEN);
    delay_ms(50);
       
    output_high(RELE1);
    delay_ms(250);
    output_low(RELE1);
    delay_ms(100);
        
    output_high(LED_RED);
    delay_ms(50);
    output_low(LED_RED);
    delay_ms(50);
    
    int rele2_boot;
    for(rele2_boot=1; rele2_boot<=2; rele2_boot++)
    {
        output_high(RELE2);
        delay_ms(120);
        output_low(RELE2);
        delay_ms(80);
    }
    delay_ms(2000);
    
    printf(write_display,"\f"); // começa limpando a linha 1
    printf(write_display,"\n"); // começa limpando a linha 2
}

    Comecei a gostar de programar(estudar sempre), mas agora estou frustrado com o que imaginava ser fácil!!!

    Fico no aguardo de uma ajuda, obrigado!!!

 

 

 

  • Membro VIP
Postado

Você mostrou a alma. Agora mostre o corpo. Publique o esquema.

Uma técnica consiste em distribuir as funções pelo tempo. Tempo de escrever ignorando a leitura e vice versa.

Outra é fazer uso de interrupção. Sente uma tecla pressionada, vê se pode parar pra tratá-la ou pelo menos avisa o 'cabeça' pra tratá-la quando puder.

Tem outras... mas como disse, pra harmonizar com a 'alma' depende do 'corpo'

Postado
4 horas atrás, .if disse:

Você mostrou a alma. Agora mostre o corpo. Publique o esquema.

Uma técnica consiste em distribuir as funções pelo tempo. Tempo de escrever ignorando a leitura e vice versa.

Outra é fazer uso de interrupção. Sente uma tecla pressionada, vê se pode parar pra tratá-la ou pelo menos avisa o 'cabeça' pra tratá-la quando puder.

Tem outras... mas como disse, pra harmonizar com a 'alma' depende do 'corpo'

    Olá if, fiz o "esqueminha" básico, só da parte do teclado, exatamente como está, isso ajuda?

 

    Então, sobre os tempos, parar isso ou aquilo, acho que estou no caminho certo, pois eu criei várias contagens, usando apenas o timer0.

 

    Enquanto nada ocorre, eu chamo uma função e jogo uma mensagem no LCD, fico com essa mensagem por X tempo, depois de um tempo, exibe uma segunda mensagem, a cada 4x que exibe essa mensagem, mostra uma terceira mensagem.

    Se algo acontece, tudo é zerado, exibe a mensagem dessa função que ocorreu e volta pro while... e fica essa mensagem no LCD por  um tempo, ou caso esse algo que aconteceu se encerre, volta pra mensagem padrão novamente. ,

 

    Aprendi, ou posso estar errado, que não se coloca exibição de mensagem no while principal, pois a mensagem ficará piscando, então sempre exibo mensagem em funções, saio do while, pego a mensagem e volto pro while novamente, devo estar certo.

 

    Só não estou conseguindo fazer o teclado funcionar.

    Aprendi usar buffer circular, então pensei em pegar um caracter, sair do while quando a tecla é pressionada, ir pra uma função pegar o caracter dessa tecla jogar em um buffer circular voltar pro while pra pegar a outra tecla e assim por diante, e quando pegar o caracter # eu encerro o buffer circular e aí envio novamente no LCD o número completo e o código inteiro na serial pra exibir no hyper terminal.

    Mas a questão é que não estou conseguindo mais fazer os números (caracteres) funcionarem corretamente. Não é possível que funcionamento (varredura) de teclado matricial seja tão impreciso assim. 

 

    Quando voce fala em fazer interrupção, seria uma interrupção via programação? Acha necessário? Mas como faria isso? Pois cada tecla está num pino normal digital, e não são pinos de interrupção o portB. 

    Outra coisa, eu vi que no 16f876 tem pull-up, endereço RBPU 0x81 bit 7, então habilitei, não usei a função port_b_pullups, e mesmo assim os pinos do portB continuam em nível baixo, somente os 4 das 4 linhas ficam em 5v devido ao pull-up elétrico.

    

LCD e KBD.jpg

  • Membro VIP
Postado

Tem um tópico muito recente sobre isso. Não me lembro onde/quando. Se o sumido amigo Paulão @aphawk (que me lembro que participou dele) quiser, pode indicar onde está, Leia-o todo.

 

Não analiso com profundidade seu fonte, sorry. Só acho que pode ser muito mais resumido pro quesito título do tópico. No caso do esquema penso que pode bolar um algoritmo como:

-escreva no display e iniba-o com EN=0;

-aguarde a tecla fazendo varredura;

Resumindo: o pulo do gato é EN=0 ... neste caso pode fazer o que quiser com os outros pinos

 

Confira se o esquema é aquele mesmo. Eu colocaria resistores ou diodos pra não dar contato entre 2 terminais quando pressiona tecla.

Postado
15 horas atrás, .if disse:

Tem um tópico muito recente sobre isso. Não me lembro onde/quando. Se o sumido amigo Paulão @aphawk (que me lembro que participou dele) quiser, pode indicar onde está, Leia-o todo.

 

Não analiso com profundidade seu fonte, sorry. Só acho que pode ser muito mais resumido pro quesito título do tópico. No caso do esquema penso que pode bolar um algoritmo como:

-escreva no display e iniba-o com EN=0;

-aguarde a tecla fazendo varredura;

Resumindo: o pulo do gato é EN=0 ... neste caso pode fazer o que quiser com os outros pinos

 

Confira se o esquema é aquele mesmo. Eu colocaria resistores ou diodos pra não dar contato entre 2 terminais quando pressiona tecla.

Olá if, muito obrigado pelas dicas, vou salvar aqui.

Ontem a tarde, dia 20/03 eu de cabeça fresca consegui fazer funcionar com perfeição só usando lógica e variáveis. Com apenas 1 ano de estudo estou me surpreendendo 

Eu parei pra pensar e pensei em câmera lenta. Parei com os testes num código pequeno e fui direto para o meu código principal, realmente removi o delay.

No codigo principal dentro do while deixei a função de verificação e varredura de tecla, em seguida um if conforme no exemplo, após ter pêgo a tecla digitada eu saio imediatamente do while e vou para uma função, nessa função eu jogo a tecla no display, aciono um timer que está no while, para aguardar a proxima tecla digitada caso nada seja digitado em um tempo, exibo uma mensagem e zero tudo, conforme vão sendo digitados adiciono os números a uma matriz.

Por fim ficou mais fácil e melhor do que eu imaginava. Realmente o CCS é fantástico! Vou comprar a licença original...

Ainda vou estudar mais, porém esse é meu primeiro código grande, já fiz outros dois pequenos antes com pic de 8 pinos. Preciso aprender a usar strutura, enumeração, switch, na verdade estudei, mas pôr em prática, pois estou usando apenas for, if e while, algum problema em programar só assim?

Muito obrigado pela suas dicas.

  • Membro VIP
Postado
2 horas atrás, erpgc82 disse:

apenas for, if e while, algum problema em programar só assim?

Não há problema algum,,, caso esteja atendendo suas expectativas do momento. De fato if é a mais importante função do c. ..tente fazer um programa qualquer em c sem if 😁

Quando aprender ponteiros, vetores e afins... me explica. Depois de anos ainda me são pedra no caminho kk...
p.ex. olha isso que fofo que usei há muitos anos pra gravar uma variável float na eeprom ...

Spoiler

 

 

 



#include <ioavr.h>
//*************************************************************
void eepw(unsigned char ucAddress, unsigned char ucData)
{
/* Wait for completion of previous write */
while(EECR_Bit1);
/* Set Programming mode */
EECR_Bit5=EECR_Bit4=0; //Erase and Write in one operation (Atomic Operation)
/* Set up address and data registers */
EEAR = ucAddress;
EEDR = ucData;
/* Write logical one to EEMWE */
EECR_Bit2=1;  //o mesmo que EEMPE bit2
/* Start eeprom write by setting EEWE */
EECR_Bit1=1;  //o mesmo que EEPE bit1
}

//*************************************************************

unsigned char eepr(unsigned char ucAddress)
{
/* Wait for completion of previous write */
while(EECR_Bit1); //bit1
/* Set up address register */
EEAR = ucAddress;
/* Start eeprom read by writing EERE */
EECR_Bit0=1; //bit0
/* Return data from data register */
return EEDR;
}

float pi;

/*struct float_struct        //estrutura de 4 bytes do float 32 bits
{
unsigned char _byte0;
unsigned char _byte1;
unsigned char _byte2;
unsigned char _byte3;
};
*/

/*
#define byte0 *((unsigned char *)(ponteiro)+0))    //4 bytes
#define byte1 *((unsigned char *)(ponteiro)+1))
#define byte2 *((unsigned char *)(ponteiro)+2))
#define byte3 *((unsigned char *)(ponteiro)+3))
*/

/*
union  
{
struct float_struct float_byte;  //4 bytes contidos em...
float _float;      //32 bits
} float_union; //união dos 4 bytes

#define float0 float_union._float  //float todo dividido em 
#define byte0 float_union.float_byte._byte0    //4 bytes
#define byte1 float_union.float_byte._byte1
#define byte2 float_union.float_byte._byte2
#define byte3 float_union.float_byte._byte3
*/

int main( void )
{
float float0;
float *ponteiro;
  
ponteiro = &float0; 
  
float0=3.141592;

//grava os pedaços na eeprom
eepw(0,*((unsigned char *)(ponteiro)+0)); 
eepw(1,*((unsigned char *)(ponteiro)+1)); 
eepw(2,*((unsigned char *)(ponteiro)+2)); 
eepw(3,*((unsigned char *)(ponteiro)+3)); 

float0=0; //destroi

//reconstroi float0 a partir dos pedaços da eeprom
*((unsigned char *)ponteiro + 0)=eepr(0);
*((unsigned char *)(ponteiro)+1)=eepr(1);
*((unsigned char *)(ponteiro)+2)=eepr(2);
*((unsigned char *)(ponteiro)+3)=eepr(3);
  
pi=float0; //taí

for(;;);
}

 

 

 

Tudo que sei é que funciona e acho que nem quero saber porquê 😜

(dica de shultz do asm51.com.br)

Deixei as estruturas e union pra efeito de comparação. Estas sim originais e explicáveis portanto 🙂

 

2 horas atrás, erpgc82 disse:

CCS é fantástico

Que bom pra você que gostou dele. Ele é algo como um arduino com funções mastigadas. Infelizmente nasci com c puro e não me dei bem com ele. Portanto não devo te acompanhar. Desejo-lhes boa sorte:hehehe:

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...

LANÇAMENTO!

eletronica2025-popup.jpg


CLIQUE AQUI E BAIXE AGORA MESMO!