找回密码
 立即注册

QQ登录

只需一步,快速开始

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

第17章-DS1302时钟芯片的单片机驱动

[复制链接]
跳转到指定楼层
楼主
51单片机轻松入门—基于STC15W4K系列(C语言版)
李友全
编著 详见:http://www.51hei.com/bbs/dpj-37954-1.html

第17章 DS1302时钟芯片
1 电路图
2 程序移植

使用单片机的定时器可以实现时钟功能,

但程序较为复杂,单片机断电后重新上电 时间需要重新设置,为了降低程序的复杂程度,解决断电后重新上电的时间设置

问题,我们需要使用专用的时钟芯片DS1302
1 电 路 图
配套实验板1号单片机与时钟芯片DS1302连接电路如图所示。


4

为了简化实验,电路中使用了100uF的电容代替电池,当

单片机系统断电后由电容维持DS1302的供电(3分钟左右)。 当作为长期使用的时钟时,应更换为3V的纽扣电池。


2 程 序 移 植
例17.1 读取DS1302运行过程中的年、月、日、时、分、秒数据并发送到计算机串口助手显 示,单片机时钟频率22.1184MHz,波特率9600。串口助手接收区选择“字符格式显示”。

sbit SCK = P2^7; // 时钟
sbit SDA = P4^5; // 数据
sbit RST = P4^6; // DS1302复位(片选)
unsigned char StartTime[7]= {14,11,30,23,50,59,7}; // 设定初始时间值
// 年、月、日、时、分、秒、星期* ,14-11-30 23:50:59 星期7

void main()

{
port_mode(); // 所有IO口设为准双向弱上拉方式。 UART_init(); // 波特率:9600/22.1184MHz Data_Swap(); // 数据交换
set_time(time); // 设定初始时间值 , 只设定1次,设定完成后应屏蔽本行
while(1)
{
read_time(time); // 秒分时日月周年 UART_Send_PC(time);
delay_1S();
}
}



