sexta-feira, 21 de julho de 2017

Sistema de irrigação com pic 16F628

Olá, já algum tempo comprei umas válvulas para controlar um sistema de irrigação, dai coloquei três válvulas para decidir qual mangueira acionar (com pequenos pivôs(ou aspersores de irrigação)), o primeiro problema a ser resolvido era tentar umidecer ao máximo todo o jardim com esses aspersores, porém como eu não posso controlar a pressão da água que vem da rua, resolvi montar um circuito que   pudesse acionar fazendo combinações de modo a ter pelo menos 3 níveis de alcance(o alcance depende da pressão da água e esta depende do numero de micropivô).veja abaixo o esquemático do projeto,observe que terá um botão para ligar e outro para desligar(se necessário pois quando o programa for finalizado ele já desliga toda energia).

        Com a combinação consegui um resultado satisfatório; então depois de fazer toda a parte hidráulica era hora de colocar em pratica este circuito que montei, apesar de ter 2 reles para garantir que não existiria energia nos contatos das válvulas(para eliminar risco de choques quando o sistema não estiver acionado, ou caso um vazamento molhasse os contatos elétricos) resolvi separar a parte elétrica da hidráulica e acabei tendo que usar uma caixa de alarme(de uma sucata que eu tinha aqui em casa) para colocar todo o circuito, veja abaixo as fotos da placa e da montagem final:


Vamos agora ver como ficou o código fonte, ele é separado em 2 partes,o modo configuração usado pra gravar os tempos em que o sistema ficará em cada estagio(são 7)  e o modo de funcionamento onde rodará o programa uma vez e logo em seguida desliga tudo.Veja que será usado a comunicação serial pra configurar e guardar os dados na memoria.

O código fonte:

  /* projeto irrigador simples XC8
 *
 * Compilador : MPlabXC8
 * Microcontrolador: 16F628A
 * Autor: aguivone
 * Versão: 1
 * Data :  06 de julho de 2017
 * 
 * intruções:
 *  a programação deve ser feita usado #SXX* ; onde S=o ciclo que se quer alterar(1 a 7) e XX é um valor de 00 a 99
 *  note que a programação será por multiplos de 10s
 * 
 * 
 * mapa de endereços
 * posição de memoria - descrição.
 * 
 * 0 - posição de memoria rom que indica se houve gravação
 * 1 a 7 - relativo ao modo de funcionamento 1 a 7.
 * 
 */

#include <stdio.h>
#include <string.h> //para usar funçoes de string deve se adicionar este header
#include <stdlib.h>
#define _XTAL_FREQ 4000000    // vou usar o oscilador interno
#include <xc.h>

/////////////////////////////////////////////////////////configuraçôes//////////////////////////////////////////////////

//#pragma config FOSC = INTOSCIO  // Oscillator Selection bits (INTOSC oscillator: I/O function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN)
#pragma config FOSC = HS  ///se for de 20mhz deve ser HS
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = ON       // Power-up Timer Enable bit (PWRT enabled)
#pragma config MCLRE = OFF      // RA5/MCLR/VPP Pin Function Select bit (RA5/MCLR/VPP pin function is digital input, MCLR internally tied to VDD)
#pragma config BOREN = OFF      // Brown-out Detect Enable bit (BOD disabled)
#pragma config LVP = OFF        // Low-Voltage Programming Enable bit (RB4/PGM pin has digital I/O function, HV on MCLR must be used for programming)
#pragma config CPD = OFF        // Data EE Memory Code Protection bit (Data memory code protection off)
#pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)

#define BOT_CONFIG   RA4

#define RL_GERAL RB7

#define RL_1 RB4
#define RL_2 RB5
#define RL_3 RB6

#define LED_STATUS RB0


////////////////////////////////////////////////variaveis globais///////////////////////////////////////////////////////////
int modo=0;//modo de funcionamento
int tempo[7];//para guardar os tempos
int pos_prog=6;//posição inicial

//usadas na serial
char rs232[6];//guarda pacote recebido
char caracter;
int pos_serial=0;
bit flag_interrupcao = 0;

/////////////////////////////////funçoes usadas pela uart //////////////////////////////////////////////////////
//void inicializa_RS232(long velocidade,int modo)
void inicializa_RS232()
{////por padrão é usado o modo 8 bits e sem paridade, mas se necessario ajuste aqui a configuração desejada.
    //verifique datasheet para ver a porcentagem de erro e se a velocidade é possivel para o cristal utilizado.
    RCSTA = 0X90;//habilita porta serial,recepção de 8 bit em modo continuo,assincrono.  
    TXSTA = 0X24;//modo assincrono,trasmissao 8 bits./alta velocidade
    SPBRG = 25;//9600
    RCIE = 1;//habilita interrupção de recepção
    TXIE = 0;//deixa interrupção de transmissão desligado(pois corre se o risco de ter uma interrupção escrita e leitura ao mesmo tempo)
}
void escreve(char valor)
{
    TXIF = 0;//limpa flag que sinaliza envio completo.
    TXREG = valor;
    while(TRMT==0);//resolvi usar este flag em vez de TXIF
   // while(TXIF ==0);//espera enviar caracter//alterei para 1 para testar 18/07/17
   // __delay_us(20); 
}
void imprime(const char frase[])
{
     char indice = 0;
     char tamanho = strlen(frase);
      while(indice < tamanho ) ///veja que o programa pode travar se aqui não tiver as duas aspas
       {
           escreve(frase[indice]);
           indice++;
       }
}
void int_to_char(int quant)
{//converte para inteiro e imprime
     unsigned char ucDez='0', ucUn='0';
     while(quant>=10)
    {
      quant -= 10;  
      ucDez++;  
    }
    while(quant>=1)
    {
       quant -= 1; 
       ucUn++;  
    }
     escreve(ucDez);
     escreve(ucUn);
}
void delay_ms(long valor)//resolve um erro do conmpilador
{
    while(valor>0)
    {
     __delay_ms(1);   
     valor--;
    }        
}
void delay_seg(long valor)//rotina de 1s
{
    while(valor>0)
    {
     __delay_ms(1000); 
     //__delay_ms(100); //pra simular
     LED_STATUS = ~LED_STATUS;
     valor--;
    } 
    //para simular pode reduzir o tempo
}
void ler_dados()
{
    imprime(" \n\r tempos=");
    int var_auxi=0;
    while(var_auxi<7)
    {              
      tempo[var_auxi] = eeprom_read(var_auxi+1);
      int_to_char(tempo[var_auxi]); 
      escreve('0');
      escreve('|');
      var_auxi++;
    }
}


