panda1985 发表于 2010-2-25 17:38:50

DS1302程序读不出数据SPI通信,帮忙看一下那地方不对呢?

#include <iom16v.h>
#include <macros.h>

#define uint unsigned int
#define uchar unsigned char
#define RS_0 PORTD&0xfe
#define RS_1 PORTD|0x01
#define E_0PORTD&0xfd
#define E_1PORTD|0x02
#define RW_0 PORTD&0xfb
#define RW_1 PORTD|0x04

/*读写控制*/
#define cmd_read           0x01
#define cmd_write           0x00

/*时钟日期命令*/
#define cmd_second           0x80
#define cmd_minute           0x82
#define cmd_hour           0x84
#define cmd_day                   0x86
#define cmd_month           0x88
#define cmd_week           0x8a
#define cmd_year           0x8c
#define cmd_control           0x8e   
                                                 //写保护
#define cmd_trickle_charge0x90
                                          //充电控制
#define cmd_clocl_burst                0xbe
                                           //连续写
/*时钟配置位*/
#define clock_halt                0x80
#define _12-24_slect                0x80
#define AM_PM_slect                0x20
#define protect                        0x80
#define unprotect                0x00   

/*充电控制*/
#define CFG_TC_D1R2                        0xA5        //high 1 Diode +2K Resistors
#define CFG_TC_D2R8                        0xAB        //low2 Diodes+8K Resistors
#define CFG_TC_DISABLED                0x00        //Disabled(TCS<>1010 or DS=00 or RS=00

/*RAM命令*/
#define cmd_RAM_base                0xc0
#define cmd_RAM_burst                0xfe


/*管脚定义*/
#define CE                                        4
#define MOSI                                 5
#define MISO                                6
#define SCK                                        7

#define DS1302_ON      PORTB|=(1<<4)   
                                                  //使能DS1302
#define DS1302_OFF               PORTB&=~(1<<4)
                                                  //关闭DS1302
                                                                       

uchar CURDATE;
uchar Timer={0,0};
uchar DS1302_EXIST;
uchar table={0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f};
uchar DATA={0,0,0,0};

uchar init_data={0x50,0x59,0x23,0x06,0x10,0x04,0x05,0x80};
/*************************************************************************************/
void delay(uint ms)
{
uint i,j;
for(i=0;i<ms;i++)
   {
   for(j=1141;j!=0;j--)
           {;}
   }
}
/****************************************************************************************/

void init_SPI(void)                              //初始化SPI
{
SPCR=(1<<SPIE)|(1<<MSTR)|(1<<DORD)|(1<<SPR0);
}

/****************************************************************************************/
uchar Write_data_DS1302(uchar command,uchar wdata)//<------向DS1302读写数据
{
uchar rdata;
DS1302_ON;
delay(10);
SPDR=command;
while(!(SPSR&(1<<SPIF)));
delay(10);
SPDR=wdata;
while(!(SPSR&(1<<SPIF)));
rdata=SPDR;
DS1302_OFF;
return rdata;
}
/*******************************************************************************************/
void Burst_data(uchar CMD,uchar len,uchar *pwdata,uchar *prdata)   //<-----读写一批数据到DS1302
{
DS1302_ON;
delay(10);
SPDR=CMD;
while(!(SPSR&(1<<SPIF)));
delay(10);
while(len--)
   {
   SPDR=*pwdata++;
       while(!(SPSR&(1<<SPIF)));
       *prdata++=SPDR;
   }
DS1302_OFF;
delay(10);
}
/************************************************************************************/
uchar check_RTC(void)          //<---------------检测DS1302
{
uchar i;
Write_data_DS1302(cmd_control|cmd_write,unprotect);
Write_data_DS1302(cmd_RAM_base|cmd_write,0xA5);
Write_data_DS1302(cmd_control|cmd_write,protect);
i=Write_data_DS1302(cmd_RAM_base|cmd_read,0x00);
if(i==0xA5)return 1;
else return 0;
}
/***************************************************************************************/
void init_RTC(void)   //<----------------初始化DS1302
{
uchar temp;
Write_data_DS1302(cmd_control|cmd_write,unprotect);
Burst_data(cmd_clocl_burst|cmd_write,8,&init_data,&temp);
Write_data_DS1302(cmd_trickle_charge|cmd_write,0xA5);
Write_data_DS1302(cmd_control|cmd_write,protect);
}

