微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > STM32与DS1302接口

STM32与DS1302接口

时间:10-02 整理:3721RD 点击:

    作者在某STM32的应用中外接了一块DS1302,借鉴原来写过的PIC代码,很快移植成功。在这里与大家分享一下。

(1)硬件 CLK PA4  DAT PA5 RST PA6

(2)硬件初始化 CLK与RST均为输出,而DAT是开漏型的输出。因为在这种方式下,IO口的读仍然存在,因此是真正的双向IO模式。

  1. /*DSCK -PA4 DAT PA5 RST DAT*/
  2. #define ds1302Clk GPIO_Pin_4   //与时钟线相连的芯片的管脚
  3. #define ds1302Dat GPIO_Pin_5   //与数据线相连的芯片的管脚
  4. #define ds1302Rst GPIO_Pin_6   //与复位端相连的芯片的管脚
  5. /* PA 4,6,为输出*/
  6. GPIO_InitStructure.GPIO_Pin =  ds1302Clk | ds1302Rst ;
  7.    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  8.    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  9.    GPIO_Init(GPIOA, &GPIO_InitStructure);
  10. //PA5配置为开漏模式,此模式下可以实现真下的双向IO
  11. GPIO_InitStructure.GPIO_Pin =  ds1302Dat;
  12.    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
  13.    GPIO_Init(GPIOA, &GPIO_InitStructure);

复制代码


(3)配置完毕,然后实现的代码就很简单了,从现成的代码移植过来。

  1. #define WrEnDisCmd  0x8e  //写允许/禁止指令代码
  2. #define WrEnDat     0x00 //写允许数据
  3. #define WrDisDat    0x80 //写禁止数据
  4. #define OscEnDisCmd 0x80 //振荡器允许/禁止指令代码
  5. #define OscEnDat    0x00 //振荡器允许数据
  6. #define OscDisDat   0x80 //振荡器禁止数据
  7. #define WrMulti     0xbe //写入多个字节的指令代码
  8. #define WrSingle    0x84 //写入单个字节的指令代码
  9. #define RdMulti  0xbf //读出多个字节的指令代码

复制代码


////以上这些#define均放在一个ds1302.h文件中。

  1. void SendDat_1302(u8 Dat)
  2. { u8 i;
  3. u8 cTmp;
  4. for(i=0;i<8;i++)
  5. {
  6.    cTmp=Dat&LSB; //数据端等于tmp数据的末位值
  7.   if(cTmp)    //1
  8.       GPIO_SetBits(GPIOA,ds1302Dat);
  9.   else
  10.    GPIO_ResetBits(GPIOA,ds1302Dat);
  11.   Dat>>=1;
  12.   GPIO_SetBits(GPIOA,ds1302Clk);
  13.   uDelay(1);
  14.   GPIO_ResetBits(GPIOA,ds1302Clk);
  15. }
  16. }

复制代码


/*写入1个或者多个字节,第1个参数是相关命令
#define WrMulti     0xbe //写入多个字节的指令代码
#define WrSingle    0x84 //写入单个字节的指令代码
第2个参数是待写入的值
第3个参数是待写入数组的指针
*/

  1. void WriteByte_1302(u8 CmdDat,u8 Num,u8 *pSend)
  2. {
  3. u8 i=0;
  4. GPIO_ResetBits(GPIOA,ds1302Rst);
  5. uDelay(1);
  6. GPIO_SetBits(GPIOA,ds1302Rst);
  7. SendDat_1302(CmdDat);
  8. for(i=0;i<Num;i++)
  9. { SendDat_1302(*(pSend+i));
  10. }
  11. GPIO_ResetBits(GPIOA,ds1302Rst);
  12. }

复制代码


/*读出字节,第一个参数是命令
#define RdMulti  0xbf //读出多个字节的指令代码
第2个参数是读出的字节数,第3个是指收数据数组指针

  1. */
  2. void RecByte_1302(u8 CmdDat,u8 Num,u8 *pRec)
  3. {
  4. u8 i,j,tmp,cTmp;
  5. GPIO_ResetBits(GPIOA,ds1302Rst);//复位引脚为低电平
  6. uDelay(1);
  7. GPIO_ResetBits(GPIOA,ds1302Clk);
  8. uDelay(1);
  9. GPIO_SetBits(GPIOA,ds1302Rst);
  10. SendDat_1302(CmdDat); //发送命令
  11. for(i=0;i<Num;i++)
  12. { for(j=0;j<8;j++)
  13.   { tmp>>=1;
  14.    cTmp=GPIO_ReadInputDataBit(GPIOA,ds1302Dat);
  15.    if(cTmp)
  16.     tmp|=0x80;
  17.    GPIO_SetBits(GPIOA,ds1302Clk);
  18.    uDelay(1);
  19.    GPIO_ResetBits(GPIOA,ds1302Clk);      
  20.   }
  21.   *(pRec+i)=tmp;
  22. }
  23. uDelay(1);
  24. GPIO_ResetBits(GPIOA,ds1302Rst);//复位引脚为低电平
  25. }
  26. /*

复制代码


当写保护寄存器的最高位为0时,允许数据写入寄存器。
写保护寄存器可以通过命令字节8E、8F来规定禁止写入/读出。写保护位不能在多字节传送模式下写入。
当写保护寄存器的最高位为1时,禁止数据写入寄存器。

时钟停止位操作:当把秒寄存器的第7位时钟停止位设置为0时起动时钟开始
当把秒寄存器的第7位时钟停止位设置为1时,时钟振荡器停止。
   
    根据传入的参数决定相关命令,
第一个参数:命令字,第2个参数:写入的数据
写允许命令;8EH,00H
写禁止命令;8EH,80H
振荡器允许命令;80H,00H
振荡器禁止命令;80H,80H

  1. */
  2. void WrCmd(u8 CmdDat,u8 CmdWord)
  3. { u8 CmdBuf[2];
  4. CmdBuf[0]=CmdWord;
  5. WriteByte_1302(CmdDat,1,CmdBuf);
  6. }

复制代码


main函数中调用如下:


  1. u8 Ds1302SendBuf[8]={0x30,0x32,0x01,0x10,0x01,0x01,0x08,33};  //发送数据缓冲区
  2. u8 Ds1302RecBuf[8];    //接收数据缓冲区
  3. WrCmd(WrEnDisCmd,WrEnDat);  //写允许
  4. WrCmd(OscEnDisCmd,OscEnDat); //振荡器允许
  5. WriteByte(WrMulti,8,Ds1302SendBuf);//将时间值送到DS1302中
  6. RecByte(RdMulti,8,Ds1302RecBuf); // 读出来看看,

复制代码



南京傲屹电子 有限公司  各种资料 在我们的网站  各种接口  设计  使用方法 俱全

不错

多多交流,不错

您好  我想问下  这个例程是怎样显示出来时钟的?

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top