///////////////////////////////////////////////////interrupção//////////////////////////////////////////////////////////////
void interrupt RS232(void)//vetor de interrupção
 {
    if(RCIF)
    {//se pacote for de tamanho diferente ele descarta o pacote. formato #XXX*
     caracter = RCREG;
     if(flag_interrupcao == 0)
     {//verifica se está liberado para ler dados
     if(pos_serial>0)
     {               
            if(caracter == '*')
            {//pacote aceito
                if(pos_serial == 4)
                {
                 flag_interrupcao = 1;
                 rs232[pos_serial]=caracter; 
                 pos_serial = 0;//pra evitar que escreva antes de ler
                }
                else
                {//descarta pois é menor que o esperado
                    pos_serial = 10;//faz zerar tudo
                }
                 
            }
            else
            {
               rs232[pos_serial]=caracter; 
               pos_serial++;
            }            
        }
     if(pos_serial>4)
        {
            //erro no tamanho zera tudo
             rs232[0]='0';
             rs232[1]='0';
             rs232[2]='0';
             rs232[3]='0';
             rs232[4]='0';
             pos_serial = 0; 
        }
     if(caracter == '#')
     {
        pos_serial = 1;
        rs232[0]='#';
     }  
    }
     RCIF = 0;//  limpa flag de interrupção de recepção
    }    

 }


//////////////////////////////////////////////////////Rotina principal///////////////////////////////////////////////////////////////

void main(void)
{
    TRISB = 0X02;//configura portB como saida, B1 (pino RX) como entrada
    PORTB = 0;  // limpar as portas que estão configuradas como saidas
    TRISA = 0XFF;//configura portA   como entrada
    inicializa_RS232();//modo de alta velocidade
    PEIE = 1;//habilita interrupção de perifericos do pic
    GIE = 1; //GIE: Global Interrupt Enable bit
    __delay_ms(200);
    imprime("Sistema de irrigação V.1.0.0 \n\r"); 
    //pega valores da memoria
    if(eeprom_read(0) != 'G')
    {//nunca foi gravada, então coloca valor padrão
        eeprom_write(0X00,0);
        eeprom_write(0X01,1);//endereço/valor
        eeprom_write(0X02,1);
        eeprom_write(0X03,1);
        eeprom_write(0X04,1);
        eeprom_write(0X05,1);
        eeprom_write(0X06,1);
        eeprom_write(0X07,1);
    }
    ////leitura 
    modo=1;
    if(BOT_CONFIG == 0)
    {   delay_ms(1000);
        if(BOT_CONFIG == 0)
        {
         imprime("Modo configuração \n\r");        
         modo=0;
       // eeprom_write(0X00,'G');//indica que houve gravação na memoria
         LED_STATUS =1;
        }        
    } 
    if(modo == 1)
        {
          RCIE = 0;//desabilita interrupção de recepção
          TXIE = 0;//desabilita interrupção de transmissao 
          ler_dados(); 
          LED_STATUS =0;
        }
   
    
//////////////
    for(;;)
    {   
        if(modo==0)
        {
            if(flag_interrupcao ==  1)
            {//tem dados para ler
             LED_STATUS =0;
             escreve(rs232[0]);
             escreve(rs232[1]);
             escreve(rs232[2]);//retorna o valor lido
             escreve(rs232[3]);
             escreve(rs232[4]);
             //////processa dados/////
             if((rs232[2]>0X2F)&&(rs232[2]<0X40)&&(rs232[3]>0X2F)&&(rs232[3]<0X40))//indica que foi recebido um numero valido
             {//trata pacote                 
                 if((rs232[1]>0X30)&&(rs232[1]<0X38))//indica que foi recebido um modo valido(entre 1 e 7)
                 {//verifica se o modo de programação tem caracter valido
                    int valor = (((rs232[2] - 0X30)*10)+(rs232[3] - 0X30));//converte pra int
                    int posicao = (rs232[1] - 0X30);//converte pra int 
                    eeprom_write(posicao,valor);//altera o valor na de memoria;                    
                    imprime("\n\r Alterado:\n\r");
                    for(int i=1;i<8;i++)
                    {//imprime valores da memoria
                     int_to_char(eeprom_read(i));
                     escreve('|');
                    }
                    eeprom_write(0X00,'G');//indica que houve gravação na memoria;
                 }
             }
             pos_serial = 0; 
             flag_interrupcao = 0;//libera pra pegar outro pacote 
             LED_STATUS =1;
            }  
            
        }
        else
        {   //a sequencia foi pensada de forma que cada valvula tenha pelo menos 1 ciclo de descanso a cada 2 ciclos(execto se o tempo for zero para uma das posicoes)          
              switch(pos_prog)
              {
                  case 0:
                  { //fim de programa
                     RL_1=0;
                     RL_2=0;
                     RL_3=0;
                     delay_ms(500);
                     RL_GERAL=0;
                  }break;
                  case 1:
                  {
                     if(tempo[0]>0)
                     {
                        RL_1=1;
                        RL_2=0;
                        RL_3=0;
                     } 
                     pos_prog=3;//vai para proxima posição
                     delay_seg(tempo[0]*10);
                  }break;
                  case 2:
                  {
                     if(tempo[1]>0)
                     {
                        RL_1=0;
                        RL_2=1;
                        RL_3=0;
                     } 
                     pos_prog=7;//vai para proxima posição
                     delay_seg(tempo[1]*10);
                  }break;
                  case 3:
                  {
                     if(tempo[2]>0)
                     {
                        RL_1=1;
                        RL_2=1;
                        RL_3=0;
                     } 
                     pos_prog=4;//vai para proxima posição
                     delay_seg(tempo[2]*10);
                  }break;
                  case 4:
                  {
                     if(tempo[3]>0)
                     {
                        RL_1=0;
                        RL_2=0;
                        RL_3=1;
                     } 
                     pos_prog=5;//vai para proxima posição
                     delay_seg(tempo[3]*10);
                  }break;
                  case 5:
                  {
                     if(tempo[4]>0)
                     {
                        RL_1=1;
                        RL_2=0;
                        RL_3=1;
                     } 
                     pos_prog=2;//vai para proxima posição
                     delay_seg(tempo[4]*10);
                  }break;
                  case 6:
                  {//como o programa inicia aqui é preciso ter uma atenção diferente neste ponto
                     RL_GERAL=1; //rele principal, mantem a placa energizada 
                     if(tempo[5]>0)
                     {
                        RL_1=0;
                        RL_2=1;
                        RL_3=1;
                     }
                     else
                     {
                        RL_1=0;
                        RL_2=0;
                        RL_3=0;
                     } 
                     pos_prog=1;//vai para proxima posição
                     delay_seg(tempo[5]*10);
                  }break;                  
                  case 7:
                  {
                     if(tempo[6]>0)
                     {
                        RL_1=1;
                        RL_2=1;
                        RL_3=1;
                     } 
                     pos_prog=0;//vai para proxima posição
                     delay_seg(tempo[6]*10);
                  }break;
              }
        }             
     }//loop infinito 

}

O esquemático de simulação no proteus ficou:


O vídeo de demonstração :



Até a próxima pessoal!







sábado, 15 de julho de 2017

