基础版本
This commit is contained in:
@@ -0,0 +1,242 @@
|
||||
|
||||
#include "config.h" //全局声明
|
||||
|
||||
//===========================================================================
|
||||
//Subroutine: iic_init
|
||||
//IIC初始化
|
||||
//===========================================================================
|
||||
|
||||
//void delay_us(unsigned int Counter)
|
||||
//{
|
||||
// uint32_t count;
|
||||
// while (Counter--)
|
||||
// {
|
||||
// count = 42; // 根据主频和编译器调整该值
|
||||
// while (count--)
|
||||
// {
|
||||
// __asm__ volatile("nop"); // 确保不被优化
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
void DS1307_Init()
|
||||
{
|
||||
u8 i = 0;
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);
|
||||
|
||||
GPIO_InitStructure.GPIO_Pin = iic_scl|iic_sda;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||
GPIO_Init(iic_gpio, &GPIO_InitStructure);
|
||||
GPIO_SetBits(iic_gpio,iic_scl|iic_sda);
|
||||
TXHData.CTIMEReadTimer.Init = 0; //清除初始化标志
|
||||
TXHData.CTIMEReadTimer.Flag = 0; //清除到时标志
|
||||
TXHData.CTIMEReadTimer.ON_OFF = 1; //打开
|
||||
TXHData.CTIMEReadTimer.Cycle = 1; //设置为循环模式,发送时启动
|
||||
TXHData.CTIMEReadTimer.TimerCountMax = 500;//周期0.5秒
|
||||
DS1307_Read();
|
||||
if(TXHData.CTIME.Sec > 0x59)
|
||||
{
|
||||
//TXHData.PREXDATA_WaitUpNummber = 0;
|
||||
TXHData.CTIME.Year = 0x24;//年
|
||||
TXHData.CTIME.Month = 0x08;//月
|
||||
TXHData.CTIME.Day = 0x30;//日
|
||||
//TXHData.CTIME.Week = 0x02;//周
|
||||
TXHData.CTIME.Hour = 0x14;//时
|
||||
TXHData.CTIME.Min = 0x20;//分
|
||||
TXHData.CTIME.Sec = 0x00;//秒
|
||||
DS1307_Write();
|
||||
}
|
||||
}
|
||||
//===========================================================================
|
||||
//Subroutine: iic_start
|
||||
//IIC数据传送启动信号
|
||||
//SCL为高电平的时候,SDA下降沿
|
||||
//===========================================================================
|
||||
void iic_start(void)
|
||||
{
|
||||
iic_sdaout(); //SDA线输出
|
||||
GPIO_SetBits(iic_gpio,iic_sda); //SDA为高电平
|
||||
GPIO_SetBits(iic_gpio,iic_scl); //SCL为高电平
|
||||
delay_us(4);
|
||||
GPIO_ResetBits(iic_gpio,iic_sda); //SDA下降沿
|
||||
}
|
||||
//===========================================================================
|
||||
//Subroutine: iic_stop
|
||||
//IIC数据传送停止信号
|
||||
//SCL为高电平时,SDA上升沿
|
||||
//===========================================================================
|
||||
void iic_stop(void)
|
||||
{
|
||||
iic_sdaout(); //SDA线输出
|
||||
GPIO_ResetBits(iic_gpio,iic_sda); //SDA为低电平
|
||||
delay_us(4);
|
||||
GPIO_SetBits(iic_gpio,iic_scl); //SCL高电平
|
||||
GPIO_SetBits(iic_gpio,iic_sda); //SDA上升沿,I2C总线数据传送结束信号
|
||||
}
|
||||
//===========================================================================
|
||||
//Subroutine: iic_wait4ack
|
||||
//IIC等待应答
|
||||
//返回值:1,接收应答失败
|
||||
// 0,接收应答成功
|
||||
//===========================================================================
|
||||
|
||||
u8 iic_wait4ack(void)
|
||||
{
|
||||
u8 times=0;
|
||||
iic_sdain(); //SDA设置为输入
|
||||
GPIO_SetBits(iic_gpio,iic_sda);//sda发送高点平
|
||||
delay_us(1);
|
||||
GPIO_SetBits(iic_gpio,iic_scl); //时钟高电平,上升沿
|
||||
delay_us(1);
|
||||
while(GPIO_ReadInputDataBit(iic_gpio, iic_sda)) //读数据,直到从机给出应答
|
||||
{
|
||||
if(++times>IICWAITTIMEOUT)
|
||||
{
|
||||
iic_stop(); //无应答,停止
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
GPIO_ResetBits(iic_gpio,iic_scl);//时钟输出低电平,下降沿
|
||||
return 0;
|
||||
}
|
||||
//===========================================================================
|
||||
//Subroutine: iic_act 产生应答
|
||||
//表示将继续接收数据
|
||||
//===========================================================================
|
||||
|
||||
void iic_ack(void)
|
||||
{
|
||||
GPIO_ResetBits(iic_gpio,iic_scl); //时钟低电平
|
||||
iic_sdaout();
|
||||
GPIO_ResetBits(iic_gpio,iic_sda); //数据低电平,表示有应答
|
||||
delay_us(2);
|
||||
GPIO_SetBits(iic_gpio,iic_scl); //时钟上升沿
|
||||
delay_us(2);
|
||||
GPIO_ResetBits(iic_gpio,iic_scl); //时钟下降沿
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//Subroutine: iic_noact 无应答或否认应答
|
||||
//表示不再接收数据
|
||||
//===========================================================================
|
||||
void iic_noack(void)
|
||||
{
|
||||
GPIO_ResetBits(iic_gpio,iic_scl); //时钟低电平
|
||||
iic_sdaout();
|
||||
GPIO_SetBits(iic_gpio,iic_sda); //数据高电平,表示无应答
|
||||
delay_us(2);
|
||||
GPIO_SetBits(iic_gpio,iic_scl); //时钟上升沿
|
||||
delay_us(2);
|
||||
GPIO_ResetBits(iic_gpio,iic_scl); //时钟下降沿
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//Subroutine: iic_sendbyte
|
||||
//IIC发送一个字节
|
||||
//===========================================================================
|
||||
void iic_sendbyte(u8 txd)
|
||||
{
|
||||
u8 t;
|
||||
iic_sdaout(); //SDA设置为输出,因为要发送数据
|
||||
GPIO_ResetBits(iic_gpio,iic_scl); //时钟低电平,只有SCL为低才可改变数据
|
||||
for(t=0;t<8;t++)//循环发送8个字节
|
||||
{
|
||||
if ((txd&0x80)>>7) GPIO_SetBits(iic_gpio,iic_sda); //发出第7-t位
|
||||
else GPIO_ResetBits(iic_gpio,iic_sda);
|
||||
txd<<=1;
|
||||
delay_us(2);
|
||||
GPIO_SetBits(iic_gpio,iic_scl); //拉高SCL,发数据
|
||||
delay_us(2);
|
||||
GPIO_ResetBits(iic_gpio,iic_scl); //SCL恢复低电平,准备修改SDA
|
||||
delay_us(2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//Subroutine: iic_readbyte
|
||||
//读1个字节,ack=1时,读之后发送ACK,ack=0,读者后发送nACK
|
||||
//===========================================================================
|
||||
u8 iic_readbyte(u8 ack)
|
||||
{
|
||||
unsigned char i,receive=0;
|
||||
iic_sdain();//准备接收数据,SDA设置为输入
|
||||
for(i=0;i<8;i++ ) //循环接收8位
|
||||
{
|
||||
GPIO_ResetBits(iic_gpio,iic_scl); //SCL为低电平
|
||||
delay_us(2);
|
||||
GPIO_SetBits(iic_gpio,iic_scl); //SCL上升沿,开始读取数据
|
||||
receive<<=1;
|
||||
if(GPIO_ReadInputDataBit(iic_gpio, iic_sda)) //读取数据
|
||||
receive|=0x01; //如果读到的数据为1,receive最低位应为1
|
||||
delay_us(1);
|
||||
}
|
||||
if (ack) //如果需要应答
|
||||
iic_ack();//发送应答
|
||||
else
|
||||
iic_noack(); //发送无应答
|
||||
return receive;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//在指定地址读出一个数据
|
||||
//返回值 :读到的数据
|
||||
//===========================================================================
|
||||
void DS1307_Read(void)//93us
|
||||
{
|
||||
u8 temp[7],i;
|
||||
|
||||
iic_start(); //启动
|
||||
iic_sendbyte(0XD0); //发送器件地址0XD0
|
||||
iic_wait4ack(); //等待应答
|
||||
iic_sendbyte(0); //发送字地址
|
||||
iic_wait4ack(); //等待应答
|
||||
iic_start(); //产生一个起动条件
|
||||
iic_sendbyte(0XD1); //发送地址0XD1进入接收模式
|
||||
iic_wait4ack(); //等待应答
|
||||
for (i = 0;i < 7;i ++)
|
||||
{
|
||||
if (i < 6)
|
||||
temp[i] = iic_readbyte(1);
|
||||
else
|
||||
temp[i] = iic_readbyte(0);
|
||||
}
|
||||
iic_stop(); //产生一个停止条件
|
||||
TXHData.CTIME.Year = temp[6];//年
|
||||
TXHData.CTIME.Month = temp[5];//月
|
||||
TXHData.CTIME.Day = temp[4];//日
|
||||
|
||||
TXHData.CTIME.Hour = temp[2];//时
|
||||
TXHData.CTIME.Min = temp[1];//分
|
||||
TXHData.CTIME.Sec = temp[0];//秒
|
||||
}
|
||||
//===========================================================================
|
||||
//在指定地址写一个数据
|
||||
//返回值 :无
|
||||
//===========================================================================
|
||||
void DS1307_Write(void)
|
||||
{
|
||||
u8 i = 0,temp[7];
|
||||
|
||||
temp[0]= TXHData.CTIME.Sec;
|
||||
temp[1]= TXHData.CTIME.Min;
|
||||
temp[2]= TXHData.CTIME.Hour;
|
||||
temp[3]= 0x01;
|
||||
temp[4]= TXHData.CTIME.Day;
|
||||
temp[5]= TXHData.CTIME.Month;
|
||||
temp[6]= TXHData.CTIME.Year;
|
||||
iic_start();
|
||||
iic_sendbyte(0XD0); //发送器件地址0XD0
|
||||
iic_wait4ack(); //等待应答
|
||||
iic_sendbyte(0x00); //发送字地址
|
||||
iic_wait4ack(); //等待应答
|
||||
for(i = 0;i < 7;i ++)
|
||||
{
|
||||
iic_sendbyte(temp[i]); //发送字节
|
||||
iic_wait4ack(); //等待应答
|
||||
}
|
||||
iic_stop(); //产生一个停止条件
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
#ifndef __DS1307_H
|
||||
#define __DS1307_H
|
||||
|
||||
//==============================================================================
|
||||
//macro: iic_sdain iic_sdaout
|
||||
//设置sda为输入或输出
|
||||
//方法: 设置CRL 高4位为 1000 位7 sda 上下拉输入
|
||||
// 设置CRL 高4位为 0011 位7 sda 推挽输出 最高频率50M
|
||||
//因为可以保证不会设置为AF
|
||||
//==============================================================================
|
||||
#define iic_sdain() GPIOF->MODER &= 0XFFFFF3FF;//
|
||||
#define iic_sdaout() GPIOF->MODER |= 0X00000400;//
|
||||
#define IICWAITTIMEOUT 250
|
||||
#define iic_gpio GPIOF
|
||||
#define iic_scl GPIO_Pin_4
|
||||
#define iic_sda GPIO_Pin_5
|
||||
|
||||
//void delay_us(unsigned int Counter);
|
||||
void DS1307_Init(void);
|
||||
void iic_start(void);
|
||||
void iic_stop(void);
|
||||
u8 iic_wait4ack(void);
|
||||
void iic_ack(void);
|
||||
void iic_noack(void);
|
||||
void iic_sendbyte(u8);
|
||||
u8 iic_readbyte(unsigned char ack);
|
||||
void DS1307_Read(void);
|
||||
void DS1307_Write(void);
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user