找回密码
 立即注册

QQ登录

只需一步,快速开始

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

蓝桥杯第四届省赛部分驱动代码

[复制链接]
跳转到指定楼层
楼主
ID:386213 发表于 2018-8-14 15:43 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include "ds1302.h"
#include <STC15F2K60S2.H>


#include<intrins.h>   //包含_nop_()函数定义的头文件

/***********************************************************************
以下是DS1302芯片的操作程序
************************************************************************/

int ReadValue;
/*****************************************************
函数功能:延时若干微秒
入口参数:n
***************************************************/
void delaynus(unsigned char t)
{
        unsigned int i;

        _nop_();
        _nop_();
        i = 3*t-3 ;
        while (--i);
}
/*****************************************************
函数功能:向1302写一个字节数据
入口参数:x
***************************************************/
void Write1302(unsigned char dat)
{
  unsigned char i;
  SCLK=0;            //拉低SCLK,为脉冲上升沿写入数据做好准备
  delaynus(2);       //稍微等待,使硬件做好准备
  for(i=0;i<8;i++)      //连续写8个二进制位数据
    {
            DATA=dat&0x01;    //取出dat的第0位数据写入1302
                delaynus(2);       //稍微等待,使硬件做好准备
                 SCLK=1;           //上升沿写入数据
                 delaynus(2);      //稍微等待,使硬件做好准备
                 SCLK=0;           //重新拉低SCLK,形成脉冲
                 dat>>=1;          //将dat的各数据位右移1位,准备写入下一个数据位
          }       
}
/*****************************************************
函数功能:根据命令字,向1302写一个字节数据
入口参数:Cmd,储存命令字;dat,储存待写的数据
***************************************************/
void WriteSet1302(unsigned char Cmd,unsigned char dat)
{
   RST=0;           //禁止数据传递
   SCLK=0;          //确保写数居前SCLK被拉低
        RST=1;           //启动数据传输
        delaynus(2);     //稍微等待,使硬件做好准备
        Write1302(Cmd);  //写入命令字
        Write1302(dat);  //写数据
        SCLK=1;          //将时钟电平置于已知状态
        RST=0;           //禁止数据传递
}
/*****************************************************
函数功能:从1302读一个字节数据
入口参数:x
***************************************************/
unsigned char Read1302(void)
{
   unsigned char i,dat;
        delaynus(2);       //稍微等待,使硬件做好准备
        for(i=0;i<8;i++)   //连续读8个二进制位数据
         {
           dat>>=1;       //将dat的各数据位右移1位,因为先读出的是字节的最低位
                if(DATA==1)    //如果读出的数据是1
                 dat|=0x80;    //将1取出,写在dat的最高位
                 SCLK=1;       //将SCLK置于高电平,为下降沿读出
                 delaynus(2);  //稍微等待
                 SCLK=0;       //拉低SCLK,形成脉冲下降沿
                 delaynus(2);  //稍微等待
          }         
  return dat;        //将读出的数据返回
}  
/*****************************************************
函数功能:根据命令字,从1302读取一个字节数据
入口参数:Cmd
***************************************************/
unsigned char  ReadSet1302(unsigned char Cmd)
{
  unsigned char dat;
  EA=0;
  RST=0;                 //拉低RST
  SCLK=0;                //确保写数居前SCLK被拉低
  RST=1;                 //启动数据传输
  Write1302(Cmd);       //写入命令字
  dat=Read1302();       //读出数据
  SCLK=1;              //将时钟电平置于已知状态
  RST=0;               //禁止数据传递
  EA=1;
  return dat;          //将读出的数据返回
}
/*****************************************************
函数功能:DS1302是否写保护        =1,写保护   =0,不写保护
入口参数:flag
***************************************************/
void DS1302_SetProtect(bit flag)        //是否写保护
{
        if(flag)
                WriteSet1302(0x8E,0x10); //WP=1,不能写入
        else
                WriteSet1302(0x8E,0x00);//WP=0,可以写入
}
/*****************************************************
函数功能:设置时间函数
入口参数:Address,Value
Address = 0x8c(年的地址)  0x88(月) 0x86(日)
                  0x84(时的地址)  0x82(月) 0x80(日)
***************************************************/
void DS1302_SetTime(unsigned char Address, unsigned char Value)        // 设置时间函数
{
        DS1302_SetProtect(0);
        WriteSet1302(Address, ((Value/10)<<4 | (Value%10))); //高4位为十位,低4位为个位
}
/*****************************************************
函数功能: 1302进行初始化设置
***************************************************/
void Init_DS1302(void)
{        EA = 0;
    WriteSet1302(0x8E,0x00);                 //根据写状态寄存器命令字,写入不保护指令
    WriteSet1302(0x80,((12/10)<<4|(12%10)));   //根据写秒寄存器命令字,写入秒的初始值
        WriteSet1302(0x82,((12/10)<<4|(12%10)));   //根据写分寄存器命令字,写入分的初始值
        WriteSet1302(0x84,((12/10)<<4|(12%10))); //根据写小时寄存器命令字,写入小时的初始值
        WriteSet1302(0x86,((12/10)<<4|(12%10))); //根据写日寄存器命令字,写入日的初始值
        WriteSet1302(0x88,((12/10)<<4|(12%10))); //根据写月寄存器命令字,写入月的初始值
        WriteSet1302(0x8c,((12/10)<<4|(12%10)));   //根据写小时寄存器命令字,写入小时的初始值
        WriteSet1302(0x8E,0x10);
        EA = 1;
}
/*********************************************
函数功能:设置初始时间2017年2月28 16点52分0秒
*********************************************/

