基础版本

This commit is contained in:
bathfire
2026-04-27 16:55:02 +08:00
commit 64b3e488da
269 changed files with 383851 additions and 0 deletions
+242
View File
@@ -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时,读之后发送ACKack=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(); //产生一个停止条件
}
+32
View File
@@ -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