Reproduzindo som MP3 com auxilio do PIC.

             Olá quando pensamos em reproduzir sons MP3 imaginamos sempre um chip ou talvez algum microcontrolador que possua isso em seu hardware(mas são caros e de difícil aquisição, o que prejudica o uso em pequenos projetos), mas existe uma outra possibilidade, estou me referindo aos módulos DSPLAYERS que pode ser controlados por qualquer microcontrolador, bastando para isso ter acesso ao seu set de instruções.
             Veja na figura abaixo a aparência de um modulo DSPLAYER,já vem equipado com entrada USB, comunicação rs_232 para fazer a interface e saída de som analógica(alto falantes) + saídas para fone de ouvido. Neste site tem um exemplo de como usa-lo com arduino além de explorar melhor seus aspectos construtivos https://www.dfrobot.com/wiki/index.php/DFPlayer_Mini_SKU:DFR0299.


            Graças ao meu parceiro Renato que tem me enviado vários materiais para postar (pois como já disse anteriormente em outros "post", estou tendo dificuldade para desenvolver novos projetos), este projeto conta com os recursos principais para fazer funcionar o modulo usando um microcontrolador PIC.Agradeço muito nosso colaborador por compartilhar conosco sua experiencia com este módulo.Ele ainda me deixou uma dica "Se alguém se interessar posso produzir o circuito impresso, só entrar em contato: -> Renato : lobosoft@oi.com.br".

A aparência do protótipo pronto ficou assim:



O código fonte:

 Programa principal: Código para compilação no CCS.

////////////////////////////////////////////////////////////////////////////////
//              Projeto: Aparelho de som com modulo DFPlayer Mini             //
//                 Nome: Renato Lôbo Rodrigues                                //
//                 Data: 12/07/17                                             //
//                Email: lobosoft@oi.com.br                                   //
////////////////////////////////////////////////////////////////////////////////

#include "config_pic675.h"

void main()
{
   int1 st1=false, st2 = false, st3=false, st4 = false, play = true, di = false;
   int8 equ = 1,disp = 1;
   tris_bot1 = 1;
   tris_bot2 = 1;
   tris_bot3 = 1;
   tris_bot4 = 1;
   tris_bot5 = 1;
   GPPU      = 0;
   delay_ms(2000);
   Uart_SendCMD(0x06 , 0 , 0x16 ) ;  //volume inicial
   delay_ms(200);
   sorteia();
   delay_ms(200);
   Tocar();   
   delay_ms(200);          
   Proxima_trilha();
   delay_ms(500);
 
   while(true)
   {
      if( bot1) st1 =false;         //Equalizador
      delay_ms(50);
      if(!bot1 && !st1)
      {
         st1 = true;
         equ++;
         if(equ>5)equ=1;
         if(equ==1)equaliza(1);
         if(equ==2)equaliza(2);
         if(equ==3)equaliza(3);
         if(equ==4)equaliza(4);
         if(equ==5)equaliza(5);
         delay_ms(1000);
      }
      if( bot2) st2 =false;         //troca o dispositivo: Memoria/Pendrive
      delay_ms(50);
      if(!bot2 && !st2)
      {
         st2 = false;
         di=~di;
         if(di) disp=2; else disp=1;
         dispositivo(disp);
         delay_ms(500);
      } 
 
      if(!bot3) st3 =false;         //toca tudo altomaticamente
      delay_ms(50);
      if( bot3 && !st3  && play)
      {
         st3 = true;
         Proxima_trilha();
         delay_ms(200);
      }

      if( bot4) st4 =false;         //tocar/pausa
      delay_ms(50);
      if(!bot4 && !st4)
      {
         st4 = true;
         play = ~play;
         if (play)Tocar();else Pausa();
         delay_ms(500);
      }         
   }
}

Configuração do PIC 12F675

////////////////////////////////////////////////////////////////////////////////
//              Projeto: configuração de cabeçalho de projeto com pic12F675   //
//                 Nome: Renato Lôbo Rodrigues                                //
//                 Data: 12/07/17                                             //
//                Email: lobosoft@oi.com.br                                   //
////////////////////////////////////////////////////////////////////////////////
#include "12F675.h"
#use delay(clock=4Mhz)
#include "DFPlayer.h"
//=======================================================================
//Configurando fusiveis
//=======================================================================
#fuses NOWDT
#fuses PUT
#fuses NOBROWNOUT
#fuses NOMCLR
#fuses INTRC_IO
#fuses PROTECT
//=======================================================================
//Configurando I/O de direção dos pinos
//=======================================================================
#bit  bot1        = 0x05.0
#bit  bot2        = 0x05.2
#bit  bot3        = 0x05.3
#bit  bot4        = 0x05.4
#bit  bot5        = 0x05.5

#bit  tris_bot1   = 0x85.0
#bit  tris_bot2   = 0x85.2
#bit  tris_bot3   = 0x85.3
#bit  tris_bot4   = 0x85.4
#bit  tris_bot5   = 0x85.5

#bit  GPPU        = 0x81.7


Biblioteca do DSPlayer Mini

////////////////////////////////////////////////////////////////////////////////
//              Projeto: Biblioteca para acessar o DFPlayer Mini              //
//                 Nome: Renato Lôbo Rodrigues                                //
//                 Data: 12/07/17                                             //
//                Email: lobosoft@oi.com.br                                   //
////////////////////////////////////////////////////////////////////////////////


#use rs232(baud=9600,xmit=PIN_A1,rcv=PIN_A2, ERRORS)

static unsigned INT8 Send_buf[10] = {0} ;


void SendCmd(unsigned INT8 leng)
{
INT8 i = 0 ;
putc(0x7E);
for(i=0; i<leng; i++)//dados
{
putc(Send_buf[i]);
}
putc(0xEF);
}

void DoSum( unsigned INT8 *Str, unsigned INT8 len)
{
   unsigned INT16 xorsum = 0;
   unsigned INT8 i;
   for(i=0; i<len; i++)
   {
      xorsum = xorsum + Str[i];
   }
   xorsum = 0 -xorsum;
   *(Str+i) = (unsigned INT8)(xorsum >>8);
   *(Str+i+1) = (unsigned INT8)(xorsum & 0x00FF);
}
void Uart_SendCMD(unsigned INT8 CMD ,unsigned INT8 feedback , unsigned INT16 dat)
{
   Send_buf[0] = 0xFF;                       //bytes reservados
   Send_buf[1] = 0x06;                       //comprimento
   Send_buf[2] = CMD;                        //instruções de controle
   Send_buf[3] = feedback;                   //A necessidade de feedback
   Send_buf[5] = (unsigned INT8)(dat);       //datal
   Send_buf[4] = (unsigned INT8)(dat >> 8);  //datah
   DoSum(&Send_buf[0],6);                    //Verifique
   SendCmd(8);                               //Esta transmissão da trama de dados
}

void Arquivo_musica(int8 pasta,int8 numero)
{
   int16 pasta_numero;
   pasta_numero = (pasta * 256) | numero ;
   Uart_SendCMD(15 , 0, pasta_numero);
}

void Proxima_trilha()
{
   Uart_SendCMD(1 , 0, 0);
}

void Trilha_anterior()
{
   Uart_SendCMD(2 , 0, 0);
}

void Diminuir_volume()
{
   Uart_SendCMD(5 , 0, 0);
}

void Aumentar_volume()
{
   Uart_SendCMD(4 , 0, 0);
}

void Volume(int8 vol)
{
   Uart_SendCMD(6 , 0, vol);
}

void Equaliza(int8 equa)
{
   Uart_SendCMD(7 , 0, equa);
}

