DS1302是DALLAS公司推出的一种高性能、低功耗、带RAM的实时时钟芯片,它可以对年、月、日、周、时、分、秒进行计时,具有闰年补偿功能,最大有效年分可达2100年。
本例运行时,每隔0.5s读取DS1302实时是钏芯片时间数据,通过格式转换后显示在1602LCD上
Proteus运行时截图:
Atmel Studio6.2编译通过的截图:
程序清单:
主程序:
/*
* GccApplication27.c
*
* Created: 2014-12-4 18:47:28
* Author: Administrator
*/
#define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <string.h>
#include <stdio.h>
#include <stdint.h>
extern void Initialize_LCD();
extern void LCD_ShowString(uint8_t x,uint8_t y,char *str);
extern void GetDateTime();
extern uint8_t DateTime[];
extern char *WEEK[];
char LCD_DSY_BUFFER[17];
int main()
{
DDRA = 0xFF;
DDRC = 0xFF;
DDRD = 0xFF;
Initialize_LCD();
while(1)
{
GetDateTime();
//按格式:“DATA 00 - 00 - 00XX”显示年月日与星期
sprintf(LCD_DSY_BUFFER,"DATE %02d - %02d - %02d%3s ",DateTime[6],DateTime[4],DateTime[3],WEEK[DateTime[5]-1]);
LCD_ShowString(0,0,LCD_DSY_BUFFER);
sprintf(LCD_DSY_BUFFER,"TIME %02d:% 02d:% 02d",DateTime[2],DateTime[1],DateTime[0]);
LCD_ShowString(0,1,LCD_DSY_BUFFER);
_delay_ms(100);
}
}
时钟程序:
#define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <stdint.h>
//DS1302引脚定义
#define IO PA0
#define SCLK PA1
#define RST PA2
//DS1302 端口定义
#define DS_PORT PORTA
#define DS_DDR DDRA
#define DS_PIN PINA
//DS1302端口数据读/写(方向)
#define DDR_IO_RD() DS_DDR &= ~_BV(IO)
#define DDR_IO_WR() DS_DDR |= _BV(IO)
//DS1302 控制引脚操作定义
#define WR_IO_0() DS_PORT &= ~_BV(IO)
#define WR_IO_1() DS_PORT |= _BV(IO)
#define RD_IO() (DS_PIN & _BV(IO))
#define SCLK_1() DS_PORT |= _BV(SCLK)
#define SCLK_0() DS_PORT &=~_BV(SCLK)
#define RST_1() DS_PORT |= _BV(RST)
#define RST_0() DS_PORT&=~_BV(RST)
char * WEEK[] = {"SUN","MON","TUS","WEN","THU","FRI","SAT"};
uint8_t DateTime[7];
void Write_Byte_TO_DS1302(uint8_t x)
{
uint8_t i;
DDR_IO_WR();
for(i=0x01;i !=0x00;i<<=1)
{
if(x & i)WR_IO_1();else WR_IO_0();SCLK_0();SCLK_1();
}
}
uint8_t Get_Byte_FROM_DS1302()
{
uint8_t i,dat = 0x00;
DDR_IO_RD();
for(i=0;i<8;i++)
{
SCLK_1();SCLK_0();if (RD_IO()) dat |= _BV(i);
}
return dat/16*10 + dat % 16;
}
uint8_t Read_Data(uint8_t addr)
{
uint8_t dat;
RST_1();
Write_Byte_TO_DS1302(addr);
dat = Get_Byte_FROM_DS1302();
RST_0();
return dat;
}
void GetDateTime()
{
uint8_t i,addr = 0x81;
for(i = 0;i<7;i++)
{
DateTime[i] = Read_Data(addr);
addr + = 2;
}
}
LCD显示程序:
/*
* GccApplication26.c
*
* Created: 2014-12-2 20:34:45
* Author: Administrator
*/
#define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <stdint.h>
#define RS PD0
#define RW PD1
#define E PD2
#define LCD_CRTL_PORT PORTD
#define LCD_PORT PORTC
#define LCD_PIN PINC
#define LCD_DDR DDRC
#define RS_1() LCD_CRTL_PORT|=_BV(RS)
#define RS_0() LCD_CRTL_PORT&=~_BV(RS)
#define RW_1() LCD_CRTL_PORT|=_BV(RW)
#define RW_0() LCD_CRTL_PORT&=~_BV(RW)
#define EN_1() LCD_CRTL_PORT|=_BV(E)
#define EN_0() LCD_CRTL_PORT&=~_BV(E)
void LCD_BUSY_WAIT()
{
RS_0(); RW_1();
LCD_DDR = 0x00;
EN_1(); _delay_us(20);
//loop_until_bit_is_clear(LCD_PIN,7);
EN_0();
LCD_DDR = 0xFF;
}
void Write_LCD_Command(uint8_t cmd)
{
LCD_BUSY_WAIT();
RS_0(); RW_0();
LCD_PORT = cmd;
EN_1(); EN_0();
}
void Write_LCD_Data(uint8_t dat)
{
LCD_BUSY_WAIT();
RS_1(); RW_0();
LCD_PORT = dat;
EN_1(); EN_0();
}
void Initialize_LCD()
{
Write_LCD_Command(0x38);_delay_ms(15);
Write_LCD_Command(0x01);_delay_ms(15);
Write_LCD_Command(0x06);_delay_ms(15);
Write_LCD_Command(0x0c);_delay_ms(15);
}
void LCD_ShowString(uint8_t x,uint8_t y,char *str)
{
uint8_t i = 0;
if(y == 0)Write_LCD_Command(0x80 | x);
else if(y == 1)Write_LCD_Command(0xC0 | x);
for(i = 0; i<16 && str[i]!='\0';i++)
Write_LCD_Data(str[i]);
}
|