找回密码
 立即注册

QQ登录

只需一步,快速开始

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

51单片机ds3231+ds18b20+lcd12864

[复制链接]
跳转到指定楼层
楼主
ID:456780 发表于 2019-3-18 15:55 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 qkl189 于 2019-3-18 19:36 编辑


用的IIC通信,写的一个ds3231时钟模块的程序,可更改时间,下面是.h文件里面的部分代码

#ifndef __ds3231_h
#define __ds3231_h_
#include <reg51.h>
#define uchar   unsigned char  
#define uint    unsigned int
extern uchar day2,Htemp2,Mtemp2,Stemp2;         //星期,时分秒
extern ucharYtemp2,Mtemp2,Dtemp2,Ttemp2,Ttemp4; //年月日,温度的数据,需要先调用处理函数
void delayus(uint us);      
void Start_I2C();
void Stop_I2C();
void SendByte(uchar c);
void Ack_I2C(bit a);
void ModifyTime(uchar yea,uchar mon,uchar da,uchar day,uchar hou,uchar min,uchar sec); //修改年月日星期时分秒
void get_show_day(void);    //星期
void get_show_time(void);   //时分秒
void get_show_date(void);   //年月日
void get_show_Temperature(void);  //温度

#endif

这是.c文件里面的程序
#include <reg51.h>
#include <intrins.h>
#include "ds3231.h"

sbit SDA=P0^3;     //模拟I2C数据传送位SDA        
sbit SCL=P0^1;     //模拟I2C时钟控制位SCL     
sbit RESET=P0^2;
uchar day2,Htemp2,Mtemp2,Stemp2,Ytemp2,Mtemp2,Dtemp2,Ttemp2,Ttemp4;
bit  ack;          //应答标志位

uchar BCD2HEX(uchar val)    //BCD转换为Byte
{
        uchar temp;
        temp=val&0x0f;
        val>>=4;
        val&=0x0f;
        val*=10;
        temp+=val;   
        return temp;
}


uchar HEX2BCD(uchar val)    //B码转换为BCD码
{
        uchar i,j,k;
        i=val/10;
        j=val%10;
        k=j+(i<<4);
        return k;
}


void delayus(uint us)
{
  while(us--);
}

void Start_I2C()
{
        SDA=1;                  //发送起始条件的数据信号
        delayus(1);
        SCL=1;
        delayus(5);             //起始条件建立时间大于4.7us,延时
        SDA=0;                  //发送起始信号
        delayus(5);             // 起始条件锁定时间大于4μs      
        SCL=0;                  //钳住I2C总线,准备发送或接收数据
        delayus(2);
}


void Stop_I2C()
{
        SDA=0;                  //发送结束条件的数据信号
        delayus(1);             //发送结束条件的时钟信号
        SCL=1;                  //结束条件建立时间大于4us
        delayus(5);   
        SDA=1;                  //发送I2C总线结束信号
        delayus(4);
}

void SendByte1(uchar c)
{
        uchar BitCnt;
        for(BitCnt=0;BitCnt<8;BitCnt++)         //要传送的数据长度为8位
        {
                if((c<<BitCnt)&0x80)
                        SDA=1;                          //判断发送位
                else
                        SDA=0;               
                delayus(1);
                SCL=1;                            //置时钟线为高,通知被控器开始接收数据位
                delayus(5);                       //保证时钟高电平周期大于4μs   
                SCL=0;
        }
        delayus(2);
        SDA=1;                                  //8位发送完后释放数据线,准备接收应答位
        delayus(2);  
        SCL=1;
        delayus(3);
        if(SDA==1)
                ack=0;   
        else
                ack=1;                              //判断是否接收到应答信号
        SCL=0;
        delayus(2);
}

uchar RcvByte()
{
        uchar retc;
        uchar BitCnt;
        retc=0;
        SDA=1;                           //置数据线为输入方式
        for(BitCnt=0;BitCnt<8;BitCnt++)
        {
                delayus(1);  
                SCL=0;                      //置时钟线为低,准备接收数据位      
                delayus(5);                 //时钟低电平周期大于4.7μs      
                SCL=1;                      //置时钟线为高使数据线上数据有效
                delayus(3);
                retc=retc<<1;
                if(SDA==1)
                                retc=retc+1;            //读数据位,接收的数据位放入retc中
                delayus(2);
        }
        SCL=0;
        delayus(2);
        return(retc);
}