Void Pausa()
{
   Uart_SendCMD(14 , 0, 0);
}

Void Tocar()
{
   Uart_SendCMD(13 , 0, 0);
}

void dispositivo(int8 disp)
{
   Uart_SendCMD(9 , 0, disp);
}
void sorteia()
{
   Uart_SendCMD(24 , 0, 3);
}
void sequencia()
{
   Uart_SendCMD(24 , 0, 1);
}

Até a próxima pessoal.


sábado, 1 de julho de 2017

Motor de passo Bipolar - no CCS



Olá pessoal que acompanha o blog, hoje temos mais uma postagem do senhor Renato Lôbo Rodrigues,e neste exemplo será demonstrado como acionar um motor de passo por fase.

lista de peças para montagem em bancada:


- matriz de contatos pequena
- pic12F675, microcontrolador da Microchip
- 2 resistor de 10k para pull-up dos botões
- 2 botões de pressão
- 1 capacitor de acoplamento 104
- cabinhos para ligações dos componentes
- fonte de 5V 2A.
- Uma ponte H L298
- Motor de passo pequeno de 1A por fase

O código fonte:


///////////////////////////////////////////////////////////////////////
//              Projeto: Motor de passo Bipolar                      //
//                 Nome: Renato Lôbo Rodrigues                       //
//                 Data: 28/06/17                                    //
//                Email: lobosoft@oi.com.br                          //
///////////////////////////////////////////////////////////////////////

#include <12F675.h>        // inclusão do pic em questão
#OCS 4 MHz                 // oscilador 4.000.000 herts
#use fast_io(A)            // O método rápido de fazer E/S

//Configura os fusiveis
#fuses NOWDT
#fuses PUT
#fuses NOBROWNOUT
#fuses NOMCLR
#fuses INTRC_IO
#fuses PROTECT
//=======================================================================
//Definições de variaveis globais
//=======================================================================

#bit pulso = 0x05.2        //define pino A2 para pulso do motor
#bit dir   = 0x05.3        //define pino A3 para direção de rotação


#bit A     = 0x05.0        // define pino A0 para motor terminal A
#bit B     = 0x05.1        // define pino A1 para motor terminal B
#bit C     = 0x05.4        // define pino A2 para motor terminal C
#bit D     = 0x05.5        // define pino A3 para motor terminal D

#byte tris_portA = 0x85    // direção dos pinos do portA

int8 i = 0;              // variável i(indice) do tipo inteiro 8 bits 

//=======================================================================

void motor()               //função para girar o motor de passo Bipolar
{
   if (i<1) i=4;           //se i é menor que 1 então i = 4
   if (i>4) i=1;           //se i é maior que 4 então 1 = 1
   switch(i)               
   {
      case 1:A=1;B=0;C=0;D=1; break;    //1001
      case 2:A=0;B=1;C=0;D=1; break;    //0101
      case 3:A=0;B=1;C=1;D=0; break;    //0110
      case 4:A=1;B=0;C=1;D=0; break;    //1010
   }
}

void main()//Rotina principal do programa
{
   tris_portA = 0b00001100; //pinos A2 e A3 como entrada e o restante como saida
   While(true)              //loop infinito
   {
      if(!pulso)                 //se pulso é verdadeiro
      {
         if(dir) i++; else i--;  //igual a um: roda num sentido senão no outro sentido
         motor();                //vai para função motor()
         delay_us(800);          //800 microsegundos / simulação: 80 milesegundos
      }
   }
}//Fim de programa

A simulação:

Vídeo com o protótipo funcionando:





domingo, 18 de junho de 2017

Estrobo duplo alternado para estacionamento - CCS


Olá, hoje temos uma postagem do senhor Renato "Estrobo duplo alternado para estacionamento".
lista de peças para montagem em bancada:

- matriz de contatos pequena
- pic16F628A, microcontrolador da Microchip
- 2 resistor de 220 ohm para limitar a corrente do LED
- 2 LED de 3 ou 5 mm vermelho
- cabinhos para ligações dos componentes
- fonte de 5V, pode ser um carregador de celular ou suporte de 3 pilhas(4,5V)

O código fonte:
///////////////////////////////////////////////////////////////////////
//              Projeto: Estrobo duplo alternado para estacionamento //
//                 Nome: Renato Lôbo Rodrigues                       //
//                 Data: 12/03/17                                    //
//                Email: lobosoft@oi.com.br                          //
///////////////////////////////////////////////////////////////////////
#include <16F628A.h>
#use delay (clock = 4Mhz)
//Configure os fusíveis em acordo com o pic selecionado
#fuses NOWDT
#fuses PUT
#fuses NOBROWNOUT
#fuses NOMCLR
#fuses INTRC_IO
#fuses PROTECT

//Estes registros encontra-se nas funções especiais de cada modelo de pic.

#byte tris_portA = 0x85   //direção do portA
#bit led1        = 0x05.0 //pino A0
#bit led2        = 0x05.1 //pino A1

int1 flag=false;
//___________________________________________
void estrobo()
{
   int8 f;              //variável do laço for
   flag=!flag;          //inverte a variável flag
   if(flag){            //se flag é verdadeiro
      for(f=0;f<10;f++) //laço de contagem de 0 até 9
      {
         led1 = !led1 ; //Acende ou apaga o led1
         delay_ms(30);  //tempo de 30 milisegundos
      }
   }else{               //caso flag seja falso
      for(f=0;f<10;f++) //laço de contagem de 0 até 9
      {
         led2 = !led2 ; //Acende ou apaga o led1
         delay_ms(30);
      }
   }
}

//Rotina principal
void main()
{
   int16 conta=0;             //cria uma variável conta igual a zero
   tris_portA = 0b11111100;   //pino A0 e A1 como saída
   led1 = 0;                  //apaga o led1
   led2 = 0;                  //apaga o led2   

   while(true)                //laço infinito
   {
      conta++;                //inrementa conta
      if(conta>=25000)        // se conta é maior ou igual a 25000
      {
         conta=0;estrobo();   //zera a contagem e chama rotina de estrobo
      }//fim do if
   }//fim do while
} //fim do main

Vídeo de demonstração:

https://drive.google.com/file/d/0B9fK-FRZeeWNQWNsSXRzZmdMTVE/view?usp=sharing

quinta-feira, 1 de junho de 2017

Selecionando LED na sequência usando um botão - CCS

Selecionando LED na sequência usando um botão


lista de peças para montagem em bancada:

- matriz de contatos pequena
- pic16F628A, microcontrolador da Microchip
- 4 resistor de 220 ohm para limitar a corrente do LED
- 4 LED de 3 ou 5 mm vermelho
- Botão de contato
- cabinhos para ligações dos componentes
- fonte de 5V, pode ser um carregador de celular ou suporte de 3 pilhas(4,5V)

O código fonte:

///////////////////////////////////////////////////////////////////////
//              Projeto: Selecionar LED na sequência usando um botão //
//                 Nome: Renato Lôbo Rodrigues                       //
//                 Data: 18/05/17                                    //
//                Email: lobosoft@oi.com.br                          //
///////////////////////////////////////////////////////////////////////
#include <16F628A.h>
#use delay (clock = 4Mhz)
//Configure os fusíveis em acordo com o pic selecionado
#fuses NOWDT
#fuses PUT
#fuses NOBROWNOUT
#fuses NOMCLR
#fuses INTRC_IO
#fuses PROTECT

