//************************************************************
// 实时时钟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();
}
|