void Init_DS1302_Time(void)
{        EA = 0;
        WriteSet1302(0x8E,0x00);
        DS1302_SetTime(0x8c,17);//17年
        DS1302_SetTime(0x88,2);//2月
        DS1302_SetTime(0x86,28);//28日
        DS1302_SetTime(0x84,8);//16时
        DS1302_SetTime(0x82,30);//50分
        DS1302_SetTime(0x80,0);//0秒
        WriteSet1302(0x8E,0x10);
        EA = 1;
}

char ds1302_year()
{          
          char year;
          EA = 0;
          ReadValue = ReadSet1302(0x8d);  //从年寄存器读
      year=((ReadValue&0xf0)>>4)*10 + (ReadValue&0x0F); //将读出数据转化
          EA = 1;
          if(year)
          return(year);              //显示年
}

char ds1302_month()
{          
          char month;
          EA = 0;
          ReadValue = ReadSet1302(0x89);  //从年寄存器读
      month=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化
          EA = 1;
          if(month)
          return(month);              //显示年
}

char ds1302_day()
{          
          char day;
          EA = 0;
          ReadValue = ReadSet1302(0x87);  //从年寄存器读
      day=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化
          EA = 1;
          if(day)
          return(day);              //显示年
}


char ds1302_hour()
{          
          char hour;
          EA = 0;
          ReadValue = ReadSet1302(0x85);  //从年寄存器读
      hour=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化
          EA = 1;
          if(hour)
          return(hour);              //显示年
}

char ds1302_minute()
{          
          char minute;       
          EA=0;
          ReadValue = ReadSet1302(0x83);  //从年寄存器读
      minute=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化
          EA=1;
          if(minute)         
          return(minute);              //显示年
}

char ds1302_second()
{          
          char second;
          EA=0;
          ReadValue = ReadSet1302(0x81);  //从年寄存器读
      second=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化
          EA=1;
          if(second)
          return(second);              //显示年
}

#ifndef _DS1302_H
#define _DS1302_H

#include <STC15F2K60S2.H>


sbit DATA=P2^3;   //位定义1302芯片的接口,数据输出端定义在P1.1引脚
sbit RST=P1^3;    //位定义1302芯片的接口,复位端口定义在P1.1引脚
sbit SCLK=P1^7;   //位定义1302芯片的接口,时钟输出端口定义在P1.1引脚

void delaynus(unsigned char n);//延时若干微秒
void Write1302(unsigned char dat);//向1302写一个字节数据
void WriteSet1302(unsigned char Cmd,unsigned char dat);//根据命令字,向1302写一个字节数据
unsigned char Read1302(void);//从1302读一个字节数据
unsigned char  ReadSet1302(unsigned char Cmd);//根据命令字,从1302读取一个字节数据