//Estes registros encontra-se nas funções especiais de cada modelo de pic.
#byte tris_portA = 0x85   //direção do portA
#byte tris_portB = 0x86   //direção do portB
#bit bot1        = 0x06.3 //pino B3

#bit RBPU        = 0x81.7 //Registro pullup do portB 

#bit led1        = 0x05.0 //pino A0
#bit led2        = 0x05.1 //pino A1
#bit led3        = 0x05.2 //pino A2
#bit led4        = 0x05.3 //pino A3

//___________________________________________
//Rotina principal
void main()
{
   int1 st1 = true;  //status do botão
   int8 ponteiro = 0;//seleciona um LED de cada vez
   
   tris_portB = 0b11111111; //todos os pinos como entrada
   RBPU = 0;                //pull-up portB ativados
   
   tris_portA = 0b11110000; //pino A0,A1,A2,A3 como saída
   led1 = 1;         //liga led1
   led2 = 0;         //desliga led2   
   led3 = 0;         //desliga led3   
   led4 = 0;         //desliga led4   
   
   while(true)       //laço infinito
   {
      //funciona quando solta o botão (KeyUp)
      if (!bot1)   st1=false;
      delay_ms(50);           //um tempo para anular repique da chave
      if ( bot1 && st1==false)
      {
           st1=true;
           ponteiro++;
           if(ponteiro>3)ponteiro=0;
           led1 = 0 ;led2 = 0 ;led3 = 0 ;led4 = 0 ; //Apaga todos os LEDs
           switch (ponteiro)
           {
            case 0:led1 = 1 ; //Acende o led1
                  break;
            case 1:led2 = 1 ; //Acende o led2
                  break;
            case 2:led3 = 1 ; //Acende o led3
                  break;
            case 3:led4 = 1 ; //Acende o led4
                  break;
           }
           delay_ms(200); //um tempo para anular repique da chave
      }//fim do if
   }//fim do while
} //fim do main

quinta-feira, 11 de maio de 2017

Usando timer 0 com o CSS (por: Renato Lôbo Rodrigues)

           Olá pessoal que acompanha o blog, temos mais uma postagem do senhor Renato Lôbo,um programa escrito em C para compilador CCS, que faz piscar um LED usando o timer0 configurado pelos registradores, usando como referência o datasheet do PIC6F628A da Microchip.
http://ww1.microchip.com/downloads/en/DeviceDoc/40044G.pdf

lista de peças para montagem em bancada:
- matriz de contatos pequena
- pic16F628A, microcontrolador da Microchip
- resistor de 220 ohm para limitar a corrente do LED
- LED 3 ou 5 mm vermelho
- cabinhos para ligações dos componentes
- fonte de 5V, pode ser um carregador de celular ou suporte de 3 pilhas(4,5V)
A simulação:




foto do projeto:


O código fonte :

///////////////////////////////////////////////////////////////////////
//              Projeto: pisca-pisca usando timer0                   //
//                 Nome: Renato Lôbo Rodrigues                       //
//                 Data: 11/05/17                                    //
//                Email: lobosoft@oi.com.br                          //
///////////////////////////////////////////////////////////////////////
#include <16F628A.h>
#use delay (clock = 4Mhz)
//Configure os fusíveis em acordo com o pic selecionado
#fuses NOWDT
#fuses PUT
#fuses NOBROWNOUT
#fuses NOMCLR
#fuses INTRC_IO
#fuses PROTECT

#byte tris_portA = 0x85 //direção dos pinos do portA
#byte tris_portB = 0x86 //direção dos pinos do portB

#bit led1      = 0x05.0 //pino A0

//##############################################################################
#bit GIE           = 0x0b.7 //interrupção blobal
#bit TOIE          = 0x0b.5 //interrupção timer0
#bit TMR1ON        = 0x10.0 //interrupção timer1
#bit TMR2ON        = 0x12.2 //interrupção timer2

#byte tmr0         = 0x01   //preload do timer0

#byte OPTION_REG = 0x81    //registro no endereço 0x81 do banco1

//___________________________________________
//Rotina de interrupção do timer0
#int_rtcc
void rotina_t0()
{
   static int8 conta;
   conta++;               // conta 125 vezes o tempo do timer0(4ms) para completar 500 miliseguundos
   if (conta==125)      //125*4ms = 500ms => ciclo de 1 segundo
   {
      led1=~led1;       //inverte a saída ligando ou desligando o LED.
      conta = 0;
   }
   tmr0 = 6;            //inicia a contagem em 6 e vai até 256(onde estoura)
}
//___________________________________________
//Rotina principal
void main()
{
   //pinos configurado como entrada por segurança  (alta impedância)
   tris_portA = 0b11111110; //todos os pinos do portA como entrada exceto pino A0 como saída
   tris_portB = 0b11111111; //todos os pinos do portB como entrada
   
   led1 = 1;       //Acende o led1

   //registro configurado para 4 milisegundos(veja pagina 25 do datasheet)
   OPTION_REG = 0b10000011;//1   = pull-up desabilitado
                           //0000= deixe tudo zero como padrão
                           //011 =prescaler dividido por 16

   tmr0 = 6;                        //preload do timer0 para 4ms
   GIE = 1;                         //interrupção global ativa
   TOIE = 1;                        //interrupção timer0 ativa
   TMR1ON = 0;                      //desabilita timer1
   TMR2ON = 0;                      //desabilita timer2
  

   while(true)     //laço infinito
   {
     
   }
}

sexta-feira, 5 de maio de 2017

Acionando led pelo CCS (por:Renato Lôbo Rodrigues).


Olá pessoal que acompanha o blog, está é uma contribuição do nosso colega Renato Lôbo Rodrigues e ele deixou o seguinte programa no qual liga e desliga um LED através de um botão.
Programa indicado para iniciantes e quem mais se interessar pelo método de programação no CCS, sem usar  funções próprias do CCS.Há recursos onde o datasheet deve ser consultado para eventuais dúvidas dos registradores usados.


O código fonte:
 
lista de peças para montagem em bancada:
- matriz de contatos pequena
- pic16F628A, microcontrolador da Microchip
- resitor de 220 ohm para limitar a corrente do LED
- resitor de 10k ohm como pu-up da entrada do pino RA3
- LED 3 ou 5 mm vermelho
- botão de contato
- cabinhos para ligações dos componentes
- fonte de 5V, pode ser um carregador de celular ou suporte de 3 pilhas(4,5V)

