实验开发板为CT107D蓝桥官方板,编译环境为MDK5

采用蓝桥官方驱动改写

目录

一、DS1302时钟芯片

二、DS18B20温度传感器


一、DS1302时钟芯片

  • CE 复位脚
  • I/O 数据输入/输出引脚
  • SCLK 串行时钟
  • SCLK:串行时钟,输入,控制数据的输入与输出;
  • I/O:三线接口时的双向数据线;
  • CE:输入信号,在读、写数据期间,必须为高。

DS1302的使用主要在于看懂和掌握时序图

第一个字节的数据的第一位:1(读)2(写)

下图为各类数据的地址以及传输的格式(输入输出均用BCD码):

注意:年只有后两位,格式为20xx年。

DS1302具有Burst模式可顺序读或写日历和时间数据而跳过写地址步骤

当启用该模式后DS1302会通过数据线按:秒,分,时,日,月,星期,年的顺序输出。

main.h:

#ifndef _MAIN_H
#define _MAIN_H#include "STC15F2K60S2.h"typedef unsigned char u8;
typedef unsigned int  u16;
typedef unsigned long u32;#endif

ds1302.h:

#ifndef  __DS1302_H__
#define  __DS1302_H__#include "main.h"
#include<intrins.h>
/********************************************************************/
sbit SCK=P1^7;
sbit SD=P2^3;
sbit RST=P1^3;
/********************************************************************/
/*复位脚*/
#define RST_CLR RST=0  /*电平置低*/
#define RST_SET RST=1  /*电平置高*/
/*双向数据*/
#define SDA_CLR SD=0   /*电平置低*/
#define SDA_SET SD=1   /*电平置高*/
#define SDA_R   SD  /*电平读取*/
/*时钟信号*/
#define SCK_CLR SCK=0  /*时钟信号*/
#define SCK_SET SCK=1  /*电平置高*/
/********************************************************************/
#define ds1302_sec_addr         0x80        //秒数据地址
#define ds1302_min_addr         0x82        //分数据地址
#define ds1302_hr_addr          0x84        //时数据地址
#define ds1302_date_addr        0x86        //日数据地址
#define ds1302_month_addr       0x88        //月数据地址
#define ds1302_day_addr         0x8A        //星期数据地址
#define ds1302_year_addr        0x8C        //年数据地址#define ds1302_control_addr      0x8E        //写保护命令字单元地址
#define ds1302_charger_addr     0x90        //涓电流充电命令字地址
#define ds1302_clkburst_addr        0xBE        //日历、时钟突发模式命令字地址
/********************************************************************/
extern u8 Time[7];typedef struct time{u16 year;u8 mon;u8 day;u8 hour;u8 min;u8 sec;u8 week;
}Stime;
/********************************************************************/
/*单字节写入一字节数据*/
extern void Write_Ds1302_Byte(unsigned char dat);
/********************************************************************/
/*单字节读出一字节数据*/
extern unsigned char Read_Ds1302_Byte(void);/********************************************************************/
/********************************************************************/
/*向DS1302单字节写入一字节数据*/
extern void Ds1302_Single_Byte_Write(unsigned char addr, unsigned char dat);
/********************************************************************/
/*从DS1302单字节读出一字节数据*/
extern unsigned char Ds1302_Single_Byte_Read(unsigned char addr);extern void DS1302BurstWrite(unsigned char *dat);extern void DS1302BurstRead(unsigned char *dat);extern void Init_DS1302();//extern void DS1302_TimeIn(Stime *time);//extern void DS1302_TimeOut(Stime *time);#endif
/********************************************************************/
//              END FILE
/********************************************************************/

ds1302.c:

#include "ds1302.h"
#include "main.h"/********************************************************************/
/*单字节写入一字节数据*/
void Write_Ds1302_Byte(unsigned char dat)
{unsigned char i;SCK = 0;for (i=0;i<8;i++) { if (dat & 0x01)     // 等价于if((addr & 0x01) ==1) {SDA_SET;     //#define SDA_SET SDA=1 /*电平置高*/}else {SDA_CLR;        //#define SDA_CLR SDA=0 /*电平置低*/}       SCK_SET;SCK_CLR;       dat = dat >> 1; }
}
/********************************************************************/
/*单字节读出一字节数据*/
unsigned char Read_Ds1302_Byte(void)
{unsigned char i, dat=0;   for (i=0;i<8;i++){    dat = dat >> 1;if (SDA_R)      //等价于if(SDA_R==1)    #define SDA_R SDA /*电平读取*/ {dat |= 0x80;}else {dat &= 0x7F;}SCK_SET;SCK_CLR;}return dat;
}/********************************************************************/
/*向DS1302 单字节写入一字节数据*/
void Ds1302_Single_Byte_Write(unsigned char addr, unsigned char dat)
{ RST_SET;          /*启动DS1302总线,RST=1电平置高 */addr = addr & 0xFE;   Write_Ds1302_Byte(addr); /*写入目标地址:addr,保证是写操作,写之前将最低位置零*/   Write_Ds1302_Byte(dat);  /*写入数据:dat*/RST_CLR;                 /*停止DS1302总线*/
}/********************************************************************/
/*从DS1302单字节读出一字节数据*/
unsigned char Ds1302_Single_Byte_Read(unsigned char addr)
{ unsigned char temp;RST_CLR;           /*RST脚置低,实现DS1302的初始化*/SCK_CLR;          /*SCK脚置低,实现DS1302的初始化*/RST_SET;  /*启动DS1302总线,RST=1电平置高 */  addr = addr | 0x01;     Write_Ds1302_Byte(addr); /*写入目标地址:addr,保证是读操作,写之前将最低位置高*/temp=Read_Ds1302_Byte(); /*从DS1302中读出一个字节的数据*/        RST_CLR;    /*停止DS1302总线*/return temp;
}void DS1302BurstWrite(u8 *dat)
{u8 i;RST_SET;Write_Ds1302_Byte(ds1302_clkburst_addr);  //写入Burst模式启动指令for(i = 0; i < 8; i ++){Write_Ds1302_Byte(*dat ++);}RST_CLR;
}void DS1302BurstRead(u8 *dat)
{u8 i;RST_SET;Write_Ds1302_Byte(0XBF);for(i = 0; i < 8; i ++){dat[i] = Read_Ds1302_Byte();}RST_CLR;
}void Init_DS1302()
{u8 Init_Time[] = {0x50 , 0x59 , 0x23 , 0x16 , 0x03 , 0x06 , 0x19 };RST_CLR;SDA_CLR;Ds1302_Single_Byte_Write(ds1302_control_addr,0x00);DS1302BurstWrite(Init_Time);
}

新版官方驱动改写(DS1302):

DS1302.h:

#ifndef __DS1302_H
#define __DS1302_Hsbit SCK = P1^7;
sbit SDA_D = P2^3;
sbit RST = P1^3;   // DS1302复位 void Write_Ds1302(unsigned char temp);
u8 Read_Ds1302();
void Write_Ds1302_Byte( unsigned char address,unsigned char dat );
unsigned char Read_Ds1302_Byte( unsigned char address );
void DS1302BurstWrite(u8 *Dat);
void DS1302BurstRead(u8 *Dat);
void DS1302Init();
void TimeTranslate();
void TimeDisplay();
u8 HexToBCD(u8 Hex);
u8 BCDToHex(u8 BCD);#endif

DS1302.c:

#include "Sys.h"                                           void Write_Ds1302(unsigned  char temp)
{unsigned char i;for (i=0;i<8;i++)        { SCK=0;SDA_D=temp&0x01;temp>>=1; SCK=1;}SCK = 0;//记得加上
}
/*******************************/
u8 Read_Ds1302(){u8 i = 0, temp = 0x00;for (i=0;i<8;i++)                                            //这段来自于第47行{        SCK=0;temp>>=1; if(SDA_D)temp|=0x80;   SCK=1;} SCK = 0;//记得加上return (temp);
}
/*******************************/
void Write_Ds1302_Byte( unsigned char address,unsigned char dat )
{RST=0;    _nop_();SCK=0; _nop_();RST=1;     _nop_(); Write_Ds1302(address); Write_Ds1302(dat);      RST=0;
}unsigned char Read_Ds1302_Byte ( unsigned char address )//未使用
{unsigned char i,temp=0x00;RST=0; _nop_();SCK=0; _nop_();RST=1; _nop_();Write_Ds1302(address);for (i=0;i<8;i++)   {       SCK=0;temp>>=1; if(SDA_D)temp|=0x80;   SCK=1;} RST=0;    _nop_();SCK=0; _nop_();SCK=1; _nop_();SDA_D=0;   _nop_();SDA_D=1;   _nop_();return (temp);
}/*******************************//**************************************************************************
函数功能:DS1302Burst写
入口参数:待写入数组地址
返回值  :无
**************************************************************************/
void DS1302BurstWrite(u8 *Dat){u8 index = 0;RST = 1;Write_Ds1302(0xBE);                                           //写Burst写指令for(index = 0 ; index < 8; index ++){//读数据Write_Ds1302(Dat[index]);}RST = 0;
}
/**************************************************************************
函数功能:DS1302Burst读
入口参数:时间存储数组地址
返回值  :无
**************************************************************************/
void DS1302BurstRead(u8 *Dat){u8 index = 0;RST = 1;Write_Ds1302(0xBF);                                            //写Burst读指令for(index = 0 ; index < 8; index ++){//读数据Dat[index] = Read_Ds1302();}RST = 0;
}
/**************************************************************************
函数功能:DS1302时间初始化
入口参数:无
返回值  :无
**************************************************************************/
void DS1302Init(){u8 InitTime[] = {                                            //2019年12月12日 星期四 10:00:000x00,0x00,0x10, 0x12, 0x12, 0x04, 0x19};//秒   分   时    日    月    周    年RST = 0;SDA_D = 0;Write_Ds1302_Byte(0x8E,0x00);                      //撤销写保护DS1302BurstWrite(InitTime);
}
/**************************************************************************
函数功能:时间读取
入口参数:无
返回值  :无
**************************************************************************/
void TimeTranslate(){u8 Time[7] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};DS1302BurstRead(Time);LocalTime.Sec   = Time[0];LocalTime.Minu  = Time[1];LocalTime.Hour  = Time[2];LocalTime.Day   = Time[3];LocalTime.Month = Time[4];LocalTime.Week  = Time[5];LocalTime.Year  = Time[6];
}
/**************************************************************************
函数功能:将实时时间加载到数码管缓冲区
入口参数:无
返回值  :无
**************************************************************************/
void TimeDisplay(){TimeTranslate();SMG_Buff[0] = SMG[LocalTime.Hour >> 4];SMG_Buff[1] = SMG[LocalTime.Hour & 0x0F];SMG_Buff[2] = 0xBF;//-SMG_Buff[3] = SMG[LocalTime.Minu >> 4];SMG_Buff[4] = SMG[LocalTime.Minu & 0x0F];SMG_Buff[5] = 0xBF;SMG_Buff[6] = SMG[LocalTime.Sec >> 4];SMG_Buff[7] = SMG[LocalTime.Sec & 0x0F];
}
/**************************************************************************
函数功能:十六进制数转BCD码
入口参数:十六进制数
返回值  :BCD码
**************************************************************************/
//u8 HexToBCD(u8 Hex){
//  u8 BCD;
//  BCD = Hex/10;
//  BCD <<= 4;
//  BCD |= Hex % 10;
//
//  return BCD;
//}
/**************************************************************************
函数功能:BCD码转十六进制数
入口参数:BCD码
返回值  :十六进制数
**************************************************************************/
//u8 BCDToHex(u8 BCD){
//  u8 Hex;
//  Hex = (BCD >> 4)*10 + (BCD & 0x0F);
//
//  return Hex;
//}
/*******************************/

—————————————————————————————————————————————————

 二、DS18B20温度传感器

由于DS18B20只有一条总线,数据和指令都从这条总线上传输,所以对时间有及其严格的要求

对应于ds18B20.c中的“Start_DS18B20”函数

数据读写时序:

ds18b20.h:

#ifndef _ONEWIRE_H
#define _ONEWIRE_H#include "main.h"#define OW_SKIP_ROM 0xcc           //每次使用都需要写入
#define DS18B20_CONVERT 0x44    //启动温度转换
#define DS18B20_READ 0xbe           //读取指令//IC引脚定义
sbit DQ = P1^4;//函数声明
void Delay_OneWire(unsigned int t);
void Write_DS18B20(unsigned char dat);
bit Init_DS18B20(void);
unsigned char Read_DS18B20(void);
extern bit Start_DS18B20();#endif

ds18b20.c:

/*程序说明: 单总线驱动程序软件环境: Keil uVision 4.10 硬件环境: CT107单片机综合实训平台日    期: 2011-8-9
*/#include "onewire.h"
#include "main.h"
#include "intrins.h"
//单总线延时函数
u8 i;
void Delay_OneWire(unsigned int t)    //约等于延时1us
{do{_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();}while(-- t);
}//DS18B20芯片初始化
bit Init_DS18B20(void) //每次获取温度都需要初始化
{bit initflag = 0;EA = 0;//DQ = 1;//Delay_OneWire(12);DQ = 0;Delay_OneWire(500); DQ = 1;Delay_OneWire(60); initflag = DQ;    //Delay_OneWire(5);while(!DQ);EA = 1;return initflag;
}//通过单总线向DS18B20写一个字节
void Write_DS18B20(unsigned char dat)
{unsigned char i;EA = 0;for(i=0;i<8;i++){DQ = 0;Delay_OneWire(2);       //*DQ = dat&0x01;          //如果写1就拉高,0则拉低Delay_OneWire(60);DQ = 1;dat >>= 1;}//Delay_OneWire(5);EA = 1;
}//从DS18B20读取一个字节
unsigned char Read_DS18B20(void)
{unsigned char i;unsigned char dat;EA = 0;for(i=0;i<8;i++){DQ = 0;
//      Delay_OneWire(2);       //*dat >>= 1;        //使第一位置0DQ = 1;if(DQ)              //读取第一位{dat |= 0x80;}      Delay_OneWire(60);  //一位数据的读写要超过60us}EA = 1;return dat;
}bit Start_DS18B20()
{bit ack;ack = Init_DS18B20();if(ack == 0){  Write_DS18B20(OW_SKIP_ROM);Write_DS18B20(DS18B20_CONVERT);}return ~ack;
}//另外插入温度的数据处理函数(零下温度未处理)void Temp_Get()  //温度获取
{bit Ack;u8 LSB , MSB, index;   u16 temp;Ack = Init_DS18B20();if(Ack == 0){Write_DS18B20(OW_SKIP_ROM);           //跳过器件选取(ds18b20是可以挂载多个的,由于只用一个所以跳过器件的选取)Write_DS18B20(DS18B20_READ);  //温度读取指令LSB = Read_DS18B20();                      //MSB = Read_DS18B20();temp = ((int)MSB << 8) + LSB;temp >>= 4; //舍弃小数for(index = 7; index >= 3; index --)Led_DataBuff[index] = 0xFF; //格式转换Led_DataBuff[2] = SMG[temp / 10];Led_DataBuff[1] = SMG[temp % 10];Led_DataBuff[0] = 0xC6;}Start_DS18B20(); //再次启动温度转换模式}

新版官方驱动改写(One-Wire):

//*************************ONEWIRE**********************//
#ifndef __ONEWIRE_H
#define __ONEWIRE_H#include "config.h"void Delay_OneWire(unsigned int t);
void Write_DS18B20(unsigned char dat);
unsigned char Read_DS18B20(void);bit Start_DS18B20();
bit init_ds18b20(void);
void Temp_Get();
#endif
--------------------------------------------------------
sbit DQ = P1^4;  //单总线接口//单总线延时函数
void Delay_OneWire(unsigned int t)  //IAP15F2K61S2
{t = t * 7;while(t--);
}//通过单总线向DS18B20写一个字节
void Write_DS18B20(unsigned char dat)
{unsigned char i;EA = 0;for(i=0;i<8;i++){DQ = 0;DQ = dat&0x01;Delay_OneWire(5);DQ = 1;dat >>= 1;}Delay_OneWire(5);EA = 1;
}//从DS18B20读取一个字节
unsigned char Read_DS18B20(void)
{unsigned char i;unsigned char dat;EA = 0;for(i=0;i<8;i++){DQ = 0;dat >>= 1;DQ = 1;if(DQ){dat |= 0x80;}        Delay_OneWire(5);}EA = 1;return dat;
}//DS18B20设备初始化
bit init_ds18b20(void)
{bit initflag = 0;DQ = 1;Delay_OneWire(12);DQ = 0;Delay_OneWire(80);DQ = 1;Delay_OneWire(10); initflag = DQ;     Delay_OneWire(5);return initflag;
}bit Start_DS18B20()
{bit ack;ack = init_ds18b20();if(!ack){Write_DS18B20(0xCC);Write_DS18B20(0x44);}return ~ack;
}bit Config_DS18B20()
{bit ack;ack = Start_DS18B20();if(ack == 0){Write_DS18B20(0xCC);Write_DS18B20(0x4E);//写暂存器指令4EWrite_DS18B20(0x4B);//写高速缓存器TH高温限值75度Write_DS18B20(0x00);//写高速缓存器TL低温限值0度Write_DS18B20(0x1F);//写配置寄存器4//0x1f : 0.5000°C  转换时间93.75ms//0x3f : 0.2000°C  转换时间187.5ms//0x5f : 0.1250°C  转换时间375ms//0x7f : 0.0625°C  转换时间750ms}return ~ack;
}/************FOR_DATA***********/void Temp_Get()
{bit ack;u8 LSB , MSB;u8 index;int temp;ack = init_ds18b20();if(!ack){Write_DS18B20(0xCC);Write_DS18B20(0xBE);LSB = Read_DS18B20();MSB = Read_DS18B20();temp = ((int)MSB << 8) + LSB;temp >>= 4;for(index = 0; index < 5; index ++){SMG_Buff[index] = 0xFF;}SMG_Buff[5] = SMG_Data[temp / 10];SMG_Buff[6] =  SMG_Data[temp % 10];SMG_Buff[7] = 0xC6;    }Start_DS18B20();
}

【蓝桥杯单片机】DS1302时钟芯片+DS18B20单总线温度传感器(官方驱动源码改写)相关推荐

  1. 蓝桥杯单片机DS1302时钟芯片驱动代码注释

    蓝桥杯单片机DS1302时钟芯片驱动代码之前的疑惑注释了下 /* DS1302 芯片包含一个 实时时钟/日历和 31 字节的静态 RAM. 与时钟/RAM 通讯只需要三根线: CE,I/O (数据线) ...

  2. 【蓝桥杯单片机】IIC通讯协议与EEPROM(AT24C02)(官方驱动源码改写)

    实验开发板为CT107D蓝桥官方板,编译环境为MDK5 由蓝桥官方驱动改写 AT24C02: AT24C02为地址可编程器件(CT107D可编程位均为0),因此可于总线上挂载多个相同的器件. 最后一位 ...

  3. 蓝桥杯单片机-DS1302时钟模块

    一.简介 1.采用SPI三线接口通信(SCK.SDA.RST) 上升沿数据被写入DS1302,下降沿被读出 二.应用 1.在ds1302.c文件中定义三个数组 unsigned char code R ...

  4. 蓝桥杯单片机DS1302时钟

    采用SPI三线接口与MCU进行同步通信,并可采用突发方式一次传送多个字节的时钟参数和RAM数据. 日历时钟寄存器有8个存储单元: 所以,我们需要三个数组: 定义DS1302读操作的日历时钟存储器地址 ...

  5. 基于51单片机ds1302时钟、ds18b20、lcd12864的恒温器

    目录 项目:基于51单片机ds1302时钟.ds18b20的恒温器 功能说明: 运行流程: 效果展示: 供电方式: 用途: 提高: 附: ​                              ...

  6. 51单片机DS1302时钟芯片应用Proteus仿真

    系列文章目录 第一章 51单片机Proteus仿真(一) DS1302使用 文章目录 系列文章目录 前言 一.DS1302时序解读 二.BCD码转十进制解读 三.Proteus仿真 四.详细代码 前言 ...

  7. 蓝桥杯突击6-DS1302时钟芯片

    本次学习DS1302时钟芯片. DS1302芯片采用SPI 3线通信, 分别是SCLK, I/O,CE三根线. 由于比赛时给出DS1302的SPI协议的文件, 所以这次重点介绍其寄存器. DS1302 ...

  8. (给自己看)51单片机DS1302时钟芯片

    老规矩先上DS1302.c的代码 #include <regx52.h>//首先 DS1302_Init(); // DS1302_SetTime();//再在while中DS1302_R ...

  9. 蓝桥杯单片机——Ds1302时间开始与暂停

    首先说明一下ds1302时间,开始与暂停的原理: 只要让"秒寄存器"的最高位为1,时钟就会暂停计时. 同理只要让"秒寄存器"的最高位为0,时钟就会开始计时. 时 ...

最新文章

  1. python3 线程间通讯(借助queue)
  2. Singleton模式学习
  3. Error:Connection timed out: connect
  4. Android官方开发文档Training系列课程中文版:添加ActionBar之添加Action按钮
  5. 牛客16502 螺旋矩阵
  6. tcpdump - 数据包进行截获的包分析工具
  7. 安卓android中国象棋chess程序项目源码源代码,C/C++编程笔记:C语言打造中国象棋游戏,项目源代码分享!,c语言笔记大全...
  8. Git只获取部分目录的内容
  9. 【运动学】基于matlab GUI模拟小球自由落体【含Matlab源码 1630期】
  10. go标准库的学习-encoding/base64
  11. pid温度控制算法c语言程序,温度控制的PID算法的C语言程序
  12. resin设置权限_如何配置resin 3.1.9
  13. outlook服务器邮件满了怎么办,Outlook邮箱不能接收邮件提示邮件箱已满怎么办?
  14. ggplot2学习总结
  15. 【JZOJ6124】有限空间跳跃理论
  16. 官网中国传媒大学计算机与网络安全学院,曹建香 - 中国传媒大学 - 计算机与网络空间安全学院...
  17. 阐述免费增值游戏的设计特点及注意事项
  18. Google Dremel 原理 - 如何能 3 秒分析 1PB
  19. thinkphp5范围查询_ThinkPHP实现经纬度范围查询
  20. 2020Android手机专业摄影,华为拍照手机排行榜2020_华为拍照最好的是哪款

热门文章

  1. android 开发 佳博打印模板_电商在打印快递电子面单时的常见问题及解决方法
  2. Java 设计模式之 Observer 模式
  3. Java 并发编程之线程池 ScheduledThreadPool
  4. 使用python GluonTS库做概率预测
  5. 平衡二叉树(AVL)python实现
  6. cv2.error: opencv(4.4.0)_【从零学习OpenCV 4】图像金字塔
  7. 鱼c工作室小甲鱼的水平_历历万乡 | 得两代帝王喜爱,又上过国际舞台!深冬就去浙个“年鱼福气”加持的小村子吧!...
  8. 微信小程序怎么绑定服务器,微信小程序页面表单如何跟图片一起上传服务器
  9. java复选框只会选中一个_java复选框选中
  10. 省选专练【POI2015】Podzial naszyjnika