单片机学习小组
直播中

663597

12年用户 463经验值
私信 关注

怎样去实现基于单片机CT107D的底层驱动代码程序呢

怎样去实现基于单片机CT107D的底层驱动代码程序呢?

回帖(1)

王丽丽

2022-2-25 11:31:50
软件环境: Keil uVision 4.10
硬件环境: CT107单片机综合实训平台 8051,12MHz


1.SPI:

//SPI.h
#ifndef __DS1302_H
#define __DS1302_H

#include

***it SCLK = P1^7;
***it RST = P1^3;
***it DSIO = P2^3;

void DS1302_WriteByte(unsigned char addr, unsigned char dat);  //单字节写的时序
unsigned char DS1302_ReadByte(unsigned char addr);   //单字节读的时序

#endif


//SPI.c
#include"SPI.h"

//单字节写的时序
void DS1302_WriteByte(unsigned char addr, unsigned char dat)
{
        unsigned char n;
           RST = 0;
    _nop_();
    SCLK = 0;
    _nop_();
    RST = 1;
    _nop_();        

    for (n=0; n<8; n++)         //发送要写入数据的内存地址
    {
                DSIO = addr & 0x01;
                addr >>= 1;
                SCLK = 1;
                _nop_();
                SCLK = 0;
                _nop_();
        }
    for (n=0; n<8; n++)         //将指定内容写入该地址的内存
    {
                DSIO = dat & 0x01;
                dat >>= 1;
                SCLK = 1;
                _nop_();
                SCLK = 0;
                _nop_();
    }                 
        RST = 0;
    _nop_();
}

//单字节读的时序
unsigned char DS1302_ReadByte(unsigned char addr)
{
        unsigned char n,dat,tmp;
        RST = 0;
        _nop_();
        SCLK = 0;
        _nop_();
        RST = 1;
        _nop_();

    for(n=0; n<8; n++)         //发送要读出数据的内存地址
        {
                DSIO = addr & 0x01;
                addr >>= 1;
                SCLK = 1;
                _nop_();
                SCLK = 0;
                _nop_();
        }
               
        for(n=0; n<8; n++)         //读出该地址内存的数据
        {
                tmp = DSIO;
                dat = (dat>>1) | (tmp<<7);
                SCLK = 1;
                _nop_();
                SCLK = 0;
                _nop_();
        }
      
        RST = 0;
        _nop_();
        SCLK = 1;
        _nop_();
        DSIO = 0;
        _nop_();
        DSIO = 1;
        _nop_();
        //dat = (((dat>>4)*10) | (dat%16));
        return dat;        
}


2.IIC:

//IIC.h
#ifndef __IIC_H
#define __IIC_H

#include

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

void Delay_IIC(unsigned char t);        //延时函数
void IIC_Start(void);                   //起始信号
void IIC_Stop(void);                    //停止信号
void IIC_Ack(unsigned char ackbit);     //产生应答
bit IIC_WaitAck(void);                  //等待应答
void IIC_SendByte(unsigned char byte);        //发送数据
unsigned char IIC_RecByte(void);        //接收数据

#endif


//IIC.c
#include"IIC.h"

void Delay_IIC(unsigned char time)
{
        while(time--);
}

void IIC_Start(void)
{
        SDA = 1;
        SCL = 1;
        Delay_IIC(5);
        SDA = 0;        //在SCL高电平期间,SDA由高变低
        Delay_IIC(5);
        SCL = 0;      
}

void IIC_Stop(void)
{
        SDA = 0;
        SCL = 1;
        Delay_IIC(5);
        SDA = 1;        //在SCL高电平期间,SDA由高变低
        Delay_IIC(5);
}

void IIC_Ack(unsigned char ackbit)
{
        if(ackbit)        
                SDA = 0;        //产生应答信号
        else
                SDA = 1;        //产生非应答信号
        Delay_IIC(5);
        SCL = 1;
        Delay_IIC(5);                //第9个时钟周期
        SCL = 0;
        SDA = 1;                 //释放SDA线
        Delay_IIC(5);
}

bit IIC_WaitAck(void)
{
        SDA = 1;
        Delay_IIC(5);
        SCL = 1;
        Delay_IIC(5);      

        if(SDA)                    //在SCL高电平期间,SDA为高电平,从机非应答。
        {   
                SCL = 0;
                IIC_Stop();
                return 0;
        }
        else                         //在SCL高电平期间,SDA为低电平,从机有应答。
        {
                SCL = 0;
                return 1;
        }      
}

void IIC_SendByte(unsigned char byt)
{
        unsigned char i;
        for(i=0;i<8;i++)                //循环发送8位数据
        {   
                if(byt & 0x80)                 //数据位是高电平
                {      
                        SDA = 1;
                }
                else                         //数据位是低电平
                {
                        SDA = 0;
                }

                Delay_IIC(5);
                SCL = 1;                //SCL高电平期间,SDA的数据要保持稳定
                byt <<= 1;                //发送的数据左移,准备发送下一位
                Delay_IIC(5);                //等待SDA的数据被读取
                SCL = 0;
        }
}

unsigned char IIC_RecByte(void)
{
        unsigned char da;
        unsigned char i;
        for(i=0;i<8;i++)
        {   
                SCL = 1;
                Delay_IIC(5);                //在SCL高电平期间,读取SDA的数据
                da <<= 1;
                if(SDA)
                        da |= 0x01;
                SCL = 0;
                Delay_IIC(5);
        }
        return da;
}


3.Onewire:

//onewire.h
#ifndef _ONEWIRE_H
#define _ONEWIRE_H

#include

#define OW_SKIP_ROM 0xcc
#define DS18B20_CONVERT 0x44
#define DS18B20_READ 0xbe

//定义引脚
***it DQ = P1^4;

//函数声明
void Delay_OneWire(unsigned int t);
bit Init_DS18B20(void);
void Write_DS18B20(unsigned char dat);
unsigned char Read_DS18B20(void);

#endif


//onewire.c
#include"onewire.h"

//单总线延时函数
void Delay_OneWire(unsigned int t)
{
        while(t--);
}

//DS18B20芯片初始化
bit Init_DS18B20(void)
{
        bit initflag = 0;
        DQ = 0;
        Delay_OneWire(200);       //拉低总线480us以上
        DQ = 1;                   //然后释放总线
        Delay_OneWire(20);        //等待15—60us
        initflag = DQ;            //读取DS18B20复位应答信号
        Delay_OneWire(100);       //等待60—240us后释放总线

        return initflag;          //应答信号为低电平,表示复位成功
}

//DS18B20写操作
void Write_DS18B20(unsigned char dat)
{
        unsigned char i;
        for(i=0;i<8;i++)
        {
                DQ = 0;               //将总线拉低10—15us
                DQ = dat & 0x01;      //想总线写数据
                Delay_OneWire(20);    //维持20—45us
                DQ = 1;               //释放总线
                dat >>= 1;            //右移一位,发送下一位数据
        }
}

//DS18B20读时序
unsigned char Read_DS18B20(void)
{
        unsigned char i,dat;
        for(i=0;i<8;i++)
        {
                DQ = 0;               //将总线拉低10—15us
                dat >>= 1;            //右移
                DQ = 1;               //释放总线
                if(DQ)                                  //读取总线上的电平,如果为高电平则读1
                {
                        dat |= 0x80;
                }
                Delay_OneWire(20);    //延时45us,再度下一位
        }
        return dat;
}
举报

更多回帖

发帖
×
20
完善资料,
赚取积分