///////////////////////////////////////////////////////////////////////
// Projeto: Ligar e desligar um led através de um botão //
// Nome: Renato Lôbo Rodrigues //
// Data: 10/03/17 //
// Email: lobosoft@oi.com.br //
///////////////////////////////////////////////////////////////////////
#include <16F628A.h>
#use delay (clock = 4Mhz)
//Configure os fusíveis em acordo com o pic selecionado, consultar o arquivo <16F628.h> e datasheet.
#fuses NOWDT
#fuses PUT
#fuses NOBROWNOUT
#fuses NOMCLR
#fuses INTRC_IO
#fuses PROTECT
//Estes registros encontra-se nas funções especiais de cada modelo de pic, 
//pag 16 do datashet no mapa de memória.
#bit tris_bot1 = 0x85.3 //direção do pino A3
#bit bot1 = 0x05.3 //pino A3
#bit tris_led1 = 0x85.0 //direção do pino A0
#bit led1 = 0x05.0 //pino A0
//___________________________________________
//Rotina principal
void main()
{
int1 st1 = false; //status do botão
tris_bot1 = 1; //pino A3 em "um" como entrada
tris_led1 = 0; //pino A0 em "zero" como saída
led1 = 0; //inicia com "zero" apagando o led1
while(true) //laço infinito
{
//funciona quando aperta o botão (KeyDown)
if ( bot1) st1=false;    //
if (!bot1 && st1==false)
{
st1=true;
led1 = !led1 ; //inverte, acende ou apaga o led1
delay_ms(100); //um tempo para deboulce
}//fim do if
}//fim do while
} //fim do main

Muito obrigado Renato Lôbo Rodrigues por contribuir com o blog!

quinta-feira, 16 de março de 2017

Acessando a memoria EEprom do chip ESP8266

Olá, neste exemplo vou demostrar como escrever na memória do ESP8266, para isto usei o  mesmo exemplo do ultimo post, somente adaptei uma função que irá escrever e depois ler o que foi escrito na memória rom do chip.
         Veja que a forma de colocar dados na memoria é por identificadores e não por posição de memoria como é feito nos microcontroladores.As informações serão retornadas pela porta serial(rs-232) do chip.

O código fonte:
#include <ESP8266WiFi.h>
#include "FS.h"
const int  LED_STATUS = 2; // led de status 
const int  ANALOGICA = A0; // porta analogica

///emulando uma porta SPI generica - aqui se configura quais pinos se quer usar ////////////////
const int  SPI_CLK = 14; //ligue no sinal de clock
const int  SPI_IN  = 13; //ligue no Mosi 
const int  SPI_OUT = 12; //ligue no Miso
const int  SPI_CS  = 16; //ligue no chip select 


//***********************************************************************************************************
// Registradores do chip DS3234 - endereço de leitura,para escrever basta somar 0X80 ao valor hexadecimal
//***********************************************************************************************************
#define DS3234_SEG               0X00 // registrador de segundos
#define DS3234_MIN               0X01 // registrador de minutos
#define DS3234_HORA              0X02 // registrador de horas
#define DS3234_DIA_SEMANA        0X03 // registrador de dia da semana
#define DS3234_DIA               0X04 // registrador de dia
#define DS3234_MES               0X05 // registrador de Mes
#define DS3234_ANO               0X06 // registrador de ano

#define DS3234_ALM1_SEG          0X07 // registrador Alarme 1 de segundos
#define DS3234_ALM1_MIN          0X08 // registrador Alarme 1 de minutos
#define DS3234_ALM1_HORA         0X09 // registrador Alarme 1 de horas
#define DS3234_ALM1_DIA_SEMANA   0X0A // registrador Alarme 1 de dia e dia da semana

#define DS3234_ALM2_MIN          0X0B // registrador Alarme 2 de minutos
#define DS3234_ALM2_HORA         0X0C // registrador Alarme 2 de horas
#define DS3234_ALM2_DIA_SEMANA   0X0D // registrador Alarme 2 de dia e dia da semana

#define DS3234_CONTROLE          0X0E // registrador de controle(config)
#define DS3234_STAT_CONTROLE     0X0F // registrador de controle e status
#define DS3234_CONF_CRISTAL      0X10 // registrador do cristal interno

#define DS3234_TEMP_H            0X11 // registrador do sensor de temperatura parte alta(msb)) 
#define DS3234_TEMP_L            0X12 // registrador do sensor de temperatura parte baixa(lsb)

#define DS3234_S_RAM             0X18 // registrador da memoria S_RAM
#define DS3234_S_RAM_DADOS       0X18 // registrador da memoria S_RAM dados


void setup() {
  Serial.begin(115200);
  conf_pinos();  
  inicializa_spi();
  inicializa_DS3234(); 
  ler_memo_rom();
}
void loop() {
  digitalWrite(LED_STATUS,HIGH);
  Serial.print("DATA:");
  Serial.print(DS3234_ler_spi(DS3234_DIA), HEX);
  Serial.print("/"); 
  Serial.print(DS3234_ler_spi(DS3234_MES), HEX);
  Serial.print("/");
  Serial.print(DS3234_ler_spi(DS3234_ANO), HEX);
  Serial.print(" -> ");
  Serial.print(DS3234_ler_spi(DS3234_HORA), HEX);
  Serial.print(":");
  Serial.print(DS3234_ler_spi(DS3234_MIN), HEX);
  Serial.print(":");
  Serial.println(DS3234_ler_spi(DS3234_SEG), HEX);
  delay(300);//1s
  digitalWrite(LED_STATUS,LOW);
  delay(300);//1s
}
/*
 * Funções usadas no laço principal
 * eu poderia ter montado uma lib - mas a ideia é compartilhar como se faz 
 * uma comunicação spi com o DS3234 que sirva em qualquer dispositivo.
 */
  ////////////////////////////////////////////////////////////////////
//configura os pinos
////////////////////////////////////////////////////////////////////
void conf_pinos()
{  
  pinMode(9, INPUT);//sempre será entrada
  pinMode(LED_STATUS, OUTPUT);
  digitalWrite(LED_STATUS, LOW);  
   return;
}
 ////////////////////////////////////////////////////////////////////
//lendo a memoria rom do ESP8266
////////////////////////////////////////////////////////////////////
void ler_memo_rom()
{  
  bool result = SPIFFS.begin();
  Serial.println("abrindo SPIFFS : " + result);  
  File f = SPIFFS.open("/f.alame1", "r");  
  if (!f) {  // tenta abrir o arquivo com nome "f.alame1"  
    Serial.println("Arquivo não existe");
    // abre o arquivo em modo escrita
    File f = SPIFFS.open("/f.alame1", "w");//cria ao arquivo 
          if (!f) 
            {
            Serial.println("não foi possivel cria o arquivo!");
            }
    // escreve 2 linhas já colocando o caracter de fim de linha
    f.println("hora=12");
    f.println("minutos=00");
  }
  else 
  {//o arquivo já existe
    Serial.println("Dados da memoria :");
    while(f.available()) //enquanto tiver dados ele lê
    {//cria string para ler um linha a linha do arquivo
      String line = f.readStringUntil('\n');
      Serial.println(line);
    }

  }
  f.close();
}
 ////////////////////////////////////////////////////////////////////
