1512|0

6893

帖子

0

TA的资源

五彩晶圆(高级)

楼主
 

MSP430G2553 连接 SD30系列 C程序(供参考) [复制链接]

本帖最后由 Jacktang 于 2018-1-23 22:34 编辑

/***********************************************************************
*             MSP430G2553 连接 SD30系列 C程序(供参考)
*  DCO:1Mhz
*  占用2个IO: P1.4  P1.5
*  特别感谢Mr.Ray提供此程序
*  此程序在Mr.Ray提供的程序上修改
*  2014.07.01
***********************************************************************/
#include
#include "dco_1m_delay.h"              //延时程序,可以自写
#include "uart.h"                      //串口调试,可以去掉


#define uchar unsigned char
#define uint  unsigned int
/***********************************************************************
***函数定义
***********************************************************************/
uchar I2CStart(void);
uchar I2CWaitAck(void) ;
uchar I2CReceiveByte(void);

void I2CStop(void);
void I2CAck(void);
void I2CNoAck(void);
void I2CSendByte(uchar Byte);
void I2CReadDate(void);
void WriteTimeOn(void);
void WriteTimeOff(void);
void I2CWriteDate(void);

/***********************************************************************
***P1.5 SDA
***********************************************************************/
#define SDA_IN      P1DIR &=~ BIT5     //输入
#define SDA_OUT     P1DIR |= BIT5      //输出
#define SDA_H       P1OUT |= BIT5      //SDA = 1;     
#define SDA_L       P1OUT &= ~BIT5     //SDA = 0;     
#define SDA_Read    (P1IN & BIT5)      //数据读取  




/***********************************************************************
***P1.4 SCL
***********************************************************************/
#define SCL_IN      P1DIR&=~BIT4    //输入
#define SCL_OUT     P1DIR|=BIT4     //输出
#define SCL_H       P1OUT |= BIT4       //SCL = 1;      
#define SCL_L       P1OUT &= ~BIT4      //SCL = 0;     
#define SCL_Read    (P1IN & BIT4)       //时钟读取



/**********************************************************************
*返回值定义
***********************************************************************/
#define true  1
#define false 0




/**********************************************************************
*初始化时间InitTime 依次为:年、月、日、星期、时、分、秒。
*默认:13年12月31日23时59分50秒
***********************************************************************/
uchar   ReadTime[7]; //用于存放读取数值
uchar   InitTime[7]={0x13,0x12,0x31,0x02,0x23,0x59,0x50};


uchar     bat1,bat2;//电池电量
uint      bat;       //电池电量值

/**********************************************************************
*开启 SD30系列 的 I2C 总线
***********************************************************************/
uchar I2CStart(void)
{
        SDA_OUT;SCL_OUT;
    _NOP();
        SDA_H;SCL_H;   
    _NOP();_NOP();
    SDA_IN;
    _NOP();_NOP();
    if(!SDA_Read)return false;  //总线忙-->>退出
    SDA_OUT;
    _NOP();
    SDA_L;  
    _NOP();_NOP();
    SDA_IN;     
    _NOP();_NOP();
    while(SDA_Read)return false;    //总线出错-->>退出
    SCL_L;  
    _NOP();_NOP();
    return true;

}

/**********************************************************************
*关闭 SD30系列 的 I2C 总线
***********************************************************************/

void I2CStop(void)
{
        SCL_OUT;SDA_OUT;
    _NOP();
    SDA_L;
    _NOP();
    SCL_L;
    _NOP();_NOP();
    SCL_H;
    _NOP();_NOP();
    SDA_H;
}

/**********************************************************************
*发送 ACK
***********************************************************************/
void I2CAck(void)
{   
        SCL_OUT;SDA_OUT;
    _NOP();_NOP();
    SDA_L;  
    _NOP();_NOP();
    SCL_L;  
    _NOP();_NOP();
    SCL_H;  
    _NOP();_NOP();
    SCL_L;  
}

/**********************************************************************
*发送 NO ACK
***********************************************************************/
void I2CNoAck(void)
{   
        SCL_OUT;SDA_OUT;
    _NOP();
    SDA_H;  
    _NOP();
    SCL_L;  
    _NOP();_NOP();
    SCL_H;  
    _NOP();_NOP();
    SCL_L;  
}

/**********************************************************************
*读取ACK信号--------返回值:  1 --> 有ACK;  0 --> 无ACK
***********************************************************************/

