搜索
bottom↓
回复: 13

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

[复制链接]

出0入0汤圆

发表于 2010-2-25 17:38:50 | 显示全部楼层 |阅读模式
#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_0  PORTD&0xfd
#define E_1  PORTD|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_charge  0x90
                                            //充电控制
#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        //low  2 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[7];
uchar Timer[2]={0,0};
uchar DS1302_EXIST;
uchar table[10]={0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f};
uchar DATA[4]={0,0,0,0};

uchar init_data[8]={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[8];
  Write_data_DS1302(cmd_control|cmd_write,unprotect);
  Burst_data(cmd_clocl_burst|cmd_write,8,&init_data[0],&temp[0]);
  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[i++];
  *pstr=sWEEK;
}
/*****************************************************************************/
void read_date(void)
{
        Burst_data(cmd_clocl_burst|cmd_read,7,0,CURDATE);        //读取当前时间
                                                                                        
        BCD_to_ASCII(CURDATE[0],&Timer[0]);                        //分 ,00~59
        BCD_to_ASCII(CURDATE[1],&Timer[1]);                                        //秒 ,00~59       
}

void display(uchar *p)
{
  uchar i;
  uchar sel=0x01;
  for(i=0;i<4;i++)
  {
    PORTC=sel;
    PORTD=table[p];
        delay(2);
        sel=sel<<1;
  }
}
/**************************************************************************************/
void process(uchar *p1,uchar *p2)
{
  p2[0]=p1[0]/10;
  p2[1]=p1[0]%10;
  p2[2]=p1[1]/10;
  p2[3]=p1[1]%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);
  }
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2010-2-25 17:59:22 | 显示全部楼层
DS1302不是SPI。

出0入0汤圆

 楼主| 发表于 2010-2-25 18:16:46 | 显示全部楼层
DS1302不可以用SPI方式通讯吗?不会吧?

原理图 (原文件名:TP[S_7BM8[G(07FFQJIDIAJ.jpg)

出0入0汤圆

发表于 2010-2-25 19:41:19 | 显示全部楼层
第一次看到这么接SPI的
ds1302是用IO口模拟的通信时序,记得时序和SPI还是有区别的
SPI是数据进出各一条线,再加一条时钟线,单向传输
而1302的数据口是双向的

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

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

出0入0汤圆

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

出0入0汤圆

发表于 2010-2-25 20:44:36 | 显示全部楼层
回复【3楼】Jigsaw  
-----------------------------------------------------------------------

原理图没问题  之前做过

出0入0汤圆

发表于 2010-2-25 22:14:11 | 显示全部楼层
5楼可以把自己用过的SPI源码贴给楼主

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

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

出0入0汤圆

发表于 2010-2-25 22:57:17 | 显示全部楼层
http://hi.baidu.com/282280072/blog/item/b5dd7da0d73ff88146106473.html

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

参考下吧  好久了

出0入0汤圆

 楼主| 发表于 2010-2-26 14:15:04 | 显示全部楼层
多谢各位老师指导  我现在改成用IO口模拟方式了,调试通过了,谢了

出0入0汤圆

发表于 2011-5-10 23:01:39 | 显示全部楼层
回复【8楼】panda1985 盼盼
-----------------------------------------------------------------------

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

出0入0汤圆

发表于 2011-5-11 05:01:12 | 显示全部楼层
ds1302 is spi, except that its slave select is active high, vs. active low for "standard" spi.

出0入0汤圆

发表于 2011-10-12 23:34:55 | 显示全部楼层
MARK

出0入0汤圆

发表于 2013-2-27 22:18:16 | 显示全部楼层
mark~~~~~~~~~~~~~~~

出0入0汤圆

发表于 2013-2-28 08:47:15 | 显示全部楼层
和DS1302之间的通讯,我也正在头痛中
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-24 05:23

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表