//cria estado padrão dos pinos spi
////////////////////////////////////////////////////////////////////
void inicializa_spi()
{ 
  pinMode(SPI_CLK, OUTPUT);
  digitalWrite(SPI_CLK, HIGH);
  pinMode(SPI_IN, INPUT);
  pinMode(SPI_OUT, OUTPUT);
  digitalWrite(SPI_OUT, LOW);
  pinMode(SPI_CS, OUTPUT);
  digitalWrite(SPI_CS,HIGH);
  return;
}
////////////////////////////////////////////////////////////////////
//inicializa o chip
////////////////////////////////////////////////////////////////////
void inicializa_DS3234()
{
    DS3234_escr_spi(DS3234_CONTROLE,0X80);//80= desliga saida do oscilador , SQ wave @1hz, Alarme desabilitados
    DS3234_escr_spi(DS3234_ANO,0X17);//configura data para 25/08/2017 - 15:05
    DS3234_escr_spi(DS3234_MES,0X02);//colocar os valores sempre em hexadecimal
    DS3234_escr_spi(DS3234_DIA,0X25);
    DS3234_escr_spi(DS3234_HORA,0X15);
    DS3234_escr_spi(DS3234_MIN,0X05);
    return;
}
////////////////////////////////////////////////////////////////////
//essa rotina serve tanto para escrever quanto para ler 
////////////////////////////////////////////////////////////////////
int DS3234_ler_spi_byte(int valor,int liga_cs)
{//já escreve e já lê
  int dados = 0;
  int pos=128;
  digitalWrite(SPI_CS, LOW);
  delayMicroseconds(1); 
  while(pos>0)///bit mais significativo primeiro
  {
      if((valor&pos)>0)//faz uma operaçao and e checa se é 1
        {digitalWrite(SPI_OUT,HIGH);}
      else
        {digitalWrite(SPI_OUT,LOW);}
        digitalWrite(SPI_CLK,LOW);
        delayMicroseconds(1); ///tempo em nivel baixo do clock
        if(digitalRead(SPI_IN)==HIGH)
        {dados = dados|pos;}      
        digitalWrite(SPI_CLK,HIGH);
        delayMicroseconds(1); ///tempo em nivel baixo do clock//tempo em nivel alto do clock
    pos=pos/2;//rotaciona 1 bit
  }
  if(liga_cs == 1)
  {digitalWrite(SPI_CS, HIGH);}
   return(dados);
}
////////////////////////////////////////////////////////////////////
//essa rotina lê um byte do registrador colocado em endereço
////////////////////////////////////////////////////////////////////
int DS3234_ler_spi(int endereco)
{
  int dados;
  DS3234_ler_spi_byte(endereco,0);
  dados = DS3234_ler_spi_byte(0X00,1);//não envia nada somente para pegar os dados
  return(dados);
}
////////////////////////////////////////////////////////////////////
//essa rotina escreve um byte no registrador  em endereço
////////////////////////////////////////////////////////////////////
void DS3234_escr_spi(int endereco,int dados)
{
  endereco = endereco|0X80;//pronto pra escrever
  DS3234_ler_spi_byte(endereco,0);
  DS3234_ler_spi_byte(dados,1);  
}

Até a próxima pessoal!

quarta-feira, 22 de fevereiro de 2017

Cuidados que se deve ter com o ESP8266 12E gravado pela interface Arduíno.

       Olá, hoje vou trazer umas dicas para quem quer se aventurar pelo mundo do ESP8266 12E gravando diretamente pela interface Arduíno.O chip que estou usando é este da foto abaixo:

      além das adaptações físicas para fazer a interface com um PC é preciso cuidado ao usar alguns pinos como I/O(GPIO) pela interface Arduíno, pessoal pode crer essas dicas aqui poderão poupar tempo e evitar dores de cabeça, vamos então as dicas:
