- Materiais requisitados:
- Módulo RTC:
- Conectando o DS3231 RTC com Microcontrolador PIC:
- Programando PIC para Módulo RTC:
- Breve explicação do arquivo de cabeçalho PIC16F877a_DS3231.h:
- Simulação:
- Exibir hora e data no LCD:
Quase todos os dispositivos embarcados são projetados para interagir com o mundo real. Eles atuam como uma ponte de comunicação entre o mundo digital e o mundo real. Para tornar esse processo mais fácil e eficiente, o mundo digital às vezes precisaria manter o controle da hora e data do mundo real. Desta forma, o mundo digital saberá que hora / dia é no mundo real e poderá até distinguir entre dia e noite. Ele também pode atuar como uma fonte de tempo para executar certas tarefas em uma hora ou data específica. Portanto, aqui estamos fazendo a interface de um módulo RTC com o microcontrolador PIC e exibindo a hora e a data no LCD 16x2. Este projeto também pode ser usado como Relógio Digital.
Materiais requisitados:
- Fonte regulada de 5V
- PIC16F877A
- Oscilador de cristal 20Mhz
- Capacitor 33pf - 2Nos
- 10K, 5,1K, resistor 1K
- Módulo DS3231 RTC
- POT -10k
- Módulo LCD 16 * 2
- Fios de conexão
Módulo RTC:
A forma mais comum de um microcontrolador controlar a hora ou data do mundo real é usando um RTC IC. O termo RTC significa Relógio em tempo real; este IC mantém registro da hora e data do mundo real e compartilharia essas informações com o microcontrolador sempre que solicitado. O RTC IC que estamos usando aqui é o DS3231 mais popular e preciso. Este IC muda apenas alguns segundos a cada ano e, portanto, é altamente confiável. Neste tutorial, estamos usando o módulo DS3231 RTC, que pode ser facilmente adquirido online ou na loja de hardware local. O módulo vem com uma célula tipo moeda de 3 V que alimenta o módulo RTC sempre e, portanto, uma vez que a hora e a data sejam definidas, ela será atualizada enquanto a célula tipo moeda estiver viva.
O módulo DS3231 se comunica com a ajuda do protocolo I2C, portanto, se você não sabe o que é e como é usado com o PIC, leia o tutorial I2C com PIC antes de prosseguir. Também neste tutorial, vamos criar um arquivo de cabeçalho que pode ser usado para se comunicar com nosso módulo RTC e também testá-lo no hardware exibindo a hora e a data em um display LCD, portanto, também é importante aprender como fazer a interface display com microcontrolador PIC. O arquivo de cabeçalho criado neste tutorial para o DS3231 pode ser usado / modificado posteriormente para se adequar aos seus aplicativos.
Anteriormente, usamos DS3231 RTC com Arduino nos projetos abaixo:
- Alimentador automático de animais de estimação usando Arduino
- Arduino Data Logger
Conectando o DS3231 RTC com Microcontrolador PIC:
O diagrama de circuito para relógio digital baseado em microcontrolador PIC é fornecido abaixo. Como dito anteriormente, o DS3231 trabalha com a ajuda da comunicação I2C, então ele terá um pino Serial Clock (SCL) e um Serial Data (SDA) que deve ser conectado aos pinos I2C em nosso PIC, que é o pino 18 (SCL) e pino 23 (SDA). Um resistor pull up de valor 4.7k é usado para manter o barramento em estado alto quando ocioso.
Um display LCD também é conectado aos pinos da Porta D para exibir a data e a hora atuais. O diagrama de circuito completo foi projetado em proteus e é mostrado abaixo. Iremos usar o mesmo para simular ou programar posteriormente neste tutorial.
Siga o diagrama de circuito e faça as conexões de acordo, a caixa I2C mostrada acima é usada para depuração I2C, portanto não incluiremos isso em nossas conexões. Além disso, não é mostrado que o módulo RTC deve ser alimentado com uma fonte de + 5V usando os pinos Vcc e terra no módulo. Usei minha placa de ensaio para fazer a conexão e depois de fazer as conexões necessárias, minha configuração ficou mais ou menos assim abaixo.
Se você é novo no microcontrolador PIC, comece com Introdução ao microcontrolador PIC.
Programando PIC para Módulo RTC:
O programa completo para este relógio digital pode ser baixado do arquivo ZIP aqui. O programa inclui três arquivos de cabeçalho no total. Eles são o arquivo lcd.h para trabalhar com display LCD, o arquivo PIC16F877a_I2C.h para trabalhar com comunicação I2C com PIC e finalmente o PIC16F877a_DS3231.h arquivo para trabalhar com módulos RTC. Todos os três arquivos de cabeçalho são necessários para este programa e estão disponíveis no arquivo ZIP acima. Mais abaixo, irei explicar o programa principal que usa todos esses arquivos de cabeçalho para ler a hora e a data do módulo RTC e exibi-los na tela LCD. Depois disso, explicarei o que realmente está acontecendo dentro do arquivo de cabeçalho RTC. Como sempre, comece o programa definindo os bits de configuração e definindo a frequência do clock como 20 MHz, já que é o que usamos em nosso hardware.
#pragma config FOSC = HS // Bits de seleção do oscilador (oscilador HS) #pragma config WDTE = OFF // Bit de ativação do temporizador Watchdog (WDT desativado) #pragma config PWRTE = ON // Bit de ativação do temporizador de inicialização (PWRT ativado) # pragma config BOREN = LIGADO // Bit de habilitação de redefinição de Brown-out (BOR habilitado) #pragma config LVP = DESLIGADO // Bit de habilitação de programação serial de baixa tensão (fonte única) (RB3 é E / S digital, HV ligado MCLR deve ser usado para programação) #pragma config CPD = OFF // Bit de proteção de código de memória EEPROM de dados (proteção de código EEPROM de dados desativada) #pragma config WRT = OFF // Flash de memória de programa habilitar bits de habilitação (proteção de gravação desativada; toda a memória de programa pode ser escrito pelo controle EECON) #pragma config CP = OFF // Bit de proteção de código de memória de programa Flash (proteção de código desativada) #define _XTAL_FREQ 20000000
O próximo passo seria definir os pinos do LCD, se você olhar o hardware verá que conectamos os pinos do LCD à PORTA D do RD2 ao RD7, portanto definimos o mesmo conforme mostrado abaixo.
#define RS RD2 #define EN RD3 #define D4 RD4 #define D5 RD5 #define D6 RD6 #define D7 RD7
Por padrão, quando você comprou o módulo RTC, a hora e a data corretas não serão configuradas nele, portanto, temos que configurá-lo através de nosso programa. Portanto, declaramos a variável para cada dado e alimentação na hora e data do mundo real, conforme mostrado abaixo. No momento de fazer o upload do programa, minha hora e data eram 10:55 da manhã do dia 05/06/2018, portanto, configurei as variáveis conforme abaixo. Você pode definir a hora e a data corretas de acordo com sua aplicação real
/ * Defina o valor atual de data e hora abaixo de * / int sec = 00; int min = 55; hora int = 10; data int = 06; mês int = 05; ano int = 18; / * Definir hora e data * /
Em seguida, adicionamos todos os arquivos de cabeçalho sobre os quais discutimos. Se você baixou e abriu o programa a partir do arquivo ZIP, então não será um problema, então certifique-se de que todos os arquivos de cabeçalho foram adicionados ao arquivo de origem ou ao diretório do projeto.
#incluir
Visto que usamos a PORTA D como os pinos de saída para fazer a interface com o LCD, temos que declará-los como pinos de saída em nosso programa e inicializar o display LCD como mostrado abaixo
TRISD = 0x00; // Faça os pinos da Porta D como saída para interface de LCD Lcd_Start (); // Inicializar módulo LCD
O módulo RTC se comunica com a ajuda do protocolo I2C, portanto temos que habilitar a comunicação I2C com nosso microcontrolador PIC. A maioria dos dispositivos, incluindo nossos módulos DS3231, tem uma frequência operacional I2C de 100KHz, portanto, iniciamos a comunicação I2C com uma frequência de 100KHz, conforme mostrado abaixo
I2C_Initialize (100); // Inicializa I2C Master com clock de 100KHz
Assim que tivermos estabelecido uma comunicação I2C com o módulo RTC, a primeira coisa que faremos é definir a hora e a data atuais que inserimos em nosso programa. Isso pode ser feito chamando a função set_Time_Date conforme mostrado abaixo. Uma vez que a hora e a data são definidas, o módulo irá rastreá-los automaticamente e incrementá-los como um relógio digital.
Set_Time_Date (); // definir hora e data no módulo RTC
Para indicar que o programa foi iniciado, exibiremos uma pequena mensagem de introdução, que permanecerá na tela por 2 segundos. Esta mensagem exibirá RTC com PIC –Circuit Digest na tela. O programa para o mesmo é mostrado abaixo
Lcd_Clear (); Lcd_Set_Cursor (1,1); Lcd_Print_String ("RTC com PIC"); Lcd_Set_Cursor (2,1); Lcd_Print_String ("-Circuit Digest"); __delay_ms (1500);
Dentro da nossa infinita enquanto loop de que devemos ler a hora e data atual e, em seguida, exibir os valores em nossa tela de LCD. Para ler a hora e a data do módulo RTC, a função Update_Current_Time_Date pode ser usada conforme mostrado abaixo. Esta função irá ler o valor do módulo RTC e atualizar as variáveis seg, min, hora, data, mês e ano com os valores atuais. Então, podemos usá-los para nosso propósito.
Update_Current_Date_Time (); // Leia a data e hora atuais do módulo RTC
As variáveis são do tipo de dados inteiros, temos que convertê-las em caracteres individuais para que possamos exibi-las na tela LCD. Portanto, usamos o operador de módulo para obter o dígito único e dividimos a variável por 10 para obter o dígito das dezenas. O mesmo é feito para todas as variáveis.
// Dividir em char para exibir no lcd char sec_0 = sec% 10; char sec_1 = (seg / 10); char min_0 = min% 10; char min_1 = min / 10; char hora_0 = hora% 10; char hora_1 = hora / 10; char date_0 = data% 10; char data_1 = data / 10; char month_0 = month% 10; char mês_1 = mês / 10; char year_0 = year% 10; char ano_1 = ano / 10;
Tudo o que resta fazer é exibir as informações que adquirimos na tela LCD. Isso pode ser feito facilmente com as funções do LCD que discutimos anteriormente em nosso tutorial do LCD. Portanto, o código para exibir a hora é fornecido abaixo, o mesmo método é usado para exibir a data também. Um atraso de 500 ms é dado após a exibição dos dados para que atue como um intervalo de atualização.
Lcd_Clear (); Lcd_Set_Cursor (1,1); Lcd_Print_String ("HORA:"); Lcd_Print_Char (hora_1 + '0'); Lcd_Print_Char (hora_0 + '0'); Lcd_Print_Char (':'); Lcd_Print_Char (min_1 + '0'); Lcd_Print_Char (min_0 + '0'); Lcd_Print_Char (':'); Lcd_Print_Char (sec_1 + '0'); Lcd_Print_Char (sec_0 + '0');
Breve explicação do arquivo de cabeçalho PIC16F877a_DS3231.h:
As coisas explicadas até agora são suficientes para usar o módulo DS3231 com PIC para seus próprios projetos, mas para os curiosos por aí gostariam de saber o que realmente acontece dentro do arquivo de cabeçalho e os dados são realmente recebidos do módulo RTC pelo PIC, apenas leia mais.
A melhor maneira de fazer isso é lendo o datasheet do DS3231 na íntegra. Para resumir o que é necessário, o módulo atua como um escravo do PIC e o endereço de todos os módulos DS3231 é D0. Então, para escrever dados no módulo, temos que passar o endereço D0 e para ler os dados do RTC, temos que passar o endereço D1. Se passarmos o endereço de escrita ao módulo RTC, estaremos preparados para obter os dados do PIC para que os dados consequentes escritos pelo PIC sejam recebidos e guardados no módulo RTC. Da mesma forma, se enviarmos o endereço para leituraentão o PIC deve se preparar para ler os valores do RTC, pois o módulo RTC começará a enviar todos os dados que possui. A sequência de bits para D0 e D1 é mostrada abaixo na folha de dados. Observe que o endereço 0b11010000 representa D0 (gravação) e 0b11010001 representa D01 (leitura)
Quando o PIC envia o endereço D0 ou D1 para escrever ou ler, os dados a seguir devem ser lidos ou escritos em um pedido. Este pedido é mostrado na tabela abaixo. Assim, os primeiros dados serão seg (00h) seguidos de minutos (01h) seguidos de horas (02h) seguidos de dia (03h) e até MSB de Temperatura.
O módulo RTC não entende valores decimais, ele se comunica apenas por meio de valores BCD. Portanto, antes de gravar qualquer valor no módulo RTC, ele deve ser convertido para BCD e também os valores recebidos do módulo RTC estarão no formato BCD e deve ser convertido para decimal para fazer sentido para nós. Com isso em mente, vamos criar todas as funções necessárias para usar o módulo RTC.
Funções BCD_2_DEC e DEC_2_BCD:
As duas primeiras funções seriam usadas para converter os dados BCD em decimais e os dados decimais em BCD, uma vez que o módulo RTC entende apenas BCD. As fórmulas para converter BCD em decimal e BCD em decimal são
Decimal = (BCD >> 4) * 10 + (BCD & 0x0F) BCD = ((Decimal / 10) << 4) + (Decimal% 10)
Só temos que usar essas duas fórmulas para criar uma função que pega na unidade oposta como parâmetro e converte para o formato requerido e o retorna, a função para fazer o mesmo é mostrada abaixo
int BCD_2_DEC (int to_convert) { return (to_convert >> 4) * 10 + (to_convert & 0x0F); } int DEC_2_BCD (int to_convert) { return ((to_convert / 10) << 4) + (to_convert% 10); }
Função Set_Time_Date ():
Esta função irá escrever o valor da hora e data do módulo PIC para o RTC. Os valores de tempo real e data devem ser atualizados nas variáveis seg, min, hora, data, mês e ano pelo usuário. Esses valores serão então convertidos em BCD e gravados no módulo RTC.
Como discutimos, para escrever um valor no módulo RTC, temos que passar o endereço D0 e escrever um bit 0 para iniciar o processo de escrita. Em seguida, podemos enviar os dados na ordem mostrada na tabela acima.
void Set_Time_Date () { I2C_Begin (); I2C_Write (0xD0); I2C_Write (0); I2C_Write (DEC_2_BCD (seg)); // atualiza sec I2C_Write (DEC_2_BCD (min)); // atualiza min I2C_Write (DEC_2_BCD (hora)); // hora de atualização I2C_Write (1); // ignora a atualização do dia I2C_Write (DEC_2_BCD (data)); // data de atualização I2C_Write (DEC_2_BCD (mês)); // atualiza o mês I2C_Write (DEC_2_BCD (ano)); // ano de atualização I2C_End (); }
Função Update_Current_Date_Time ():
A última função da biblioteca é a que permite ler a hora e a data do módulo RTC e repassá-la ao microcontrolador PIC. Esta função é dividida em três segmentos, um para iniciar o processo de leitura e o segundo para ler os valores e salvá-los nas variáveis globais como seg, min, hora, data, mês e ano. E a terceira é reconhecer que a leitura foi bem-sucedida.
Observe que para cada ação a comunicação I2C deve ser iniciada e encerrada.
Para ler os valores do RTC temos que enviar o endereço D0 seguido de 0. Isso fará com que o módulo RTC envie todos os valores que possui na ordem mostrada na tabela acima. Podemos apenas lê-los, convertê-los em decimais e salvá-los nas variáveis na mesma ordem.
Finalmente, após a leitura, o módulo RTC enviará um bit de confirmação que também deverá ser lido e confirmado.
void Update_Current_Date_Time () { // INICIAR a leitura I2C_Begin (); I2C_Write (0xD0); I2C_Write (0); I2C_End (); // LEIA I2C_Begin (); I2C_Write (0xD1); // Inicializa a leitura de dados sec = BCD_2_DEC (I2C_Read (1)); min = BCD_2_DEC (I2C_Read (1)); hora = BCD_2_DEC (I2C_Read (1)); I2C_Read (1); data = BCD_2_DEC (I2C_Read (1)); mês = BCD_2_DEC (I2C_Read (1)); ano = BCD_2_DEC (I2C_Read (1)); I2C_End (); // END Reading I2C_Begin (); I2C_Write (0xD1); // Inicializa dados lidos I2C_Read (1); I2C_End (); }
Simulação:
O projeto pode ser simulado usando o software de simulação Proteus. Faça as conexões conforme mostrado no diagrama de circuito e carregue o arquivo hex no controlador PIC. Ao simular, você encontrará duas caixas pop-up e a data e a hora exibidas no LCD conforme mostrado abaixo.
O pequeno na parte superior mostra a hora e a data atuais dentro do módulo RTC e o segundo pop-up é o depurador I2C. É uma excelente ferramenta para verificar quais dados estão realmente sendo passados para dentro e para fora do bug I2C.
Exibir hora e data no LCD:
Assim que o hardware estiver pronto e o código for baixado como arquivo ZIP através do link fornecido, abra o programa usando o MPLABX IDE. Você deve iniciar o IDE primeiro e usar a opção abrir projeto e navegar até o conteúdo dentro do arquivo ZIP e abrir a pasta.X.
Basta verificar se o programa está compilando e enviar o código para o seu hardware usando o PicKit3. Assim que o programa for carregado, você deverá ver a mensagem introdutória e, em seguida, a hora e a data deverão ser exibidas conforme mostrado abaixo.
Se não houver nada no LCD, verifique suas conexões e certifique-se de que o nível de contraste está configurado corretamente variando o potenciômetro. É assim que você pode mostrar a hora e data para todos os seus projetos de microcontrolador PIC e pode usar isso como Relógio Digital. Espero que você tenha aprendido algo novo e tenha gostado de aprender este tutorial. Se você tiver enfrentado algum problema, poste-os nos comentários abaixo ou nos fóruns para obter ajuda técnica.
Baixe o programa PIC completo para este projeto com arquivos de cabeçalho a partir daqui e verifique mais tarde todos os nossos tutoriais PIC aqui.