DS3232 is a newer RTC device with TWI interface. It requires only a few external passive components to make the circuit works. It has an internal precise 32.768 kHz clock. Hence, the device need only a back up battery and two pull up resistor, basically. In the market, this device built into the Arduino module cost around 2$.
In the earlier post, ATMega32 reads date and time from DS1307 TWI RTC. Similarly, this device could interface to other TWI device, within the case of DS3232.
DS3232 has a larger RAM space than the DS1307. The extended RAM space contain many control and data register. But, here the notable registers are the two internal device's temperature registers. In this post I wrote about using DS3232 with PIC16F716 with more device details. The device's details is not listed here due to duplication.
![]() |
ATMega32 Interfaces To DS3232 And Character LCD |
I use a 20x4 character LCD I used for many years in my academic stuffs and projects development. The temperature is in floating point format available in both degree Celsius and Fahrenheit.
C source stored in my GitHub gist respiratory.
/* | |
* ds3232LcdM32.c | |
* | |
* Created: 9/2/2020 6:13:42 PM | |
* Author : https://aki-technical.blogspot.com | |
*/ | |
#include <avr/io.h> | |
#include <stdio.h> | |
#define F_CPU 16000000UL | |
#include <util/delay.h> | |
#define lcdPort PORTD | |
#define lcdDir DDRD | |
#define RS 0 | |
#define E 1 | |
void lcdPortInit(void){ | |
//Only PORTD Is LCD Port | |
lcdDir=0xFF; | |
} | |
void writeCommand(char command){ | |
lcdPort=(command&0xF0)|(1<<E); | |
lcdPort=(command&0xF0); | |
_delay_us(50); | |
lcdPort=(command<<4)|(1<<E); | |
lcdPort=(command<<4); | |
_delay_ms(3); | |
} | |
void writeChararacter(char character){ | |
lcdPort=(character&0xF0)|(1<<E)|(1<<RS); | |
lcdPort=(character&0xF0)|(1<<RS); | |
_delay_us(50); | |
lcdPort=(character<<4)|(1<<E)|(1<<RS); | |
lcdPort=(character<<4)|(1<<RS); | |
_delay_ms(3); | |
} | |
void writeString(char *text){ | |
while(*text) writeChararacter(*text++); | |
} | |
/*This function ease of setting the cursor position*/ | |
void setXy(int x,int y){ | |
/*Select A 40x4 LCD*/ | |
char numberOfLines[4]={0x80,0xC0,0x94,0xD4}; | |
/* The position starts from (x,y)=(0,0) */ | |
writeCommand(numberOfLines[x]+y); | |
} | |
void lcdInit(void){ | |
/*Initialize the LCD PORT*/ | |
lcdPortInit(); | |
/*Writing the instructions | |
4-bit mode, 2-line,5x8 dot*/ | |
writeCommand(0b00110011); | |
writeCommand(0b00110010); | |
writeCommand(0b00101000); | |
writeCommand(0x01); | |
/*Turn On Display, Cursor Off*/ | |
writeCommand(0b00001100); | |
/*Cursor Shift in Increment Mode*/ | |
writeCommand(0b00000110); | |
} | |
void i2cInit(void){ | |
TWSR=0x03; //Bit Rate Pre-scaler Is 1:64 | |
TWBR=0x0F; | |
TWCR=(1<<TWEN); //Enable The TWI Module | |
PORTC|=(1<<0); | |
PORTC|=(1<<1); | |
} | |
void i2cStart(void){ | |
TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN); | |
while((TWCR&(1<<TWINT))==0); | |
} | |
void i2cWrite(unsigned char data){ | |
TWDR=data; | |
TWCR=(1<<TWINT)|(1<<TWEN); | |
while((TWCR&(1<<TWINT))==0); | |
} | |
unsigned char i2cRead(char ACK){ | |
if(ACK==0) | |
TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWEA); | |
else | |
TWCR=(1<<TWINT)|(1<<TWEN); | |
while((TWCR&(1<<TWINT))==0); | |
return TWDR; | |
} | |
void i2cStop(){ | |
TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWSTO); | |
} | |
void ds3232Init(void){ | |
i2cStart(); | |
/*D0 is DS1307 Write Address*/ | |
i2cWrite(0xD0); | |
/*Select Control Register*/ | |
i2cWrite(0x0E); | |
/*Enable SQWE bit blinks at 1 Hz*/ | |
i2cWrite(1<<5); | |
i2cStop(); | |
} | |
int main(void) | |
{ | |
char ds3232Data[19],ds3232Datatring[16],dateString[20]; | |
char *dayOfWeek; | |
float temperature,fahrenheit; | |
char signing=0; | |
lcdInit(); | |
i2cInit(); | |
ds3232Init(); | |
while (1) { | |
/*Second Register*/ | |
i2cStart(); | |
i2cWrite(0xD0); | |
/*Select Second register*/ | |
i2cWrite(0x00); | |
i2cStop(); | |
for(int i=0;i<19;i++){ | |
i2cStart(); | |
i2cWrite(0xD1); | |
ds3232Data[i]=i2cRead(1); | |
i2cStop(); | |
} | |
if (ds3232Data[17]&0x80) | |
{ | |
signing=1; | |
ds3232Data[17]=~ds3232Data[17]; | |
ds3232Data[18]=~ds3232Data[18]; | |
temperature=(ds3232Data[17])+1+((ds3232Data[18]>>6)*0.25); | |
} | |
else{ | |
temperature=(ds3232Data[17])+((ds3232Data[18]>>6)*0.25); | |
signing=0; | |
} | |
fahrenheit=(temperature*1.8)+32; | |
/*Find Day Of Week String*/ | |
switch(ds3232Data[3]){ | |
case 1: dayOfWeek="SunDay"; break; | |
case 2: dayOfWeek="Monday"; break; | |
case 3: dayOfWeek="Tuesday"; break; | |
case 4: dayOfWeek="Wednesday"; break; | |
case 5: dayOfWeek="Thursday"; break; | |
case 6: dayOfWeek="Friday"; break; | |
case 7: dayOfWeek="Saturday"; break; | |
default: dayOfWeek=""; break; | |
} | |
/*Make Day Of Week Month Day And Year String*/ | |
sprintf(dateString,"%s %x/%x/20%x ",dayOfWeek,ds3232Data[5],ds3232Data[4],ds3232Data[6]); | |
setXy(0,0); | |
/*Displaying The Date*/ | |
writeString(dateString); | |
/*Make Time: Hour:Minute:Second String*/ | |
sprintf(ds3232Datatring,"Time: %x:%x:%x ",ds3232Data[2],ds3232Data[1],ds3232Data[0]); | |
setXy(1,0); | |
/*Displaying The Time*/ | |
writeString(ds3232Datatring); | |
setXy(2,0); | |
writeString("Device's Temperature"); | |
sprintf(dateString,"%c%0.2f %cC %0.2f %cF ",signing?'-':' ',temperature,223,fahrenheit,223); | |
setXy(3,0); | |
writeString(dateString); | |
/*Waiting For Next Second*/ | |
_delay_ms(1000); | |
} | |
} |
Click here to download the zip file of this example project.
![]() |
Schematic Diagram |
For more tutorial on HD44780 character LCD:
No comments:
Post a Comment