-> Usando as portas como saídas.
* Os GPIO'S  4,5,10,12,13,14,16 = funcionam sem restrição
* O GPIO 9 não funciona se colocar ele como saída o chip pode nem funcionar(fica resetado!).
* O GPIO 2 funciona, mas está ligado ao led da placa.dependendo do projeto deve ser colocado um resistor de pull_up para que seja possível uma gravação posterior pela serial rs232 (pois os pinos de GPIO'S  15,0,2 que configuram como deve ser a gravação).
* O GPIO 15 funciona, porém deve ser colocado um resitor de pull down de forma que uma gravação posterior pela serial seja possível(pois os GPIO'S 15,0,2 configuram como deve ser a gravação).
* O GPIO 0 funciona, porém no nodemcu a placa pode ficar travada se ele for ligado a base de um transistor(uso comum pra acionar reles) - cautela ao usar este pino.

-> Usando as portas como Entradas:
* Os GPIO'S  0,2,4,5,10,12,13,14,15,16 funcionam, apenas o GPIO 9 não deve ser usado pois reseta o chip quando entra em nível baixo.O pino 2 apesar de funciona está ligado ao led.
* Os cuidados para os pinos de configuração(os GPIO'S  15,0,2) devem ser observado caso queira programa o chip posteriormente, conforme já mencionado quando tratamos do uso das portas como saídas.
* a porta analógica funcionou perfeitamente.
->  As comunicações:
* A comunicação serial RS232 funcionou bem com as lib's do arduino.
* Usando os pinos que já vem no chip e que teoricamente é preparado para comunicação SPI não deu certo com as lib's nativas do Arduino (não sei o por que?)foi preciso emular uma SPI para que comunicasse com outros chips SPI.(veja um exemplo clicando aqui )
*A comunicação WIFI funciona bem, sendo muito estável,porém a senha da wifi deve ser obrigatoriamente maior que 8 caracteres ou em branco(aberta), caso contrario não troca o nome da wifi e nem aceita a senha(dá erro).

Um exemplo simples, para mostrar como o pino 9 pode "empacar" seu desenvolvimento é mostrado na imagem a seguir. Este simples código roda perfeitamente mas basta tirar as barras de  comentário para perceber que  seu programa ficara travado e não faz nada! o pior é que o software do Arduíno nem te alerta para este problema.
Espero ter ajudado alguém com essas dicas.
deixe seu comentário abaixo ou no Facebook.
Até a próxima!

terça-feira, 14 de fevereiro de 2017

Usando o RTC DS3234 com o ESP8266 pela interface do Arduino.

           Olá, hoje vou demonstrar como comunicar com o RTC DS3234 e o modulo ESP8266(gravado pela IDE arduino) com uma SPI emulada,pois a lib do Arduíno não deu certo com este modulo, tentei de varias formas usar a lib do Arduino e não deu certo, até que em um dos blogs e sites que pesquisei(chegou a afirmar) que os pinos de SPI que vem no moduloESP8266 só servem para gravação do chip(achei isso estranho), mas como não estava dando certo a comunicação e já havia passado horas de tentativa resolvi implementar uma comunicação SPI na "unha", como esse tipo de comunicação é relativamente simples aceitei o desafio de fazê-lo funcionar assim.Uma vantagem disso é que vc fica livre pra escolher os pinos que quiser, podendo inclusive usar esta ideia para microcontroladores que não possui uma SPI. Veja como ficou as conexões entre os dois chips:
           Uma das vantagens de usar este RTC é que não precisa de nenhum hardware adicional, assim como o ESP8266,basicamente  só é necessário esses 2 chips,mas dai ainda coloquei um led para piscar, só mesmo pra saber que o programa está rodando.
           O ESP8266 irá inicialmente setar uma data qualquer no chip e depois ira ler qual a data e a hora que está no chip a cada 2s, imprimindo na porta serial RS232 e usando um conversor usb serial isso chega ao PC.O programa que usei no pc foi este, mas pode ser usado qualquer outro terminal serial inclusive o do Arduíno.

O código fonte:

#include <ESP8266WiFi.h>

const int  LED_STATUS = 5; // led de status 
///emulando uma porta SPI generica - aqui se configura quais pinos se quer usar ////////////////
const int  SPI_CLK = 14; //ligue no sinal de clock
const int  SPI_IN  = 13; //ligue no Mosi 
const int  SPI_OUT = 12; //ligue no Miso
const int  SPI_CS  = 16; //ligue no chip select 


//***********************************************************************************************************
// Registradores do chip DS3234 - endereço de leitura,para escrever basta somar 0X80 ao valor hexadecimal
//***********************************************************************************************************
#define DS3234_SEG               0X00 // registrador de segundos
#define DS3234_MIN               0X01 // registrador de minutos
#define DS3234_HORA              0X02 // registrador de horas
#define DS3234_DIA_SEMANA        0X03 // registrador de dia da semana
#define DS3234_DIA               0X04 // registrador de dia
#define DS3234_MES               0X05 // registrador de Mes
#define DS3234_ANO               0X06 // registrador de ano

#define DS3234_ALM1_SEG          0X07 // registrador Alarme 1 de segundos
#define DS3234_ALM1_MIN          0X08 // registrador Alarme 1 de minutos
#define DS3234_ALM1_HORA         0X09 // registrador Alarme 1 de horas
#define DS3234_ALM1_DIA_SEMANA   0X0A // registrador Alarme 1 de dia e dia da semana

#define DS3234_ALM2_MIN          0X0B // registrador Alarme 2 de minutos
#define DS3234_ALM2_HORA         0X0C // registrador Alarme 2 de horas
#define DS3234_ALM2_DIA_SEMANA   0X0D // registrador Alarme 2 de dia e dia da semana

#define DS3234_CONTROLE          0X0E // registrador de controle(config)
#define DS3234_STAT_CONTROLE     0X0F // registrador de controle e status
#define DS3234_CONF_CRISTAL      0X10 // registrador do cristal interno

#define DS3234_TEMP_H            0X11 // registrador do sensor de temperatura parte alta(msb))
#define DS3234_TEMP_L            0X12 // registrador do sensor de temperatura parte baixa(lsb)

#define DS3234_S_RAM             0X18 // registrador da memoria S_RAM
#define DS3234_S_RAM_DADOS       0X18 // registrador da memoria S_RAM dados


void setup() {
  Serial.begin(115200); 
  pinMode(LED_STATUS, OUTPUT);
  digitalWrite(LED_STATUS, LOW);
  inicializa_spi();
  inicializa_DS3234(); 
}
void loop() {
  digitalWrite(LED_STATUS,HIGH);
  Serial.print("DATA:");
  Serial.print(DS3234_ler_spi(DS3234_DIA), HEX);
  Serial.print("/"); 
  Serial.print(DS3234_ler_spi(DS3234_MES), HEX);
  Serial.print("/");
  Serial.print(DS3234_ler_spi(DS3234_ANO), HEX);
  Serial.print(" -> ");
  Serial.print(DS3234_ler_spi(DS3234_HORA), HEX);
  Serial.print(":");
  Serial.print(DS3234_ler_spi(DS3234_MIN), HEX);
  Serial.print(":");
  Serial.println(DS3234_ler_spi(DS3234_SEG), HEX);
  delay(1000);//1s
  digitalWrite(LED_STATUS,LOW);
  delay(1000);//1s
}
/*
 * Funções usadas no laço principal
 * eu poderia ter montado uma lib - mas a ideia é compartilhar como se faz 
 * uma comunicação spi com o DS3234 que sirva em qualquer dispositivo.
 */
 ////////////////////////////////////////////////////////////////////
//cria estado padrão dos pinos spi
////////////////////////////////////////////////////////////////////
void inicializa_spi()
{ 
  pinMode(SPI_CLK, OUTPUT);
  digitalWrite(SPI_CLK, HIGH);
  pinMode(SPI_IN, INPUT);
  pinMode(SPI_OUT, OUTPUT);
  digitalWrite(SPI_OUT, LOW);
  pinMode(SPI_CS, OUTPUT);
  digitalWrite(SPI_CS,HIGH);
  return;
}
////////////////////////////////////////////////////////////////////
//inicializa o chip
////////////////////////////////////////////////////////////////////
void inicializa_DS3234()
{
    DS3234_escr_spi(DS3234_CONTROLE,0X80);//80= desliga saida do oscilador , SQ wave @1hz, Alarme desabilitados
    DS3234_escr_spi(DS3234_ANO,0X17);//configura data para 25/08/2017 - 15:05
    DS3234_escr_spi(DS3234_MES,0X08);//colocar os valores sempre em hexadecimal
    DS3234_escr_spi(DS3234_DIA,0X25);
    DS3234_escr_spi(DS3234_HORA,0X15);
    DS3234_escr_spi(DS3234_MIN,0X05);
    return;
}
////////////////////////////////////////////////////////////////////
//essa rotina serve tanto para escrever quanto para ler 
////////////////////////////////////////////////////////////////////
int DS3234_ler_spi_byte(int valor,int liga_cs)
{//já escreve e já lê
  int dados = 0;
  int pos=128;
  digitalWrite(SPI_CS, LOW);
  delayMicroseconds(1); 
  while(pos>0)///bit mais significativo primeiro
  {
      if((valor&pos)>0)//faz uma operaçao and e checa se é 1
        {digitalWrite(SPI_OUT,HIGH);}
      else
        {digitalWrite(SPI_OUT,LOW);}
        digitalWrite(SPI_CLK,LOW);
        delayMicroseconds(1); ///tempo em nivel baixo do clock
        if(digitalRead(SPI_IN)==HIGH)
        {dados = dados|pos;}      
        digitalWrite(SPI_CLK,HIGH);
        delayMicroseconds(1); ///tempo em nivel baixo do clock//tempo em nivel alto do clock
    pos=pos/2;//rotaciona 1 bit
  }
  if(liga_cs == 1)
  {digitalWrite(SPI_CS, HIGH);}
   return(dados);
}
////////////////////////////////////////////////////////////////////
//essa rotina lê um byte do registrador colocado em endereço
////////////////////////////////////////////////////////////////////
int DS3234_ler_spi(int endereco)
{
  int dados;
  DS3234_ler_spi_byte(endereco,0);
  dados = DS3234_ler_spi_byte(0X00,1);//não envia nada somente para pegar os dados
  return(dados);
}
////////////////////////////////////////////////////////////////////
//essa rotina escreve um byte no registrador  em endereço
////////////////////////////////////////////////////////////////////
void DS3234_escr_spi(int endereco,int dados)
{
  endereco = endereco|0X80;//pronto pra escrever
  DS3234_ler_spi_byte(endereco,0);
  DS3234_ler_spi_byte(dados,1);  
}


Veja o vídeo de demonstração :