打印
[Atmel]

用AtmelStudio6.2跑mega16例程(64)DS1302时钟芯片

[复制链接]
1492|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
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]);
}




相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:http://shop34182318.taobao.com/ http://shop562064536.taobao.com

2398

主题

6955

帖子

67

粉丝