uchar I2CWaitAck(void)           //返回为:1=有ACK,0=无ACK
{
    uchar Wait=255;
    SCL_OUT;
    SDA_IN;
    _NOP();
    SCL_L;  
    _NOP();_NOP();
    SCL_H;  
    _NOP();
    SDA_IN;
    _NOP();
    while(SDA_Read)
    {
        Wait--;
        _NOP();
        if(!Wait)
        {_NOP();_NOP();
        SCL_L;
        return false;
                 }
    }
    SCL_L;  
    return true;
}
/**********************************************************************
*MCU 向 SD30系列 发送一个字节------数据从高位到低位
***********************************************************************/     
void I2CSendByte(uchar Byte)        
{
    uchar bd=8;                                                        
    SDA_OUT;
    SCL_OUT;
        while(bd--)
        {
            SCL_L;  
            _NOP();
            if(Byte&0x80)
            {SDA_H;}
             else
            {SDA_L;}
            Byte<<=1;
            _NOP();
            SCL_H;
            _NOP();
        }
        SCL_L;  
}
/**********************************************************************
*MCU 从 SD30系列 读取一个字节------数据从高位到低位
***********************************************************************/  
uchar I2CReceiveByte(void)      
{
    uchar i=8;
    uchar Byte=0;
    SCL_OUT;
    _NOP();
    _NOP();
    SDA_IN;             //c51中为SDA=1;端口切换为输入状态!!
    _NOP();
    while(i--)
    {
        Byte<<=1;              //数据从高位开始读取
        _NOP();
        SCL_L;
        _NOP();_NOP();         
        SCL_H;
        _NOP();_NOP();  
        if(SDA_Read)
        {
            Byte|=0x01;    //非零写1,否则移位,默认为0
        }
    }
    SCL_L;
    return Byte;
}
/**********************************************************************
*读 SD30系列 实时数据寄存器(就是读取时间)
***********************************************************************/  
void I2CReadDate(void)
{
    uchar n;
    I2CStart();
    I2CSendByte(0x65);
    I2CWaitAck();
    for(n=0;n<7;n++)
    {
        ReadTime[n]=I2CReceiveByte();
        if (n!=6)            //最后一个数据不应答
        {
            I2CAck();
        }
    }
    I2CNoAck();
    _NOP();
    I2CStop();
}
/**********************************************************************
*允许写入SD30
***********************************************************************/  
void WriteTimeOn(void)
{      
    I2CStart();
    I2CSendByte(0x64);      
    I2CWaitAck();   
        I2CSendByte(0x10);      //设置写地址10H      
    I2CWaitAck();   
    I2CSendByte(0x80);      //置WRTC1=1      
    I2CWaitAck();
    I2CStop();

    I2CStart();
    I2CSendByte(0x64);      
    I2CWaitAck();   
        I2CSendByte(0x0F);      //设置写地址0FH      
    I2CWaitAck();   
    I2CSendByte(0xFF);      //置WRTC2,WRTC3=1      
    I2CWaitAck();
    I2CStop();

}

/**********************************************************************
*禁止写入SD30
***********************************************************************/  
void WriteTimeOff(void)
{   
    I2CStart();
    I2CSendByte(0x64);      
    I2CWaitAck();   
    I2CSendByte(0x0F);      //设置写地址0FH      
    I2CWaitAck();   
    I2CSendByte(0x7B) ;     //置WRTC2,WRTC3=0      
    I2CWaitAck();
    I2CSendByte(0x0) ;      //置WRTC1=0(10H地址)      
    I2CWaitAck();
    I2CStop();
}
/**********************************************************************
*写SD30系列实时数据寄存器(初始化值以及修改可用)
***********************************************************************/  
void I2CWriteDate(void)
{      

        WriteTimeOn();              //首先得允许写入

    I2CStart();
    I2CSendByte(0x64);      
    I2CWaitAck();   
        I2CSendByte(0x00);          //设置写起始地址      
    I2CWaitAck();   
    I2CSendByte(InitTime[6]);       //秒   
    I2CWaitAck();   
    I2CSendByte(InitTime[5]);       //分      
    I2CWaitAck();   
    I2CSendByte(InitTime[4]|0x80);      //时间(注意12/24进制关系,选择24小时制需要把最高位置1)     
    I2CWaitAck();   
    I2CSendByte(InitTime[3]);       //周
    I2CWaitAck();   
    I2CSendByte(InitTime[2]);       //日      
    I2CWaitAck();   
    I2CSendByte(InitTime[1]);       //月      
    I2CWaitAck();   
    I2CSendByte(InitTime[0]);       //年      
    I2CWaitAck();   
    I2CStop();

    WriteTimeOff();             //写完记得关闭写入
}

/******写SD30系列单字节程序******/
void WriteOneByte(uchar add, uchar date)
{      
    WriteTimeOn();

    I2CStart();
    I2CSendByte(0x64);      
    I2CWaitAck();   
        I2CSendByte(add);           //设置写地址      
    I2CWaitAck();   
        I2CSendByte(date);          //写数据
    I2CWaitAck();   
    I2CStop();

    WriteTimeOff();
}

