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

2020-02-09 09:16发布

为什么我的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[7]; //定义读取时间和日期存放表格
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();
void  delay()                //延时程序
{
     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[0]=table1[3];      
          table1[1]=table1[4];
          table1[2]=table1[6];
}*/
/* i=table1[0]&0x0f; //保留秒的数据
PORTC=table2; //送C口显示
PORTA=0x1f; //0001 1111点亮秒的个位
delay();
i=i>>4; //右移4位
PORTC=table2; //送C口显示
PORTA=0x2f; //0010 1111点亮秒的十位
delay();*/

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

    i=table1[2]&0x0f;            //求时的个位
    PORTC=table2&0x7f;        //送C口显示,并加上小数点
    PORTA=0x3D;                  //0011 1101点亮时的个位
    delay();                     //延时一定时间,保证亮度
    i=table1[2]&0xf0;            //求时的十位
    i=i>>4;     
    PORTC=table2;             //送C口显示
    PORTA=0x3E;                  //0011 1110点亮时的十位
    delay();                     //延长一段时间,保证亮度
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
3条回答
rkfch
1楼-- · 2020-02-09 12:55
上电后,延时不要低于1S,然后才去操作DS1302.

(原文件名:QQ截图未命名.png)
y123
2楼-- · 2020-02-09 17:41

(原文件名:QQ截图未命名.jpg)

我是用的标准的6PF,并且我也去掉电容试过,都不起振。

并且我在最初化时,我已使能了振荡位的啊?

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); //发控制命令到写寄存器并且写禁止
surf_131
3楼-- · 2020-02-09 22:18
找个采用ds1302的运行正常的开发板,将你的ds1302换上,确认芯片是好的。然后再说程序问题。

国产劣质芯片据说有些就是不起振。

一周热门 更多>