51单片机~DS1302时钟,SPI总线原理

发布者:Qianfeng最新更新时间:2022-09-23 来源: csdn关键字:51单片机  DS1302时钟 手机看文章 扫描二维码
随时随地手机看文章

(一)说明:

在这里插入图片描述
在这里插入图片描述

(二)SPI总线原理:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

(三)日历时钟寄存器

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

慢充电:

在这里插入图片描述

BCD码:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

temp.h


#ifndef __TEMP_H_

#define __TEMP_H_


#include

//---重定义关键词---//

#ifndef uchar

#define uchar unsigned char

#endif


#ifndef uint 

#define uint unsigned int

#endif


//--定义使用的IO口--//

sbit DSPORT=P3^7;


//--声明全局函数--//

void Delay1ms(uint );

uchar Ds18b20Init();

void Ds18b20WriteByte(uchar com);

uchar Ds18b20ReadByte();

void  Ds18b20ChangTemp();

void  Ds18b20ReadTempCom();

int Ds18b20ReadTemp();


#endif


temp.c


#include"temp.h"

/*******************************************************************************

* 函 数 名         : Delay1ms

* 函数功能    : 延时函数

* 输    入         : 无

* 输    出         : 无

*******************************************************************************/


void Delay1ms(uint y)

{

uint x;

for( ; y>0; y--)

{

for(x=110; x>0; x--);

}

}

/*******************************************************************************

* 函 数 名         : Ds18b20Init

* 函数功能    : 初始化

* 输    入         : 无

* 输    出         : 初始化成功返回1,失败返回0

*******************************************************************************/


uchar Ds18b20Init()

{

uchar i;

DSPORT = 0; //将总线拉低480us~960us

i = 70;

while(i--);//延时642us

DSPORT = 1; //然后拉高总线,如果DS18B20做出反应会将在15us~60us后总线拉低

i = 0;

while(DSPORT) //等待DS18B20拉低总线

{

Delay1ms(1);

i++;

if(i>5)//等待>5MS

{

return 0;//初始化失败

}

}

return 1;//初始化成功

}


/*******************************************************************************

* 函 数 名         : Ds18b20WriteByte

* 函数功能    : 向18B20写入一个字节

* 输    入         : 无

* 输    出         : 无

*******************************************************************************/


void Ds18b20WriteByte(uchar dat)

{

uint i, j;


for(j=0; j<8; j++)

{

DSPORT = 0;         //每写入一位数据之前先把总线拉低1us

i++;

DSPORT = dat & 0x01;  //然后写入一个数据,从最低位开始

i=6;

while(i--); //延时68us,持续时间最少60us

DSPORT = 1; //然后释放总线,至少1us给总线恢复时间才能接着写入第二个数值

dat >>= 1;

}

}

/*******************************************************************************

* 函 数 名         : Ds18b20ReadByte

* 函数功能    : 读取一个字节

* 输    入         : 无

* 输    出         : 无

*******************************************************************************/



uchar Ds18b20ReadByte()

{

uchar byte, bi;

uint i, j;

for(j=8; j>0; j--)

{

DSPORT = 0;//先将总线拉低1us

i++;

DSPORT = 1;//然后释放总线

i++;

i++;//延时6us等待数据稳定

bi = DSPORT; //读取数据,从最低位开始读取

/*将byte左移一位,然后与上右移7位后的bi,注意移动之后移掉那位补0。*/

byte = (byte >> 1) | (bi << 7);   

i = 4; //读取完之后等待48us再接着读取下一个数

while(i--);

}

return byte;

}

/*******************************************************************************

* 函 数 名         : Ds18b20ChangTemp

* 函数功能    : 让18b20开始转换温度

* 输    入         : 无

* 输    出         : 无

*******************************************************************************/


void  Ds18b20ChangTemp()

{

Ds18b20Init();

Delay1ms(1);

Ds18b20WriteByte(0xcc); //跳过ROM操作命令  

Ds18b20WriteByte(0x44);     //温度转换命令

//Delay1ms(100); //等待转换成功,而如果你是一直刷着的话,就不用这个延时了

   

}

/*******************************************************************************

* 函 数 名         : Ds18b20ReadTempCom

* 函数功能    : 发送读取温度命令

* 输    入         : 无

* 输    出         : 无

*******************************************************************************/


void  Ds18b20ReadTempCom()

{


Ds18b20Init();

Delay1ms(1);

Ds18b20WriteByte(0xcc); //跳过ROM操作命令

Ds18b20WriteByte(0xbe); //发送读取温度命令

}

/*******************************************************************************

* 函 数 名         : Ds18b20ReadTemp

* 函数功能    : 读取温度

* 输    入         : 无

* 输    出         : 无

*******************************************************************************/


int Ds18b20ReadTemp()

{

int temp = 0;

uchar tmh, tml;

Ds18b20ChangTemp(); //先写入转换命令

Ds18b20ReadTempCom(); //然后等待转换完后发送读取温度命令

tml = Ds18b20ReadByte(); //读取温度值共16位,先读低字节

tmh = Ds18b20ReadByte(); //再读高字节

temp = tmh;

temp <<= 8;

temp |= tml;

return temp;

}


