y123 发表于 2011-5-11 14:08:06

为什么我的DS1302没有反应呢?

为什么我的DS1302没有反应呢?测试其时钟振荡位也没有看到波形。程序如下:

#include<pic.h>
#define rst RB3//将RB3定义为复位引脚
#define i_o RB4//将RB4定义为数据传送引脚
#define sclk RB5 //将RB5定义为时钟引脚
__CONFIG(0xE739);
unsigned char time_rx @ 0x30;                                        //定义接收寄存器
static volatile bit time_rx7 @ (unsigned)&time_rx*8+7;\
                                                                                                //定义接收寄存器的最高位
char table1;                                                                        //定义读取时间和日期存放表格
void port_init();                                                                //端口初始化
void Ds1302Init();                                                                //DS1302初始化
void w_addr_data(unsigned char add,unsigned char data);                //写地址\数据函数
void writebyte(unsigned char dat);                                //写入1字节数据函数
unsigned char readds1302(unsigned char addr);        //读取DS1302里面的数据
unsigned char readbyte();                                                //申明一个带参数返回的读字节
const char table[]={0x00,0x30,0x12,0x8,0x32,0x06,0x06,0x00};
                                                                                                //定义待设置的时间:秒、分、时、日、月、星期、年、控制字
const char table2[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,
                                       0x88,0x83,0xC6,0xA1,0x86,0x8E};
                                                                  //共阳数码管代码

void set_time();                                        //设置时间函数
void get_time();
void display();
voiddelay()                               //延时程序
{
            int i;                            //定义整形变量
            for(i=100;i--;);                    //延时
}

void main()
{
        port_init();                                        //端口初始化函数
        Ds1302Init();                                        //DS1302初始化
        set_time();                                                //调用设置时间函数
        while(1)
        {
                get_time();                                        //调用取时间函数
                display();                                        //调用显示函数
        }
}
void port_init()
{
        ADCON1=0x06;                                        //A口为普通数据口
        TRISA=0x00;                             //设置A口全输出
         TRISB=0X00;                                 //设置B口全输出
        TRISC=0x00;                                                //设置C口全输出
        PORTA=0xff;                                                //暂时熄灭所有输出口
        PORTB=0;                                               
        PORTC=0;
}
void Ds1302Init()                                        //DS1302初始化
{
//        unsigned char code;
//        code=readds1302(0x80);                        //检测DS1302是否起振
//        if((code&0x80)==0)                                //如果未振荡,程序执行if里面的语句
//        {
                w_addr_data(0x8e,0x00);                //发控制命令到写寄存器并且写使能
                w_addr_data(0x8c,0x10);                //发控制命令到年寄存器并设初置
                w_addr_data(0x88,0x11);                //发控制命令到月寄存器并设初置
                w_addr_data(0x86,0x01);                //发控制命令到日寄存器并设初置
                w_addr_data(0x84,0x12);                //发控制命令到时寄存器并设初置
                w_addr_data(0x82,0x00);                //发控制命令到分寄存器并设初置
                w_addr_data(0x80,0x00);                //发控制命令到秒寄存器并设初置
                w_addr_data(0x8e,0x80);                //发控制命令到写寄存器并且写禁止
//        }
}
unsigned char readds1302(unsigned char addr)//读取DS1302里面的数据
{
        unsigned char ds1302data;                        //定义返回函数寄存器
        rst=0;
        sclk=0;
        rst=1;
        writebyte(addr);                                        //调用写字节函数,写入地址
        ds1302data=readbyte();                                //读取的1字节值存入寄存器
        sclk=1;                                                                //上升沿发送数据
        rst=0;
        return(ds1302data);                                        //返回读到的值
}
unsigned char readbyte()
{
        unsigned char j;
        TRISB4=1;                                                //设置数据口方向为输入
        for(j=0;j<8;j++)                                //连续读8位
        {
                sclk=0;                                                //拉低时钟信号下降沿接收数据
                time_rx=time_rx>>1;                        //接收寄存器右移1位
                time_rx7=i_o;                                //把接收到的数据放到接收寄存器的最高位
                sclk=1;                                                //拉高时钟信号
        }
        TRISB4=0;                                          //恢复数据口方向为输出
        sclk=0;                                                        //拉低时钟信号
        return(time_rx);                                //返回读取到的数据
}
void w_addr_data(unsigned char add,unsigned char data)//写地址\数据函数
{
        rst=0;                                                        //复位,为rst置1做准备,rst必须置高DS1302才能有效
        sclk=0;                                                        //为时钟的上升沿做准备,在上升沿时对DS1302写入数据,只有在sclk为低电平时,才能将rst置为高电平
        rst=1;                                                        //使能DS1302,在进行任何数据的传输时,rst必须被置高电平
        writebyte(add);                                //写入地址
        writebyte(data);                                //写入命令控制数据
        sclk=1;                                                        //上升沿发送数据
        rst=0;       
}
void writebyte(unsigned char dat)        //写入1字节数据函数
{
        unsigned char j;
        for(j=0;j<8;j++)                                //连续写8次(一个字节)
        {
                i_o=0;                                                //将数据线拉低
                if(dat&0x01)                                //判断待发送的数据位是0或1
                {
                        i_o=1;                                        //判断为1,发送数据1
                }
                dat=dat>>1;                                        //待发送数据右移1位
                sclk=1;                                                //拉高时钟信号,在时钟的上升沿传送数据,传送一位数据
        }
        sclk=0;                                                        //写完一个字节,拉低时钟信号
}
void set_time()
{
        unsigned char i;
        rst=1;                                                        //使能DS1302
        writebyte(0xbe);                                //时钟多字节写命令,突发模式
        for(i=0;i<8;i++)                                //连续写8个字节数据
        {
                writebyte(table);                //调用写一个字节函数
                delay();
        }
        rst=0;                                                        //复位
}
void get_time()
{
        int i;
        rst=1;                                                        //使能DS1302
        writebyte(0xbf);                                //发送多字节读取命令,突发模式
        for(i=0;i<7;i++)                                //连续读取7个字节
        {
                table1=readbyte();                //调用读取1个字节函数
                delay();
        }
        rst=0;                                                        //复位
}

