Tuesday, September 1, 2020

ATMega32 Interfaces To DS1307 And Character LCD

Overview

With in the TWI module of Atmega32 MCU, I have already post about interfacing and programming with the DS1307 RTC. However, in the previous post, the display interface was a simple multiplexed 7-segment display. Here, the display is an HD44780-based character LCD.

In this example post, the program read the date/time and day of week from the RTC. Those data will display on a character LCD for every one second.

00:00 / 00:00
ATMega32 Interfaces To DS1307 And Character LCD
A running example program

DS1307 RTC Interfacing And Programming With ATMega32 AVR

DS1307 has a writing address of 0xD0 while the writing address is 0xD1. Its RAM registers store time, date, configuration register and general purpose SRAM registers. The RAM address of 0x00 is the second register and so on. This post store some information about the DS1307.

ATMega32 Interfaces To DS1307 And Character LCD
Schematic

PORTD interfaces to the character LCD. PC0 and PC1 are the TWI clock and data pins, respectively. As we can see, the DS1307 TWI device doesn't need its two pull up resistors. Setting PC0 and PC1 high by software eliminates the requirement of external resistors.
/*
* ds1307Lcd.c
*
* Created: 9/1/2020 9:47:37 PM
* Author : aki-technical
*/
#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;
//Turn On PC0 And PC1
PORTC=0x03;
}
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 ds1307Init(void){
i2cStart();
/*D0 is DS1307 Write Address*/
i2cWrite(0xD0);
/*Select Control Register*/
i2cWrite(0x07);
/*Enable SQWE bit blinks at 1 Hz*/
i2cWrite(1<<4);
i2cStop();
}
int main(void)
{
char times[7],timeString[16],dateString[16];
char *dayOfWeek;
lcdInit();
i2cInit();
ds1307Init();
while (1) {
/*Second Register*/
i2cStart();
i2cWrite(0xD0);
/*Select Second register*/
i2cWrite(0x00);
i2cStop();
for(int i=0;i<7;i++){
i2cStart();
i2cWrite(0xD1);
times[i]=i2cRead(1);
i2cStop();
}
/*Find Day Of Week String*/
switch(times[3]){
case 1: dayOfWeek="Sun"; break;
case 2: dayOfWeek="Mon"; break;
case 3: dayOfWeek="Tue"; break;
case 4: dayOfWeek="Wed"; break;
case 5: dayOfWeek="Thu"; break;
case 6: dayOfWeek="Fri"; break;
case 7: dayOfWeek="Sat"; break;
default: dayOfWeek=""; break;
}
/*Make Day Of Week Month Day And Year String*/
sprintf(dateString,"%s %x/%x/20%x ",dayOfWeek,times[5],times[4],times[6]);
setXy(0,0);
/*Displaying The Date*/
writeString(dateString);
/*Make Time: Hour:Minute:Second String*/
sprintf(timeString,"Time: %x:%x:%x ",times[2],times[1],times[0]);
setXy(1,0);
/*Displaying The Time*/
writeString(timeString);
/*Waiting For Next Second*/
_delay_ms(1000);
}
}
view raw ds1307Lcd.c hosted with ❤ by GitHub


Click here to download the archive of this example.

For more tutorial on HD44780 character LCD:

No comments:

Post a Comment

Search This Blog

Labels

25AA010A (1) 8051 (7) 93AA46B (1) ADC (30) Analog Comparator (1) Arduino (15) ARM (6) AT89C52 (7) ATMega32 (56) AVR (57) CCS PICC (28) DAC (1) DHT11 (2) Display (105) Distance Sensor (3) DS18B20 (3) dsPIC (2) dsPIC30F1010 (2) EEPROM (5) Environment Sensor (4) esp8266 (1) I2C (29) Input/Output (67) Interrupt (19) Keil (5) Keypad (10) LCD (47) Master/Slave (1) MAX7221 (1) MCP23017 (5) MCP23S17 (4) Meter (3) MikroC (2) Motor (15) MPLABX (71) Nokia 5110 LCD (3) OLED (2) One-Wire (6) Oscillator (8) PCB (6) PCD8544 (3) PCF8574 (5) PIC (107) PIC12F (2) PIC16F628A (2) PIC16F630 (1) PIC16F716 (3) PIC16F818 (10) PIC16F818/819 (2) PIC16F84A (15) PIC16F876A (1) PIC16F877A (9) PIC16F88 (1) PIC16F887 (60) PIC18 (19) PIC18F1220 (4) PIC18F2550 (3) PIC18F4550 (12) PWM (11) RTC (8) Sensor (10) SH1106 (1) Shift Register (11) Shift Registers (3) SPI (24) STM32 (6) STM32 Blue Pill (6) STM32CubeIDE (6) STM32F103C8T6 (6) SysTick (3) temperature sensor (11) Thermometer (21) Timer/Counter (31) TM1637 (2) UART (7) Ultrasonic (4) Voltmeter (7) WDT (1) XC16 (2) XC8 (94)