部分程序预览(完整代码请下载附件)
  1. /****************《51单片机轻松入门-基于STC15W4K系列》配套例程 *************
  2. ★★★★★★★★★★★★★★★★★★★★★★★★
  3. 《51单片机轻松入门-基于STC15W4K系列》 一书已经由北航出版社正式出版发行。
  4.   作者亲手创作的与教材配套的51双核实验板(2个MCU)对程序下载、调试、仿真方便,不需要外部
  5.   仿真器与编程器,这种设计方式彻底解决了系统中多个最高优先级谁也不能让谁的中断竞争问题。
  6.   QQ群:STC51-STM32(3) :515624099 或 STC51-STM32(2):99794374。
  7.         验证信息:STC15单片机
  8.   邮箱:xgliyouquan@126.com
  9.   ★★★★★★★★★★★★★★★★★★★★★★★★*/

  10. #include "STC15W4K.H"
  11. #include "uart_debug.H"
  12. #include <intrins.h>
  13. sbit SCK = P2^7;                   // 时钟        
  14. sbit SDA = P4^5;                      // 数据        
  15. sbit RST = P4^6;               // DS1302复位(片选)
  16. #define DS1302_W_ADDR 0x80           // 写起始地址
  17. #define DS1302_R_ADDR 0x81            // 读起始地址
  18. unsigned char StartTime[7]=        {14,11,30,23,50,59,7};  // 年月日时分秒周 14-11-30 23:50:59
  19. unsigned char time[8];  // 秒分时日月周年

  20. void Data_Swap()             // 数据交换
  21. {
  22.         time[0]=StartTime[5];         // 秒
  23.         time[1]=StartTime[4];         // 分
  24.         time[2]=StartTime[3];         // 时
  25.         time[3]=StartTime[2];         // 日
  26.         time[4]=StartTime[1];         // 月
  27.         time[5]=StartTime[6];         // 周
  28.         time[6]=StartTime[0];         // 年
  29.         time[7]=0;                                 // 最后一字节写保护为0可写入数据
  30. }

  31. // 写字节,低位在前,高位在后        
  32. void write_ds1302_byte(unsigned char dat)
  33. {
  34.         unsigned char i;
  35.         for (i=0;i<8;i++)
  36.         {
  37.                 SDA = dat & 0x01;  // bit型变量取值范围是0和1,赋值非0结果为1
  38.                 SCK = 1;                   // 放入数据到时钟上升沿时间 50nS
  39.                 dat >>= 1;                   // 时钟上升沿后数据保持时间 70nS
  40.                 SCK = 0;                   // 时钟低电平时间与时钟高电平时间250nS
  41.         }
  42. }  
  43. // 清除写保护
  44. void clear_ds1302_WP(void)
  45. {
  46.         RST = 0;           // RST引脚既是CE引脚
  47.         SCK = 0;
  48.         RST = 1;
  49.         write_ds1302_byte(0x8E);
  50.         write_ds1302_byte(0);
  51.         SDA = 0;
  52.         RST = 0;
  53. }        
  54. // 设置写保护
  55. void set_ds1302_WP(void)
  56. {
  57.         RST = 0;           // RST引脚既是CE引脚
  58.         SCK = 0;
  59.         RST = 1;
  60.         write_ds1302_byte(0x8E);
  61.         write_ds1302_byte(0x80);
  62.         SDA = 0;
  63.         RST = 0;
  64. }

  65. // 连续写入8个寄存器数据,dat-待写入数据指针  
  66. void write_ds1302_nbyte(unsigned char *dat)
  67. {
  68.     unsigned char i;
  69.     RST=0;
  70.         SCK=0;
  71.     RST = 1;
  72.     write_ds1302_byte(0xBE);  // 发送突发写寄存器指令
  73.     for (i=0; i<8; i++)       // 连续写入8字节数据
  74.     {
  75.         write_ds1302_byte(dat[i]);
  76.     }
  77.     RST = 0;
  78. }
  79. // 设定时钟数据
  80. void set_time(unsigned char *timedata)
  81. {
  82.         unsigned char i, tmp;
  83.         for (i=0; i<7; i++)  // 转化为压缩BCD格式(一个字节存放2个BCD码)
  84.         {
  85.                 tmp = timedata[i] / 10;                        // 获取高位BCD码
  86.                 timedata[i] = timedata[i] % 10;                // 获取低位BCD码
  87.                 timedata[i] = timedata[i] + tmp*16;        // 合并成压缩BCD码
  88.         }
  89.         clear_ds1302_WP();                                     // 清除写保护
  90.         write_ds1302_nbyte(timedata);                    // 连续写入8字节数据
  91.         set_ds1302_WP();                                // 写保护
  92. }  

  93. // 读字节,低位在前,高位在后
  94. unsigned char read_ds1302_byte(void)
  95. {
  96.         unsigned char i, dat=0;        
  97.         for (i=0;i<8;i++)
  98.         {        
  99.                 dat >>= 1;
  100.                 if (SDA) dat |= 0x80;
  101.                 SCK = 1;
  102.                 SCK = 0;
  103.         }
  104.         return dat;
  105. }
  106. // 连续读取8个寄存器的数据,dat-读取数据的接收指针  
  107. void read_time(unsigned char *dat)
  108. {
  109.     unsigned char i;  
  110.         RST=0;
  111.         SCK=0;
  112.     RST = 1;
  113.     write_ds1302_byte(0xBF);  //发送突发读寄存器指令
  114.     for (i=0; i<8; i++)     //连续读取8个字节
  115.     {
  116.         dat[i] = read_ds1302_byte();
  117.     }
  118.     RST = 0;
  119. }

  120. void delay_1S(void)
  121. {
  122.    unsigned char i,j,k;
  123.    for(i=85;i>0;i--)      // 注意后面没分号
  124.    for(j=254;j>0;j--)     // 注意后面没分号
  125.    for(k=255;k>0;k--);    // 注意后面有分号
  126. }
  127. // 单字节压缩BCD码转换成ASCII码另一常见格式示例,dat/16 + 0x30,
  128. // dat/16本质就是右移4位,数字0--9加上0x30即得数字0--9的ASCII码
  129. void UART_Send_PC(unsigned char *tmp)
  130. {
  131.         unsigned char str[12];           // 字符串转换缓冲区
  132.         str[0] = '2';                    // 添加年份的高2位:20
  133.     str[1] = '0';
  134.     str[2] = (tmp[6] >> 4) + '0';    //“年”高位数字转换为ASCII码
  135.     str[3] = (tmp[6]&0x0F) + '0';    //“年”低位数字转换为ASCII码
  136.     str[4] = '-';  //添加日期分隔符
  137.     str[5] = (tmp[4] >> 4) + '0';    //“月”
  138.     str[6] = (tmp[4]&0x0F) + '0';
  139.     str[7] = '-';
  140.     str[8] = (tmp[3] >> 4) + '0';    //“日”
  141.     str[9] = (tmp[3]&0x0F) + '0';
  142.     str[10] = '\0';                                         // 字符串结束符
  143.         UART_Send_Str(str);                                 // 输出  年、月、日
  144.         UART_Send_Str("   ");
  145.   
  146.     str[0] = (tmp[2] >> 4) + '0';    //“时”
  147.     str[1] = (tmp[2]&0x0F) + '0';
  148.     str[2] = ':';  //添加时间分隔符
  149.     str[3] = (tmp[1] >> 4) + '0';    //“分”
  150.     str[4] = (tmp[1]&0x0F) + '0';
  151.     str[5] = ':';
  152.     str[6] = (tmp[0] >> 4) + '0';    //“秒”
  153.     str[7] = (tmp[0]&0x0F) + '0';
  154.     str[8] = '\0';
  155.     UART_Send_Str(str);                   // 输出  时、分、秒         
  156.         UART_Send_Str("   ");   
  157.         
  158.         UART_Send_Str("week = ");
  159.         str[0] = (tmp[5]&0x0F) + '0';    //“星期”
  160.     str[1] = '\0';
  161.         UART_Send_Str(str);                          // 输出  星期  
  162.         UART_Send_Str("   ");
  163. }
  164. void port_mode()            // 端口模式
  165. {
  166.         P0M1=0x00; P0M0=0x00;P1M1=0x00; P1M0=0x00;P2M1=0x00; P2M0=0x00;P3M1=0x00; P3M0=0x00;
  167.         P4M1=0x00; P4M0=0x00;P5M1=0x00; P5M0=0x00;P6M1=0x00; P6M0=0x00;P7M1=0x00; P7M0=0x00;
  168. }
  169. void main()   
  170. {  
  171.         port_mode();            // 所有IO口设为准双向弱上拉方式。
  172.         UART_init();        // 波特率:9600/22.1184MHz
  173.         Data_Swap();        // 数据交换
  174.          set_time(time);     // 设定初始时间值 ,数组名就代表数组首地址
  175.         while(1)
  176.         {        
  177.                 read_time(time);          // 秒分时日月周年        
  178.                 UART_Send_PC(time);                  
  179.                 delay_1S();
  180.         }
  181. }
复制代码


第17章 DS1302时钟芯片.rar

174.04 KB, 下载次数: 83, 下载积分: 黑币 -5

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

使用道具 举报

沙发
ID:441232 发表于 2018-12-6 20:51 | 只看该作者
感谢 辛苦了找了很久
回复

使用道具 举报

板凳
ID:421232 发表于 2018-12-12 19:41 | 只看该作者
谢谢分享·
回复

使用道具 举报

地板
ID:288930 发表于 2019-1-18 13:57 | 只看该作者
谢谢分享!
回复

使用道具 举报

5#
ID:315083 发表于 2019-5-28 17:22 | 只看该作者
感谢楼主分享
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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