打印
[STM8]

实时时钟SD30XX读写STM8参考程序

[复制链接]
630|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
jiekou001|  楼主 | 2018-1-18 20:33 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
//************************************************************
// 实时时钟SD30XX读写STM8参考程序
// MCU: STM8S103F3
//************************************************************

#include "stm8s103f3p.h"

#define uchar unsigned char
#define SCL_H  PC_ODR |= 0X08
#define SDA_H  PA_ODR |= 0X08
#define SCL_L  PC_ODR &= 0XF7
#define SDA_L  PA_ODR &= 0XF7
#define SDAM  ((PA_IDR & 0X08) >> 3)
#define SET_SCL_OUT()    {PC_DDR |= 0X08; PC_CR1 |= 0X08; PC_CR2 &= 0XF7;}//scl选择管脚为PC3
#define SET_SDA_OUT()    {PA_DDR |= 0X08; PA_CR1 |= 0X08; PA_CR2 &= 0XF7;}//sda选择管脚为PA3
#define SET_SDA_IN()     {PA_DDR &= 0XF7; PA_CR1 &= 0XF7; PA_CR2 &= 0XF7;}//浮空输入

uchar s_data[7] = {0};

void GPIO_I2c_Master_Init(void)
{
  I2C_CR1 &= 0xFE;      
  SET_SCL_OUT();    //PC3 输出;推挽;2MHz时钟;
  SET_SDA_OUT();    //PA3 输出;推挽;2MHz时钟;
}

void Delay_5us(void)
{
  uchar i = 10;    //fcpu 16MHz

  for (; i > 0; i--);
}

void I2C_Start(void)//起始信号
{
  SDA_H;                    
  SCL_H;                    
  Delay_5us();               
  SDA_L;                  
  Delay_5us();               
  SCL_L;                    
}

void I2C_Stop(void)//结束信号
{
  SDA_L;                  
  SCL_H;                  
  Delay_5us();               
  SDA_H;                  
  Delay_5us();               
}

void I2C_SendACK(uchar ack)//应答或者非应答信号
{
  if (ack == 0)
  {
    SDA_L;
  }
  else
  {
    SDA_H;
  }
  SCL_H;                  
  Delay_5us();  
  
  SCL_L;                    
  Delay_5us();     
}

uchar I2C_SendByte(uchar sendDAT)//发送字节
{
  uchar i = 0;
  uchar revack = 0;

  for (i= 0 ; i< 8; i++)         
  {
    SCL_L;               
    Delay_5us();  
  
    if (sendDAT & 0x80)  
    {
      SDA_H;
    }
    else  
    {      
      SDA_L;
    }
    sendDAT <<=  1;
    SCL_H;               
    Delay_5us();     
  }
  SCL_L;               
  Delay_5us();  
  SET_SDA_IN();
  SCL_H;   
  _asm("nop");
  _asm("nop");
  revack = (uchar)SDAM;
  Delay_5us();   
  SCL_L;   
  SET_SDA_OUT();
  Delay_5us();  

  return revack;
}

uchar I2C_RecvByte(void)//接收字节
{
  uchar i = 0;
  uchar revDAT = 0;
  
  SDA_H;  
  SET_SDA_IN();
  for (i = 0; i < 8; i++)         
  {
     revDAT <<= 1;      
     SCL_H;
     _asm("nop");
     _asm("nop");
     if (SDAM)
     {
        revDAT |= 0x01;
     }
     else
     {
        revDAT &= 0xfe;
     }

     Delay_5us();
     SCL_L;               
     Delay_5us();  
  }   
  SET_SDA_OUT();
  
  return revDAT;
}

void WriteOn(void)//打开写保护
{
  I2C_Start();
  I2C_SendByte(0x64);
  I2C_SendByte(0x10);
  I2C_SendByte(0x80);
  I2C_Stop();
  
  I2C_Start();
  I2C_SendByte(0x64);
  I2C_SendByte(0x0f);
  I2C_SendByte(0x84);
  I2C_Stop();
}

void WriteOff(void)//关闭写保护
{
  I2C_Start();
  I2C_SendByte(0x64);
  I2C_SendByte(0x10);
  I2C_SendByte(0x00);
  I2C_Stop();
  
  I2C_Start();
  I2C_SendByte(0x64);
  I2C_SendByte(0x0f);
  I2C_SendByte(0x00);
  I2C_Stop();
}

void read_time_from_sd30xx(void)//从sd30xx读时间
{
  uchar n = 0;

  I2C_Start();
  if (I2C_SendByte(0x65))
  {
    I2C_Stop();

    return;
  }
  for (n = 0; n < 7; n++)
  {
    s_data[n] = I2C_RecvByte();
    if (n == 6)
    {
      I2C_SendACK(1);
    }
    I2C_SendACK(0);
  }
  I2C_Stop();
}



void write_time_to_sd30xx(void)//写时间到sd30xx
{
  uchar n = 0;

  WriteOn();
  
  I2C_Start();
  I2C_SendByte(0x64);
  I2C_SendByte(0x00);
  for (n = 0; n < 7; n++)
  {
    I2C_SendByte(s_data[n]);
  }
  I2C_Stop();
  
  WriteOff();
}


沙发
jiekou001|  楼主 | 2018-1-18 20:33 | 只看该作者
虽然这个不常用,但是找来分享给大家。

使用特权

评论回复
板凳
yiy| | 2018-1-19 15:36 | 只看该作者
非常感谢,学到了一招,宏都要用大括号搞起来。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

129

主题

1285

帖子

2

粉丝