void DS1302_SetProtect(bit flag);//DS1302是否写保护        =1,写保护   =0,不写保护
void DS1302_SetTime(unsigned char Address, unsigned char Value);//设置时间函数

void Init_DS1302(void);//1302进行初始化设置
void Init_DS1302_Time(void);//设置初始时间2017年2月28 16点52分0秒

char ds1302_second();//秒
char ds1302_minute();//分
char ds1302_hour();//时
char ds1302_day();//日
char ds1302_month();//月
char ds1302_year();//年



#endif


#include "I2C.h"

#define somenop Delay5us()

void Delay5us()                //@11.0592MHz
{
        unsigned char i;

        _nop_();
        i = 11;
        while (--i);
}

void lIC_Init()
{       
//                EA=0;
                SCL=0;
                IIC_Stop();
//                EA=1;
}

//总线启动条件
void IIC_Start(void)
{
        EA=0;
        SDA = 1;
        SCL = 1;
        somenop;
        SDA = 0;
        somenop;
        SCL = 0;
        EA=1;       
}

//总线停止条件
void IIC_Stop(void)
{
        EA=0;
        SCL = 0;
        SDA = 0;
        somenop;
        SCL = 1;
        somenop;
        SDA = 1;
        EA=1;
}

//应答位控制  //ackbit   =1,应答  =0,非应答
void IIC_Ack(unsigned char ackbit)
{
        if(ackbit)
        {       
                SDA = 0;
        }
        else
        {
                SDA = 1;
        }
        somenop;
        SCL = 1;
        somenop;
        SCL = 0;
        SDA = 1;
        somenop;
}

//等待应答
bit IIC_WaitAck(void)
{
        SDA = 1;
        somenop;
        SCL = 1;
        somenop;
        if(SDA)   
        {   
                SCL = 0;
                IIC_Stop();
                return 1;
        }
        else  
        {
                SCL = 0;
                return 0;
        }
}


//通过I2C总线发送数据 //eeprom专用        // 用于从机应答
bit IIC_SendByte_ep(unsigned char byt)
{       
        unsigned char i;
        bit ack;
        EA=0;
        for(i=0;i<8;i++)
        {   
                if(byt&0x80)
                {       
                        SDA = 1;
                }
                else
                {
                        SDA = 0;
                }
                somenop;
                SCL = 1;
                byt <<= 1;
                somenop;
                SCL = 0;
        }
        SDA=1;       
        somenop;
        SCL=1;
        ack=SDA;
        somenop;
        SCL=0;
        EA=1;
        return (~ack);
}

//通过I2C总线发送数据
void IIC_SendByte(unsigned char byt)
{       
        unsigned char i;

        EA=0;
        for(i=0;i<8;i++)
        {   
                if(byt&0x80)
                {       
                        SDA = 1;
                }
                else
                {
                        SDA = 0;
                }
                somenop;
                SCL = 1;
                byt <<= 1;
                somenop;
                SCL = 0;
        }
        EA=1;
}

//从I2C总线上接收数据
unsigned char IIC_RecByte(void)
{
        unsigned char da;
        unsigned char i;
        EA=0;
        for(i=0;i<8;i++)
        {   
                SCL = 1;
                somenop;
                da <<= 1;
                if(SDA)
                da |= 0x01;
                SCL = 0;
                somenop;
        }EA=1;
        return da;
}
#ifndef I2C_H
#define I2C_H
#include <STC15F2K60S2.H>

#include <intrins.h>

sbit SDA = P2^1;  /* 数据线 */
sbit SCL = P2^0;  /* 时钟线 */


void Delay5us(); //延时5us

void lIC_Init();
void IIC_Start(void);//总线启动条件
void IIC_Stop(void);//总线停止条件

void IIC_Ack(unsigned char ackbit);//应答位控制         //ackbit   =1,应答  =0,非应答
bit IIC_WaitAck(void);//等待应答        //返回值 =1,错误 =0,正常


bit IIC_SendByte_ep(unsigned char byt);        //通过I2C总线发送数据 //eeprom专用        // 用于从机应答
void IIC_SendByte(unsigned char byt); //通过I2C总线发送数据

unsigned char IIC_RecByte(void);//从I2C总线上接收数据



#endif




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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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