void Ack_I2C(bit a)
{
        if(a==0)
                SDA=0;              //在此发出应答或非应答信号
        else
                SDA=1;
        delayus(3);     
        SCL=1;  
        delayus(5);             //时钟低电平周期大于4μs   
        SCL=0;                  //清时钟线,钳住I2C总线以便继续接收
        delayus(2);   
}

uchar write_byte(uchar addr, uchar write_data)
{
        Start_I2C();
        SendByte1(0xd0);
        if (ack == 0)
                return 0;   
        SendByte1(addr);   
        if (ack == 0)
                return 0;   
        SendByte1(write_data);
        if (ack == 0)
                return 0;   
        Stop_I2C();
        delayus(10);      
        return 1;
}

uchar read_current()
{
        uchar read_data;
        Start_I2C();
        SendByte1(0xd1);
        if(ack==0)
                return(0);   
        read_data = RcvByte();
        Ack_I2C(1);
        Stop_I2C();
        return read_data;
}

uchar read_random(uchar random_addr)
{
        Start_I2C();
        SendByte1(0xd0);
        if(ack==0)
                return(0);  
        SendByte1(random_addr);
        if(ack==0)
                return(0);   
        return(read_current());
}

void ModifyTime(uchar yea,uchar mon,uchar da,uchar day,uchar hou,uchar min,uchar sec)
{
        uchar temp=0;
        temp=HEX2BCD(yea);
        write_byte(0x06,temp);   //修改年  
        temp=HEX2BCD(mon);
        write_byte(0x05,temp);  //修改月
        temp=HEX2BCD(da);
        write_byte(0x04,temp);    //修改日
        temp=HEX2BCD(day);
        write_byte(0x03,temp);
        temp=HEX2BCD(hou);
        write_byte(0x02,temp);   //修改时
        temp=HEX2BCD(min);
        write_byte(0x01,temp); //修改分  
        temp=HEX2BCD(sec);
        write_byte(0x00,temp); //修改秒
}

void get_show_day(void)
{
        uchar day1;
        day1=read_random(0x03);        //星期
        day2=BCD2HEX(day1);
}

void get_show_time(void)
{
        uchar Htemp1,Mtemp1,Stemp1;
        Htemp1=read_random(0x02);    //时 24小时制
        Htemp1&=0x3f;
        Htemp2=BCD2HEX(Htemp1);  
        Mtemp1=read_random(0x01);  //分
        Mtemp2=BCD2HEX(Mtemp1);
        Stemp1=read_random(0x00);  //秒
        Stemp2=BCD2HEX(Stemp1);
}

void get_show_date(void)
{
        uchar Ytemp1,Mtemp1,Dtemp1;   
        Ytemp1=read_random(0x06);        //年
        Ytemp2=BCD2HEX(Ytemp1);   
        Mtemp1=read_random(0x05);       //月
        Mtemp2=BCD2HEX(Mtemp1);   
        Dtemp1=read_random(0x04);         //日
        Dtemp2=BCD2HEX(Dtemp1);
}

void get_show_Temperature(void)
{
        uchar Ttemp1,Ttemp3;   
        Ttemp1=read_random(0x11);    //温度高字节
        Ttemp2=BCD2HEX(Ttemp1);
        Ttemp3=read_random(0x12);    //温度低字节
        Ttemp4=BCD2HEX(Ttemp3);
        
}
可以读取温度数据。做了两天写出来的,如果有什么不足的还请多多指教。该程序通过单片机模拟串口进行读取ds3231时钟芯片的数据,然后通过LCD12864液晶显示屏进行显示,同时还添加了温度传感器


时钟显示.rar

73.62 KB, 下载次数: 93, 下载积分: 黑币 -5

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

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

使用道具 举报

沙发
ID:456780 发表于 2019-3-18 15:57 | 只看该作者
如果有什么不足的还希望各位大神指出
回复

使用道具 举报

板凳
ID:1 发表于 2019-3-18 18:22 | 只看该作者
本帖需要重新编辑补全电路原理图,源码,详细说明与图片即可获得100+黑币(帖子下方有编辑按钮)
回复

使用道具 举报

地板
ID:96881 发表于 2020-3-19 22:42 | 只看该作者
先谢谢您分享,我先下载来试着画原理图并洞洞板试验一下,然后再来补充原理图,谢谢
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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