main.c


/*************************************************************************************


*

实验现象:下载程序后,在温度传感器接口处,按照丝印方向插好温度传感器,数码管就会显示

检测的温度值

  

接线说明: (具体接线图可见开发攻略对应实验的“实验现象”章节)

 

注意事项:


  

**************************************************************************************


*/


#include "reg52.h" //此文件中定义了单片机的一些特殊功能寄存器

#include"temp.h"


typedef unsigned int u16;   //对数据类型进行声明定义

typedef unsigned char u8;


sbit LSA=P2^2;

sbit LSB=P2^3;

sbit LSC=P2^4;



char num=0;

u8 DisplayData[8];

u8 code smgduan[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};


/*******************************************************************************

* 函 数 名         : delay

* 函数功能    : 延时函数,i=1时,大约延时10us

*******************************************************************************/

void delay(u16 i)

{

while(i--);

}



/*******************************************************************************

* 函 数 名         : datapros()

* 函数功能    : 温度读取处理转换函数

* 输    入         : temp

* 输    出         : 无

*******************************************************************************/


void datapros(int temp)  

{

    float tp;  

if(temp< 0) //当温度值为负数

  {

DisplayData[0] = 0x40;   //   -

//因为读取的温度是实际温度的补码,所以减1,再取反求出原码

temp=temp-1;

temp=~temp;

tp=temp;

temp=tp*0.0625*100+0.5;

//留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点

//后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就

//算加上0.5,还是在小数点后面。

 

  }

  else

  {

DisplayData[0] = 0x00;

tp=temp;//因为数据处理有小数点所以将温度赋给一个浮点型变量

//如果温度是正的那么,那么正数的原码就是补码它本身

temp=tp*0.0625*100+0.5;

//留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点

//后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就

//算加上0.5,还是在小数点后面。

}

DisplayData[1]=smgduan[temp/10000];

DisplayData[2]=smgduan[temp%10000/1000];

DisplayData[3]=smgduan[temp%10000%1000/100]|0X80;

DisplayData[4]=smgduan[temp%100/10];

DisplayData[5]=smgduan[temp%100%10];


}



/*******************************************************************************

* 函数名         :DigDisplay()

* 函数功能 :数码管显示函数

* 输入           : 无

* 输出          : 无

*******************************************************************************/

void DigDisplay()

{

u8 i;

for(i=0;i<6;i++)

{

switch(i) //位选,选择点亮的数码管,

{

case(0):

LSA=1;LSB=1;LSC=1; break;//显示第0位

case(1):

LSA=0;LSB=1;LSC=1; break;//显示第1位

case(2):

LSA=1;LSB=0;LSC=1; break;//显示第2位

case(3):

LSA=0;LSB=0;LSC=1; break;//显示第3位

case(4):

LSA=1;LSB=1;LSC=0; break;//显示第4位

case(5):

LSA=0;LSB=1;LSC=0; break;//显示第5位

}

P0=DisplayData[i];//发送数据

delay(100); //间隔一段时间扫描

P0=0x00;//消隐

}

}


/*******************************************************************************

* 函 数 名       : main

* 函数功能 : 主函数

* 输    入       : 无

* 输    出    : 无

*******************************************************************************/

void main()

{

while(1)

{

datapros(Ds18b20ReadTemp()); //数据处理函数

DigDisplay();//数码管显示函数

}

}

关键字:51单片机  DS1302时钟 引用地址:51单片机~DS1302时钟,SPI总线原理

上一篇:51单片机~红外通信工作原理
下一篇:51单片机~DS18B20温度传感器

热门资源推荐
热门放大器推荐
    系统发生错误

    系统发生错误

    您可以选择 [ 重试 ] [ 返回 ] 或者 [ 回到首页 ]

    [ 错误信息 ]

    页面错误!请稍后再试~

小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
  • 学习ARM开发(16)
    ARM有很多东西要学习,那么中断,就肯定是需要学习的东西。自从CPU引入中断以来,才真正地进入多任务系统工作,并且大大提高了工作效率。采 ...
  • 学习ARM开发(17)
    因为嵌入式系统里全部要使用中断的,那么我的S3C44B0怎么样中断流程呢?那我就需要了解整个流程了。要深入了解,最好的方法,就是去写程序 ...
  • 学习ARM开发(18)
    上一次已经了解ARM的中断处理过程,并且可以设置中断函数,那么它这样就可以工作了吗?答案是否定的。因为S3C44B0还有好几个寄存器是控制中 ...
  • 嵌入式系统调试仿真工具
    嵌入式硬件系统设计出来后就要进行调试,不管是硬件调试还是软件调试或者程序固化,都需要用到调试仿真工具。 随着处理器新品种、新 ...
  • 最近困扰在心中的一个小疑问终于解惑了~~
    最近在驱动方面一直在概念上不能很好的理解 有时候结合别人写的一点usb的例子能有点感觉,但是因为arm体系里面没有像单片机那样直接讲解引脚 ...
  • 学习ARM开发(1)
  • 学习ARM开发(2)
  • 学习ARM开发(4)
  • 学习ARM开发(6)
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved