Olá galera, estou tendo um problema com um RTC MCP79410 da Microchip em relação a leitura dos registradores do mesmo.
Eu estou seguindo o datasheet mas não tenho resultados positivos. Este mesmo módulo eu testei com o Arduino e funcionou bem, estou usando pullups como manda, logo o problema não é com o módulo.
Se alguém puder dar uma olhada no algoritmo e me falar o que posso estar fazendo de errado vai ser legal.
Obrigado!
_________________________________________________________________________________
//******* *************************************************************************
/** I N C L U D E S **********************************************************/
#include <p18cxxx.h> // Necessário para que o compilador adicione a biblioteca
// com as definições do PIC selecionado no projeto, neste
// caso, o modelo 18F4550.
#include <i2c.h> // Biblioteca com funções I2C
#include <timers.h> // Biblioteca dos timers
#include <delays.h> // Bilioteca com funções de atraso (delay)
#include "displayLCD.h" // Bibioteca com funções do display
/** BITS DE CONFIGURAÇÃO DO DISPOSITIVO***************************************/
#pragma config FOSC = HSPLL_HS // Habilita PLL, CPU e USB com cristal de alta velocidade (High Speed)
#pragma config PLLDIV = 5 // Oscilador de entrada de 20 MHz
#pragma config CPUDIV = OSC1_PLL2 // Clock CPU = 96MHz PLL/2
#pragma config USBDIV = 2 // Clock da USB = 96MHz PLL/2
#pragma config FCMEN = OFF // Fail Safe Clock Monitor
#pragma config IESO = OFF // Mudança do Oscilador int/ext
#pragma config PWRT = OFF // Power up Timer
#pragma config BOR = OFF // Brown-out Reset
#pragma config BORV = 3 // Tensão de Brown-out Reset = 2.05V
#pragma config VREGEN = ON // Regulator Interno da USB de 3,3V
#pragma config WDT = OFF // Watch Dog Timer
#pragma config WDTPS = 32768 // Postcaler do Watch Dog Timer
#pragma config MCLRE = ON // Master Clear Reset pino RE3
#pragma config LPT1OSC = OFF // Timer1 em Low-Power Oscilator
#pragma config PBADEN = OFF // PORTB<4:0> Analogicas no Reset
#pragma config CCP2MX = ON // CCP2 Mux ligado a RC1(ON) ou RB3(OFF)
#pragma config STVREN = ON // Stack Full / Overflow Reset
#pragma config LVP = OFF // Single Supply ICSP, Low-Voltage ICSP
#pragma config DEBUG = OFF // Pinos RB6 e RB7 dedicados para In Circuit Debug
#pragma config ICPRT = OFF // Pinos RB6 e RB7 dedicados para gravação ICSP
#pragma config XINST = OFF // Instruções Extendidas
// Proteção contra Leitura Externa dos Blocos da Flash
#pragma config CP0 = OFF // Bloco0
#pragma config CP1 = OFF // Bloco1
#pragma config CP2 = OFF // Bloco2
#pragma config CP3 = OFF // Bloco3
#pragma config CPB = OFF // Bloco Boot
#pragma config CPD = OFF // EEPROM
// Proteção contra Escrita nos Blocos da Flash
#pragma config WRT0 = OFF // Bloco0
#pragma config WRT1 = OFF // Bloco1
#pragma config WRT2 = OFF // Bloco2
#pragma config WRT3 = OFF // Bloco3
#pragma config WRTB = OFF // Bloco Boot
#pragma config WRTC = OFF // Bits de Configuração
#pragma config WRTD = OFF // EEPROM
// Proteção contra Leitura do Bloco via TBLRD localizadas em outros blocos
#pragma config EBTR0 = OFF // Bloco0
#pragma config EBTR1 = OFF // Bloco1
#pragma config EBTR2 = OFF // Bloco2
#pragma config EBTR3 = OFF // Bloco3
#pragma config EBTRB = OFF // Bloco Boot
/** D E F I N E S ************************************************************/
// Saidas Digitais
#define LED_VERMELHO LATAbits.LATA0 // Led vermelho
#define LED_AMARELO LATDbits.LATD0 // Led Amarelo
#define LED_VERDE LATCbits.LATC0 // Led Verde
//Entradas Digitais
/** V A R I A V E I S G L O B A I S ****************************************/
char num = 0 ; // Variável para armazenar o byte de leitura
int i = 0 ; // Variável para armazenar o valor da conversão
/** P R O T O T I P O S P R I V A D O S ***********************************/
void ConfiguraSistema(void) ; // Função para reunir as configurações
void ConfiguraInterrupcao(void) ; // Função para reunir config. de inter.
void ISR_alta_prioridade(void) ; // Função para alta prioridade
void ISR_baixa_prioridade(void) ; // Função para bixa prioridade
char bcd2dec(char num) ; // Função de conversão BCD para DECIMAL
/** F U N C O E S ************************************************************/
/******************************************************************************
* Funcao: void main(void)
* Entrada: Nenhuma (void)
* Saída: Nenhuma (void)
* Descrição: Função principal do programa.
*****************************************************************************/
void main(void)
{
ConfiguraSistema(); // Configura as portas e periféricos do PIC.
ConfiguraInterrupcao(); // Configura todas as interrupções
DesligaCursor(); // Chama a fuo que desliga o cursor
LimpaDisplay(); // Chama a função que limpa o display
//Inicia saidas digitais desligadas
LED_VERMELHO = 0;
LED_AMARELO = 0;
LED_VERDE = 0;
while(1) // Laço infinito que executa o funcionamento principal do projeto.
{
IdleI2C() ; // Aguarda ate que o barramento esteja livre
StartI2C() ; // Inicia a comunicação I2C
IdleI2C() ; // Aguarda ate que o barramento esteja livre
WriteI2C(0b10101110); // Control Byte enviado para "Random Read"
IdleI2C() ; // Aguarda ate que o barramento esteja livre
AckI2C() ; // Gera a condição de Acknowledge
IdleI2C() ; // Aguarda ate que o barramento esteja livre
WriteI2C(0x01) ; // Envia o "Address byte", referente aos minutos
IdleI2C() ; // Aguarda ate que o barramento esteja livre
num = ReadI2C() ; // Faz a leitura no barramento I2C de um unico byte
IdleI2C() ; // Aguarda ate que o barramento esteja livre
NotAckI2C() ; // Gera a condição de "Not Acknowlege"
IdleI2C() ; // Aguarda ate que o barramento I2C esteja livre
StopI2C() ; // Gera a condição de STOP no barramento
i= bcd2dec(num) ; // Faz a conversão de BCD para decimal
LED_AMARELO = 1 ; // Liga o led amarelo
Delay10KTCYx(100) ; // Delay CPU
PosicaoCursorLCD(1,1); // Posiciona o cursor na linha 1 coluna 1
EscreveFraseRomLCD("Leitura "); // Escreve no display
EscreveInteiroLCD(i) ; // Escreve no display o valor da leitura do I2C
LED_AMARELO = 0 ; // Desliga o led amarelo
Delay10KTCYx(100) ; // Delay CPU
}//end while(1)
}//end main
char bcd2dec(char num) // Função de conversão
{
return ((num/16 * 10) + (num % 16));
}
/******************************************************************************
* Funcao: void ConfiguraSistema(void)
* Entrada: Nenhuma (void)
* Saída: Nenhuma (void)
* Descrição: ConfiguraSistema é a rotina de configuração principal do PIC.
* Seu objetivo é configurar as portas de I/O e os periféricos
* do microcontrolador para que os mesmos trabalhem da maneira
* desejada no projeto.
*****************************************************************************/
void ConfiguraSistema(void)
{
// Desabilita todas as analógicas
ADCON1 = ADCON1 | 0x0F;
// Configurações
ConfiguraLCD();
OpenI2C(MASTER,SLEW_OFF); // Configurações do I2C
SSPADD = 49; // Configuração de velocidade de comunicação no protocolo I2C
// Configura saidas digitais
TRISDbits.TRISD1 = 0 ; // Led vermelho
TRISDbits.TRISD0 = 0 ; // Led amarelo
TRISCbits.TRISC0 = 0 ; // Led verde
// Configura entradas digitais
TRISBbits.TRISB1 = 1 ; // Configura pino usado no bus i2c como entrada
TRISBbits.TRISB0 = 1 ; // Configura pino usado no bus i2c como entrada
}//end ConfiguraSistema
/******************************************************************************
* Funcao: void ConfiguraInterrupcao(void)
* Entrada: Nenhuma (void)
* Saída: Nenhuma (void)
* Descrição: Função que configura as interrupções utilizadas no projeto
*****************************************************************************/
void ConfiguraInterrupcao(void)
{
}// end ConfiguraInterrupcao
/****************************************************************************
* Funcao: void ISR_alta_prioridade(void)
* Entrada: Nenhuma (void)
* Saída: Nenhuma (void)
* Descrição: Função de tratamento das interrupções de ALTA prioridade
* Nessa função deve-se lembrar de fazer a seguinte lista:
* 1- verificar qual foi a causa da interrupção, comparando
* os flags de cada tipo de interrupção.
* 2- tratar a interrupção selecionada.
* 3- limpar o flag que causou a interrupção!!! Importante
* para garantir que não ocorrerá uma chamada indesejada ao sair
* do tratamento da interrupção.
*
* Ao sair dessa função é usado o retorno do tipo "retfie fast",
* pois esta função é declarada como ALTA prioridade com a diretiva
* #pragma interrupt
*****************************************************************************
#pragma interrupt ISR_alta_prioridade
void ISR_alta_prioridade(void)
{
}// end Tratamento_High_Interrupt
/***************************************************************************
* Funcao: void ISR_baixa_prioridade(void)
* Entrada: Nenhuma (void)
* Saída: Nenhuma (void)
* Descrição: Função de tratamento das interrupções de BAIXA prioridade
* Nessa função deve-se lembrar de fazer a seguinte lista:
* 1- verificar qual foi a causa da interrupção, comparando
* os flags de cada tipo de interrupção.
* 2- tratar a interrupção selecionada.
* 3- limpar o flag que causou a interrupção!!! Importante
* para garantir que não ocorrerá uma chamada indesejada ao sair
* do tratamento da interrupção.
*
* Ao sair dessa função é usado o retorno do tipo "retfie",
* pois esta função é declarada como BAIXA prioridade com a diretiva
* #pragma interruptlow
*****************************************************************************
#pragma interrupt ISR_baixa_prioridade
void ISR_baixa_prioridade(void)
{
}//end Tratamento_Low_Interrupt
/********* PRAGMAS PARA AS INTERRUPÇÕES **************************************/
#pragma code int_alta = 0x08 //Endereço Vetor de interrupção de alta prioridade
void int_alta(void)
{
_asm GOTO ISR_alta_prioridade _endasm // Desvia o programa para a função ISR_alta_prioridade
}
#pragma code int_baixa = 0x18 // Endereço Vetor de interrupção de baixa prioridade
void int_baixa(void)
{
_asm GOTO ISR_baixa_prioridade _endasm // Desvia o programa para a função ISR_baixa_prioridade
}
#pragma code
/** FIM DO ARQUIVO main.c ***************************************************************/
Tags:
Bom galera, fiz uma mudanças no code, como fala a parte do datasheet em anexo e a Aplication Note da Microchip (AN1364, pg 4), e agora eu consigo ler algum valor do RTC, mas são valores aleatórios, não contínuos como deveriam ser!
Se alguém tiver alguma idéia de como coletar valores com sentido me falem.
Por enquanto estou tentando ler apenas os minutos.
Obrigado.
while(1) // Laço infinito que executa o funcionamento principal do projeto.
{
IdleI2C() ; // Aguarda ate que o barramento esteja livre
StartI2C() ; // Inicia a comunicação I2C
IdleI2C() ; // Aguarda ate que o barramento esteja livre
WriteI2C(0x6f) ; // Control Byte enviado para leitura
IdleI2C() ; // Aguarda ate que o barramento esteja livre
AckI2C() ; // Gera a condição de Acknowledge
IdleI2C() ; // Aguarda ate que o barramento esteja livre
WriteI2C(0x01) ; // Envia o "Address byte", referente aos minutos
IdleI2C() ; // Aguarda ate que o barramento esteja livre
RestartI2C() ; // Restart a comunicação
IdleI2C() ; // Aguarda
WriteI2C(0xdf) ; // Escreve referente ao acesso da SRAM do RTC
IdleI2C() ; // Aguarda
num = ReadI2C() ; // Faz a leitura no barramento I2C de um unico byte
IdleI2C() ; // Aguarda ate que o barramento esteja livre
NotAckI2C() ; // Gera a condição de "Not Acknowlege"
IdleI2C() ; // Aguarda ate que o barramento I2C esteja livre
StopI2C() ; // Gera a condição de STOP no barramento
i= bcd2dec(num) ; // Faz a conversão de BCD para decimal
LED_AMARELO = 1 ; // Liga o led amarelo
Delay10KTCYx(240) ; // Delay CPU
Delay10KTCYx(240) ; // Delay CPU
PosicaoCursorLCD(1,1) ; // Posiciona o cursor na linha 1 coluna 1
EscreveFraseRomLCD("Leitura ") ; // Escreve no display
EscreveInteiroLCD(i) ; // Escreve no display
LED_AMARELO = 0 ; // Desliga o led amarelo
Delay10KTCYx(240) ; // Delay CPU
Delay10KTCYx(240) ; // Delay CPU
Bem-vindo a
Laboratorio de Garagem (arduino, eletrônica, robotica, hacking)
© 2024 Criado por Marcelo Rodrigues. Ativado por