DOCX

ATMEGA 16

By Beth Simpson,2014-05-12 10:00
7 views 0
ATMEGA 16

    DS1302是一款常用的实时时钟芯片,该芯片时钟功能强大,具有备用电池涓流充电功能.确保时钟正常稳定地工作.本例程利用ATmega16单片机的同步串行通信功能SPIDS1302完成一个电子时钟的功能.显示部分用LCD12864模块.源代码如下:

    #include <iom16v.h>

    #include <macros.h>

    #include "12864.c"

    #define uchar unsigned char

    #define uint unsigned int

    #define spi_close SPCR&=~(1<<SPE); #pragma data:code

    const char num[]={'0','1','2','3','4','5','6','7','8','9'};

    const uchar sWEEK[]="Wr 1 2 3 4 5 6Su"; uchar CURRDATE[7];

    void init_spi(void);

    uchar com(uchar dat);

    uchar write1302(uchar addr,uchar dat); uchar read1302(uchar addr);

    void Burst1302(uchar cmd,uchar len,uchar *wdat,uchar *rdat);

    void BCDtoASCII(unsigned char cBCD,unsigned char *pstr);

    void decodeWEEK(unsigned char WEEK,unsigned char *pstr);

    void read_date(char *s_cur_date); void init1302(uchar *ptr);

    void main()

    {

    uchar sCURDATE[]="20xxYYxxMMxxDDxxHHxxmmxxSS Weekxx";

    uchar INITDATE[8]={0x35, //

     0x26, //

     0x21, // 24小时制

     0x08, //

     0x03, //

     0x07, //星期

     0x09, //

     0x80 //写保护

     };

    /*uchar dis_buf[2][17] =

    {

    {"2008/08/08 0.00V\0"},

    {"08:08:08 00.0^C\0"},

    };*/

    uchar dis_buf[4][17] =

    {

{"20080808\0"},

    {"时间: 08:08:08\0"},

    {" 星期 0 \0"},

    {" 室温:00.0^C \0"},

    };

    init_spi();

    //init1302(INITDATE); //DS1302数据.

    while(1)

    {

    init_spi();

    delayus(1);

    read_date(sCURDATE);

    /******************/

    dis_buf[0][0] = sCURDATE[0]; dis_buf[0][1] = sCURDATE[1]; dis_buf[0][2] = sCURDATE[2]; dis_buf[0][3] = sCURDATE[3]; /******************/

    dis_buf[0][6] = sCURDATE[6]; dis_buf[0][7] = sCURDATE[7]; /******************/

    dis_buf[0][10] = sCURDATE[10]; dis_buf[0][11] = sCURDATE[11];

     /******************/

    dis_buf[1][6] = sCURDATE[14]; dis_buf[1][7] = sCURDATE[15]; /******************/

    dis_buf[1][9] = sCURDATE[18]; dis_buf[1][10] = sCURDATE[19];

     /******************/

    dis_buf[1][12] = sCURDATE[22]; dis_buf[1][13] = sCURDATE[23]; /*******星期*********/

    dis_buf[2][8] = sCURDATE[31]; dis_buf[2][9] = sCURDATE[32]; spi_close; //SPI功能.

     initlcd(); //初始化LCD12864.

     dispchar(0x80,dis_buf[0]); dispchar(0x90,dis_buf[1]); dispchar(0x88,dis_buf[2]); dispchar(0x98,dis_buf[3]); delay(200);

    }

    }

void init_spi()

    {

     PORTB|=1<<PB4;

    PORTA&=~(1<<PA1); //RESET清零,DS1302; DDRA|=1<<PA1;

    DDRB|=(1<<PB4)|(1<<PB5)|(1<<PB7);

    DDRB&=~(1<<PB6); //MISO设为输入模式. SPCR=(1<<SPE)|(1<<DORD)|(1<<MSTR)|(1<<SPR0);//|(1<<SPR0);

    //开启SPI,低位在前,主机,模式0,16分频. }

    void init1302(uchar *ptr) {

     uchar temp[8];

    PORTA&=1<<PA1; //Reset清零. DDRA|=1<<PA1;

    write1302(0x8e,0x00); //写允许 Burst1302(0xbe,8,ptr,&temp[0]); //初始化时间 write1302(0x90,0xa5); //涓流充电选择 write1302(0x8e,0x80); //写保护 }

    uchar com(uchar dat) {

     SPDR=dat;

     while(!(SPSR&0x80)); return SPDR;

    }

    uchar write1302(uchar addr,uchar dat)

    {

     uchar temp;

     PORTA|=1<<PA1;

    DDRA|=1<<PA1;

    delayus(1);

    com(addr);

    delayus(1);

    temp=com(dat);

    delayus(1);

    PORTA&=~(1<<PA1);

    delayus(1);

    return temp;

    }

uchar read1302(uchar addr)

    {

     uchar temp;

     PORTA|=1<<PA1;

     DDRA|=1<<PA1; delayus(1);

    temp=com(addr); delayus(1);

    PORTA&=~(1<<PA1); return temp;

    }

    void Burst1302(uchar cmd,uchar len,uchar *wdat,uchar *rdat)

    {

     PORTA|=1<<PA1; DDRA|=1<<PA1;

    delayus(1);

    com(cmd);

    delayus(1);

    while(len--)

    {

     *rdat++=com(*wdat++);

    }

    PORTA&=~(1<<PA1); delayus(1);

    }

    //压缩BCD码转换成ASCII

    void BCDtoASCII(unsigned char cBCD,unsigned char *pstr)

    {

    unsigned char i,j; i=cBCD>>4;

    j=cBCD&0x0F;

    *pstr++=i+0x30; *pstr=j+0x30;

    }

    //BCD0~7转换成汉字''~'' void decodeWEEK(unsigned char WEEK,unsigned char *pstr)

    {

    unsigned char i; i=WEEK;

    i&=0x07;

    i=i<<1;

    *pstr++=sWEEK[i++];

*pstr=sWEEK[i];

    }

    //读取当前时间并解释

    void read_date(char *s_cur_date) {

    Burst1302(0xBF,7,0,CURRDATE); //读取当前时间

     // ;00~10 BCDtoASCII(CURRDATE[6],s_cur_date + 2);

    BCDtoASCII(CURRDATE[4],s_cur_date + 6); // ;01~12 BCDtoASCII(CURRDATE[3],s_cur_date + 10); // ;01~31(28/30/31)

    BCDtoASCII(CURRDATE[2],s_cur_date + 14); // ;00~23 BCDtoASCII(CURRDATE[1],s_cur_date + 18); // ;00~59 BCDtoASCII(CURRDATE[0],s_cur_date + 22); // ;00~59 decodeWEEK(CURRDATE[5],s_cur_date + 31); //星期 ;1~7 ~ }

Report this document

For any questions or suggestions please email
cust-service@docsford.com