Olá, hoje vou demonstrar como usar o RTC(real time clock) DS3234, a maior
vantagem é possuir internamente no chip o cristal oscilador e um sensor de temperatura,
assim não precisa elementos externo para fazer funcionar o chip RTC. Funcionou tanto na
simulação quanto fisicamente.
O código fonte :
/*
* RTC DS3234 com pic - MPlab XC8
*
* Compilador : MPlabXC8
* Microcontrolador: 16F887
* Autor: Aguivone
* Versão: 1
* Data : 13/02/2017
*/
#include <stdio.h>
#include <string.h> //para usar funçoes de string deve se adicionar este header
#include <stdlib.h>
#define _XTAL_FREQ 20000000//usado para rotinas de delays
#include <xc.h>
/////////////////////////////////////////////////////////configuraçôes//////////////////////////////////////////////////
#pragma config FOSC = HS // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = OFF // Brown-out Reset Enable bit (BOR disabled)
#pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)
unsigned char gucAlternaPino;
unsigned char gucSPI_lido;
//Defines
#define LED_STATUS RD0
/*#define DS3234_SDO TRISCbits.TRISC7
#define DS3234_SDI TRISBbits.TRISB0
#define DS3234_SCK TRISBbits.TRISB1*/
#define DS3234_SS RC2
//***********************************************************************************************************
// 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_CONTROL 0X0E // registrador de controle
#define DS3234_STAT_CONTROL 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
//***********************************************************************************************************
// FUNÇÕES
//***********************************************************************************************************
//===========================================================================================================
// Função: _configura_SPI
// Parâmetros: nenhum
// Retorno: nenhum
// Descrição: configura a parte de hardware que gerencia a SPI.
//===========================================================================================================
void inicializa_spi() //o timer 2 é usado para controlar a spi
{
//RTC - DS3234
SSPSTAT = 0B10000000;//modo metre / clock na borda de decida
SSPCON = 0B00110010;//habilita os pinos da SPI/config clock como nivel altoe freq osc/64.
}
/////////////////////////////////funçoes usadas pela uart //////////////////////////////////////////////////////
void inicializa_RS232(void)
{//// por padrão é usado o modo 8 bits e sem paridade, mas se necessario ajuste aqui a configuração desejada.
//modo alta velocidade
RCSTA = 0X90;//habilita porta serial,recepção de 8 bit em modo continuo,assincrono.
TXSTA = 0X24;//modo assincrono,trasmissao 8 bits.
//somente para cristal de 20Mhz.
SPBRG = 129;//9600
// RCIE = 1;//habilita interrupção de recepção
RCIE = 0;//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 cValor)
{
TXIF = 0;//limpa flag que sinaliza envio completo.
TXREG = cValor;
__delay_us(1);//1us para evitar problemas de perder caracteres
while(TXIF == 0);//espera enviar caracter
}
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 hex_to_int_char(char quant)
{//converte para inteiro e imprime
unsigned char ucDez='0', ucUn='0';
if(quant>=100)
{//imprime centenas
while(quant>=100)
{
quant -= 100;
ucDez++;
}
escreve(ucDez);
ucDez='0';//zera variavel novamente
}
while(quant>=10)
{
quant -= 10;
ucDez++;
}
while(quant>=1)
{
quant -= 1;
ucUn++;
}
escreve(ucDez);
escreve(ucUn);
}
void hex_to_char(char quant)
{//converte para char e imprime
unsigned char ucDez, ucUn;
ucDez = quant/16;
ucUn = quant%16;
if(ucDez >= 10)
ucDez = (ucDez-10) + 'A';
else
ucDez += '0';
if(ucUn >= 10)
ucUn = (ucUn-10) + 'A';
else
ucUn += '0';
escreve(ucDez);
escreve(ucUn);
}
unsigned char DS3234_LER_SPI(unsigned char registrador)
{
unsigned char dado = SSPBUF;//para limpar buffer
DS3234_SS = 0; // ativa SS(slave select)
SSPBUF = registrador;//envia endereço
while(!SSPSTATbits.BF);//espera completar envio de dados
dado = SSPBUF;//para limpar buffer e SSPSTATbits.BF
// for(unsigned char Cont=0;Cont<10;Cont++); // Este tempo é necessário para finalizar primeira transmissão
SSPBUF = 0X00;//envia um informação qualquer para que os dados do slave chegue(pois ainda precisa de mais 8 clock)
while(!SSPSTATbits.BF);//espera completar envio de dados
dado = SSPBUF;//para limpar buffer e SSPSTATbits.BF
DS3234_SS = 1;//desabilita chip
return(dado);//retorna valor
}
void DS3234_ESCREVE_SPI(unsigned char endereco,unsigned char valor)
{
unsigned char dado = SSPBUF;//para limpar buffer
endereco = endereco|0X80;//pronto pra escrever
DS3234_SS = 0; // ativa SS(slave select)
SSPBUF = endereco;//opcode que sinaliza que quer deixar um dado
while(!SSPSTATbits.BF);//espera completar envio de dados
dado = SSPBUF;//para limpar buffer e SSPSTATbits.BF
// for(unsigned char Cont=0;Cont<10;Cont++); // Este tempo é necessário para finalizar primeira transmissão
SSPBUF = valor;//envia os dados que será colocado no registrador
while(!SSPSTATbits.BF);//espera completar envio de dados
dado = SSPBUF;//para limpar buffer e SSPSTATbits.BF
DS3234_SS = 1;//desabilita chip
}
void inicializa_RTC()
{
DS3234_ESCREVE_SPI(DS3234_CONTROL,0X80);//80= desliga saida do oscilador , SQ wave @1hz, Alarme desabilitados
DS3234_ESCREVE_SPI(DS3234_ANO,0X17);//25/08/2017 - 15:05
DS3234_ESCREVE_SPI(DS3234_MES,0X08);//colocar os valores sempre em hexadecimal
DS3234_ESCREVE_SPI(DS3234_DIA,0X25);
DS3234_ESCREVE_SPI(DS3234_HORA,0X15);
DS3234_ESCREVE_SPI(DS3234_MIN,0X05);
}
//////////////////////////////////////////////////////Rotina principal///////////////////////////////////////////////////////////////
void main(void)
{
TRISA = 0XDF; //somente pino 5 é saida
TRISB = 0; //configura como saida
TRISC = 0X10; //somete C4 é entrada(SDI))
TRISD = 0; //configura como saida
TRISE = 0XFF; //configura como entrada
PORTA = 0;
PORTB = 0; // limpar as portas que estão configuradas como saidas
PORTC = 0;
PORTD = 0;
PORTE = 0;
inicializa_RS232();
inicializa_spi();
GIE = 0; //desliga interrupções
ADCON0 = 0X00;//desabilita modulo ADC
ADCON1 = 0X07;//desliga modulo comparador
ANSEL = 0x00; // Disable todas as portas analogicas
CM1CON0 = 0;
CM2CON0 = 0;
long Pisca = 200;//tempo qualquer
__delay_ms(50);
imprime("Usando : RTC_DS3234 \r\n");
inicializa_RTC();
for(;;)
{
if(Pisca == 0)
{
if(gucAlternaPino == '0')
{
LED_STATUS=0;
gucAlternaPino = '1';
gucSPI_lido = DS3234_LER_SPI(DS3234_HORA);
hex_to_char( gucSPI_lido);
escreve(':');
gucSPI_lido = DS3234_LER_SPI(DS3234_MIN);
hex_to_char( gucSPI_lido);
escreve(':');
gucSPI_lido = DS3234_LER_SPI(DS3234_SEG);
hex_to_char( gucSPI_lido);
escreve('-');
escreve('>');
gucSPI_lido = DS3234_LER_SPI(DS3234_DIA);
hex_to_char( gucSPI_lido);
escreve('/');
gucSPI_lido = DS3234_LER_SPI(DS3234_MES);
hex_to_char( gucSPI_lido);
escreve('/');
gucSPI_lido = DS3234_LER_SPI(DS3234_ANO);
hex_to_char( gucSPI_lido);
imprime("\r\n Temperatura :");//para temperatura negativas é preciso fazer
gucSPI_lido = DS3234_LER_SPI(DS3234_TEMP_H);//alguns tratamentos aqui vamos demontrar apena para uma escala acima de 0
hex_to_int_char( gucSPI_lido);
// praticamente não vai fazer diferença
// gucSPI_lido = DS3234_LER_SPI(DS3234_TEMP_L);
//hex_to_int_char( gucSPI_lido);
imprime("\r\n");
}
else
{
LED_STATUS=1;
gucAlternaPino = '0';
}
Pisca = 200;
}
else
{
Pisca--;
__delay_ms(1);
}
}//loop infinito
}
A simulação ficou assim:
Nenhum comentário :
Postar um comentário
olá,digite aqui seu comentário!