找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 498|回复: 1
打印 上一主题 下一主题
收起左侧

DS1302不能写入,完全断电重新启动后能写入一次,在想写入还需要完全断电重新启动

[复制链接]
跳转到指定楼层
楼主
ID:686011 发表于 2022-10-28 22:38 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
请教一下,用STM32F103CBT6驱动DS1302,只有完全掉电后再上电才会向写入1302写入一次数据更新时钟,程序运行过程中向1302中写数据没反应。
DS1302.c
  1. #include "ds1302.h"
  2. #include "delay.h"

  3. //初始化时间定义
  4. u8 time_buf[8] = {0x20,0x22,0x10,0x30,0x11,0x09,0x55,0x07}; //初始时间2010年6月1号23点59分55秒 星期二
  5. extern u8 time[15];

  6. //DS1302初始化
  7. void DS1302_Init(void)
  8. {
  9.   GPIO_InitTypeDef GPIO_InitStructure;
  10.         
  11.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  12.         
  13.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10 |GPIO_Pin_11;
  14.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  15.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  16.         GPIO_Init(GPIOA, &GPIO_InitStructure);
  17.         
  18.         GPIO_SetBits(GPIOA, GPIO_Pin_10);                 //PB10拉高
  19.         GPIO_ResetBits(GPIOA, GPIO_Pin_9 | GPIO_Pin_11); //PB9,PB11置低
  20. }


  21. //static void DS1302_IO_IN(void) //设置IO数据引脚的输入模式的配置  
  22. //{  
  23. //  GPIO_InitTypeDef GPIO_InitStructure;  
  24. //  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);  //开启GPIOD的时钟  
  25. //   
  26. //  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;  //设置引脚
  27. //  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  //速率50MHz  
  28. //  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //配置输入模式为上拉输入模式  
  29. //   
  30. //  GPIO_Init(GPIOA, &GPIO_InitStructure);//把上面的配置初始化  
  31. //}  
  32. //  
  33. //static void DS1302_IO_OUT(void)//设置IO数据引脚的输出模式的配置  
  34. //{  
  35. //  GPIO_InitTypeDef GPIO_InitStructure;  
  36. //  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//开启GPIOD时钟  
  37. //   
  38. //  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//设置引脚  
  39. //  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  
  40. //  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//配置为推挽输出  
  41. //   
  42. //  GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化  
  43. //}  


  44. //向DS1302写入一个字节数据
  45. void DS1302_Write_Byte(u8 addr, u8 data)
  46. {
  47.   u8 i;
  48.         DS1302_RST = 0;      //停止DS1302总线
  49.         delay_us(10);
  50.         DS1302_RST = 1;      //启动DS1302总线
  51.         addr = addr & 0xFE;  //最低位置零,写数据
  52.         DS1302_IO_OUT();
  53.         for(i = 0; i < 8; i ++)  //写地址
  54.         {
  55.           if (addr & 0x01)
  56.                         DS1302_DATA_OUT = 1;
  57.                 else
  58.                         DS1302_DATA_OUT = 0;
  59.                
  60.                 DS1302_SCK = 1;    //产生时钟
  61.                 delay_us(10);
  62.                 DS1302_SCK = 0;
  63.                 addr = addr>>1;
  64.         }
  65.         for (i = 0; i < 8; i ++) //写数据
  66.         {
  67.           if(data & 0x01)
  68.                         DS1302_DATA_OUT = 1;
  69.                 else
  70.                         DS1302_DATA_OUT = 0;
  71.                
  72.                 DS1302_SCK = 1;   //产生时钟
  73.                 delay_us(10);
  74.                 DS1302_SCK = 0;
  75.           data = data>>1;
  76.         }
  77.         DS1302_RST = 0;      //停止DS1302总线
  78. }

  79. //从DS1302读出一个字节数据
  80. u8 DS1302_Read_Byte(u8 addr)
  81. {
  82.   u8 i,temp;
  83.         DS1302_RST = 0;      //停止DS1302总线
  84.         delay_us(10);
  85.         DS1302_RST = 1;      //启动DS1302总线
  86.         addr = addr | 0x01;  //最低位置高,读数据
  87.         DS1302_IO_OUT();
  88.         for(i = 0; i < 8; i ++)  //写地址
  89.         {
  90.           if (addr & 0x01)
  91.                         DS1302_DATA_OUT = 1;
  92.                 else
  93.                         DS1302_DATA_OUT = 0;
  94.                
  95.                 DS1302_SCK = 1;    //产生时钟
  96.                 delay_us(10);
  97.                 DS1302_SCK = 0;
  98.                 addr = addr>>1;
  99.         }
  100.         DS1302_IO_IN();
  101.         for (i = 0; i < 8; i ++) //读数据
  102.         {
  103.           temp = temp >> 1;
  104.                 if(DS1302_DATA_IN)
  105.                         temp |= 0x80;
  106.                 else
  107.                         temp &= 0x7F;
  108.                
  109.                 DS1302_SCK = 1;   //产生时钟
  110.                 delay_us(10);
  111.                 DS1302_SCK = 0;
  112.         }
  113.         DS1302_RST = 0;      //停止DS1302总线
  114.         return temp;
  115. }

  116. //向DS1302写入时间数据
  117. void DS1302_Write_Time(void)
  118. {
  119.   DS1302_Write_Byte(ds1302_control_add, 0x00);      //关闭写保护
  120.   DS1302_Write_Byte(ds1302_sec_add, 0x80);          //暂停时钟
  121.         //DS1302_Write_Byte(ds1302_charger_add, 0xA9);      //涓流充电
  122.         DS1302_Write_Byte(ds1302_year_add,time_buf[1]);                //年
  123.         DS1302_Write_Byte(ds1302_month_add,time_buf[2]);        //月
  124.         DS1302_Write_Byte(ds1302_date_add,time_buf[3]);                //日
  125.         DS1302_Write_Byte(ds1302_hr_add,time_buf[4]);                  //时
  126.         DS1302_Write_Byte(ds1302_min_add,time_buf[5]);                //分
  127.         DS1302_Write_Byte(ds1302_sec_add,time_buf[6]);                //秒
  128.         DS1302_Write_Byte(ds1302_day_add,time_buf[7]);                //周
  129.         DS1302_Write_Byte(ds1302_control_add,0x80);                    //打开写保护
  130. }

  131. //从DS302读出时钟数据
  132. void DS1302_Read_Time(void)  
  133. {
  134.         time[1] = DS1302_Read_Byte(ds1302_year_add);                   //年
  135.         time[2] = DS1302_Read_Byte(ds1302_month_add);                   //月
  136.         time[3] = DS1302_Read_Byte(ds1302_date_add);                   //日
  137.         time[4] = DS1302_Read_Byte(ds1302_hr_add);                     //时
  138.         time[5] = DS1302_Read_Byte(ds1302_min_add);                     //分
  139.         time[6] = (DS1302_Read_Byte(ds1302_sec_add))&0x7f; //秒,屏蔽秒的第7位,避免超出59
  140.         time[7] = DS1302_Read_Byte(ds1302_day_add);                     //周         
  141. }

  142. ////DS1302向上层返回时间数据
  143. //void DS1302_Get_Time(u8 *time)
  144. //{
  145. //        DS1302_Read_Time();
  146. //        time[0]=(time_buf[0]>>4);   //年   
  147. //  time[1]=(time_buf[0]&0x0f);
  148. //   
  149. //  time[2]=(time_buf[1]>>4);   
  150. //  time[3]=(time_buf[1]&0x0f);
  151. //  
  152. //  time[4]=(time_buf[2]>>4);   //月  
  153. //  time[5]=(time_buf[2]&0x0f);

  154. //  time[6]=(time_buf[3]>>4);   //日   
  155. //  time[7]=(time_buf[3]&0x0f);
  156. //   
  157. //  time[8]=(time_buf[7]&0x07); //星期
  158. //   
  159. //  time[9]=(time_buf[4]>>4);   //时   
  160. //  time[10]=(time_buf[4]&0x0f);   

  161. //  time[11]=(time_buf[5]>>4);  //分   
  162. //  time[12]=(time_buf[5]&0x0f);   

  163. //  time[13]=(time_buf[6]>>4);  //秒
  164. //  time[14]=(time_buf[6]&0x0f);
  165. //}