/******读SD30系列单字节程序******/
uchar ReadOneByte(uchar add)
{      
    uchar buf;
    I2CStart();
    I2CSendByte(0x64);      
    I2CWaitAck();   
    I2CSendByte(add);       //设置要读的地址      
    I2CWaitAck();
    I2CStart();
    I2CSendByte(0x65);      //写数据
    I2CWaitAck();   
    buf=I2CReceiveByte();       //读数据
    I2CNoAck();
    I2CStop();
    return  buf;
}

/******设置SD30系列报警中断演示程序******/
void WriteALARM(void)               //设置报警时间:2012年2月14日 8:00
{
    WriteOneByte(0x09,0x08);        //8时
    WriteOneByte(0x0b,0x14);    //14日
    WriteOneByte(0x0c,0x02);    //02月
    WriteOneByte(0x0d,0x12);    //12年
    WriteOneByte(0x0e,0x74);    //设置报警允许(使能年、月、日、小时报警)
    WriteOneByte(0x10,0x92);    //设置INT中断选通(INTS1,INTS0),及报警中断总允许位(INTAE)
}

/******关闭SD30XX报警中断程序******/
void ClrALARM(void)                 //关闭报警中断
{
    WriteOneByte(0x10,0x90);
}
/******设置SD30XX倒计时中断******/
void SetDjs(void)                   //设置倒计时中断
{
    WriteOneByte(0x10,0x0f);        //先清倒计时中断总允许位(INTDE)
    WriteOneByte(0x10,0xf4);    //设置周期性中断(IM=1)INT中断选通(INTS1,INTS0),配置倒计时中断总允许位(INTDE)
    WriteOneByte(0x11,0x30);    //选择定时器频率源(TDS1、TDS0)为1/60HZ

    WriteOneByte(0x13,5);       //倒计时初值寄存器,设置24位倒计时计数初值(5min)
    WriteOneByte(0x14,0);       //倒计时初值寄存器,设置24位倒计时计数初值(5min)
    WriteOneByte(0x15,0);       //倒计时初值寄存器,设置24位倒计时计数初值(5min)
}

/******关闭SD30XX倒计时中断程序******/
void ClrDjs(void)         
{
    WriteOneByte(0x10,0xf0);
}
/******设置SD30XX频率中断******/
void SetFrq(void)                  
{
    WriteOneByte(0x10,0xa1);        //选通频率中断(INTS1,INTS0),设置频率中断总允许位(INTFE)
    WriteOneByte(0x11,0x09);    //设置2Hz频率中断
}
/******关闭SD30XX频率中断******/
void ClrFrq(void)         
{
    WriteOneByte(0x10,0xa0);
}



/*********延时子程序*********/
void Delay(uint nn)
{
   while(nn--);
}

/**********************************************************************
*主函数演示
***********************************************************************/  
void main(void)
{   

/**********************************************************************
*初始化MSP430G2553
***********************************************************************/
   WDTCTL = WDTPW + WDTHOLD;       // 关闭看门狗
   BCSCTL2 = SELM_0 + DIVM_0 + DIVS_0;
   if (CALBC1_1MHZ != 0xFF)
    {
        DCOCTL = 0x00;
        BCSCTL1 = CALBC1_1MHZ;     
        DCOCTL = CALDCO_1MHZ;
     }
    BCSCTL1 |= XT2OFF + DIVA_0;
    TACTL |= TASSEL_2;
    UartInit(); //初始化串口,用于查看程序运行进度

    I2CWriteDate(); //设置时间演示
//  WriteALARM();   //设置报警中断时间演示
//  SetDjs();   //设置倒计时中断演示
    SetFrq();   //设置频率中断演示

    bat1=ReadOneByte(0x1a);//读SD30系列的电池电量最高位演示
    bat2=ReadOneByte(0x1b);//读SD30系列的电池电量低8位演示
    bat=(bat1>>7)*255+bat2;//计算电池电量值演示

   while(1)
   {
    I2CReadDate();      //读实时时钟     
                printf("%02x--",ReadTime[6]);       //年
                printf("%02x--",ReadTime[5]);       //月
                printf("%02x",ReadTime[4]);     //日
                printf("  %02x--",ReadTime[2]&0x7F);    //时
                printf("%02x--",ReadTime[1]);       //分
                printf("%02x",ReadTime[0]);     //秒
                printf("  Week:%02x",ReadTime[3]);  //周
        //需要十进制输出,自行转换即可,注意“时”的最高位
        delay_1ms(500);delay_1ms(500);
        printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
    }
}

 
点赞 关注

回复
举报
您需要登录后才可以回帖 登录 | 注册

查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条
福禄克有奖直播:高精度测温赋能电子制造 报名中!
直播时间:2025年2月28日(周五)上午10:00
直播主题:高精度测温赋能电子制造
小伙伴们儿快来报名直播吧~好礼等你拿!

查看 »

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

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