/**************************************************************************************/
void BCD_to_ASCII(uchar cBCD,uchar *pstr)
{
uchar i,j;
i=cBCD>>4;
j=cBCD&0x0f;
*pstr++=i+0x30;
*pstr=j+0x30;
}
/*************************************************************************************
void decodeWEEK(uchar WEEK,uchar *pstr)
{
uchar i;
i=WEEK;
i&=0x07;
i=i<<1;
*pstr++=sWEEK;
*pstr=sWEEK;
}
/*****************************************************************************/
void read_date(void)
{
        Burst_data(cmd_clocl_burst|cmd_read,7,0,CURDATE);        //读取当前时间
                                                                                      
        BCD_to_ASCII(CURDATE,&Timer);                      //分 ,00~59
        BCD_to_ASCII(CURDATE,&Timer);                                        //秒 ,00~59       
}

void display(uchar *p)
{
uchar i;
uchar sel=0x01;
for(i=0;i<4;i++)
{
    PORTC=sel;
    PORTD=table];
        delay(2);
        sel=sel<<1;
}
}
/**************************************************************************************/
void process(uchar *p1,uchar *p2)
{
p2=p1/10;
p2=p1%10;
p2=p1/10;
p2=p1%10;
}

/****************************************************************************************/
void main(void)
{
DDRC=0xff;
PORTC=0xff;
DDRD=0xff;
PORTD=0xff;
DDRB =(1<<4)|(1<<7)|(1<<6);
PORTB=~((1<<4)|(1<<5)|(1<<6)|(1<<7));
init_SPI();
delay(100);
init_RTC();
delay(500);
while(1)
{
    read_date();
        process(Timer,DATA);
        display(DATA);
}
}

voidx 发表于 2010-2-25 17:59:22

DS1302不是SPI。

panda1985 发表于 2010-2-25 18:16:46

DS1302不可以用SPI方式通讯吗?不会吧?
http://cache.amobbs.com/bbs_upload782111/files_27/ourdev_535286.jpg
原理图 (原文件名:TP

Jigsaw 发表于 2010-2-25 19:41:19

第一次看到这么接SPI的
ds1302是用IO口模拟的通信时序,记得时序和SPI还是有区别的
SPI是数据进出各一条线,再加一条时钟线,单向传输
而1302的数据口是双向的

楼主打电话或发个电邮问一下这家公司吧,让我们都长点知识。呵呵,开个玩笑。

建议楼主看一看这家公司的配套源码,或者看清楚DS1302的Datasheet

yunlong 发表于 2010-2-25 20:40:17

从DS1302的时序上说,用SPI是可以的。
建议LZ检查一下3点;
1 把SPI的分频调到最大,因为1302的对数据的稳定时间要求是比较长的。
2 把1302到AVR的数据线弄的尽可能短些。
3 从1302读取数据的时候SPI的SPDR应该装入0XFF;
同问LZ这样接线有什么好处吗?
为什么不用模拟的时序?这样还省下一个IO.

yunqian09 发表于 2010-2-25 20:44:36

回复【3楼】Jigsaw
-----------------------------------------------------------------------

原理图没问题之前做过

Jigsaw 发表于 2010-2-25 22:14:11

5楼可以把自己用过的SPI源码贴给楼主

从SPI的时序来说,这样读写是可以理解的。
之前是自己对SPI的细节没弄清楚,MISO时同样是下降沿采样,以为都是下降沿采样。

为自己的错误向楼主致歉!

yunqian09 发表于 2010-2-25 22:57:17

http://hi.baidu.com/282280072/blog/item/b5dd7da0d73ff88146106473.html

DS1302 SPI接口,proteus,虚拟终端显示

参考下吧好久了

panda1985 发表于 2010-2-26 14:15:04

多谢各位老师指导我现在改成用IO口模拟方式了,调试通过了,谢了

walton 发表于 2011-5-10 23:01:39

回复【8楼】panda1985 盼盼
-----------------------------------------------------------------------

我用GCCAVR作的SPI口可以对DS1302进行读和写操作,但好像是单工的。

millwood0 发表于 2011-5-11 05:01:12

ds1302 is spi, except that its slave select is active high, vs. active low for "standard" spi.

ljmdzyx 发表于 2011-10-12 23:34:55

MARK

YISIMA 发表于 2013-2-27 22:18:16

mark~~~~~~~~~~~~~~~

ymhemcu 发表于 2013-2-28 08:47:15

和DS1302之间的通讯,我也正在头痛中
页: [1]
查看完整版本: DS1302程序读不出数据SPI通信,帮忙看一下那地方不对呢?