复制代码





DS1302.h
  1. #ifndef __DS1302_H
  2. #define __DS1302_H
  3. #include "sys.h"

  4. //IO方向设置
  5. #define DS1302_IO_IN()  {GPIOA->CRH&=0XFFFFF0FF;GPIOA->CRH|=8<<8;}
  6. #define DS1302_IO_OUT() {GPIOA->CRH&=0XFFFFF0FF;GPIOA->CRH|=3<<8;}
  7. //IO操作函数                                                                           
  8. #define        DS1302_DATA_OUT PAout(10) //数据端口        PA10
  9. #define        DS1302_DATA_IN  PAin(10)  //数据端口        PA10

  10. #define        DS1302_SCK  PAout(11)
  11. #define        DS1302_RST  PAout(9)

  12. //DS1302地址定义
  13. #define ds1302_sec_add                          0x80                //秒数据地址
  14. #define ds1302_min_add                          0x82                //分数据地址
  15. #define ds1302_hr_add                          0x84                //时数据地址
  16. #define ds1302_date_add                          0x86                //日数据地址
  17. #define ds1302_month_add                  0x88                //月数据地址
  18. #define ds1302_day_add                          0x8a                //星期数据地址
  19. #define ds1302_year_add                          0x8c                //年数据地址
  20. #define ds1302_control_add                0x8e                //控制数据地址
  21. #define ds1302_charger_add                0x90                                          
  22. #define ds1302_clkburst_add                0xbe

  23. void DS1302_Init(void);
  24. void DS1302_Write_Byte(u8 addr, u8 data);
  25. u8 DS1302_Read_Byte(u8 addr);
  26. void DS1302_Write_Time(void);
  27. void DS1302_Read_Time(void);
  28. //void DS1302_Get_Time(u8 *time);

  29. #endif
复制代码





分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:384109 发表于 2022-10-28 23:41 | 只看该作者
1302的地址错了,1302读和写是不同的地址
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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