void display()
{
        int i;
/*        if(RB0==0)                                                //判断RB0是否按下,如果按下显示日期,否则显示时间
        {
table1=table1;   
          table1=table1;
          table1=table1;       
        }*/
/*        i=table1&0x0f;                                //保留秒的数据
        PORTC=table2;                                //送C口显示
        PORTA=0x1f;                                                //0001 1111点亮秒的个位
        delay();
        i=i>>4;                                                        //右移4位
        PORTC=table2;                                //送C口显示
        PORTA=0x2f;                                                //0010 1111点亮秒的十位
        delay();*/

        i=table1&0x0f;                     //求分的个位
    PORTC=table2&0x7f;               //送C口显示,并显示小数点
    PORTA=0x37;                       //0011 0111点亮分的个位
    delay();                          //延时一定时间,保证亮度
           i=table1&0xf0;                 //求分的十位
           i=i>>4;               
           PORTC=table2;                    //送C口显示
           PORTA=0x3B;                       //0011 1011点亮分的十位
           delay();                          //延长一段时间,保证亮度

           i=table1&0x0f;                 //求时的个位
           PORTC=table2&0x7f;               //送C口显示,并加上小数点
           PORTA=0x3D;                       //0011 1101点亮时的个位
           delay();                          //延时一定时间,保证亮度
           i=table1&0xf0;                 //求时的十位
           i=i>>4;   
           PORTC=table2;                    //送C口显示
           PORTA=0x3E;                       //0011 1110点亮时的十位
           delay();                          //延长一段时间,保证亮度
页: [1]
查看完整版本: 为什么我的DS1302没有反应呢?