必趣CB1核心板、H616主控linux验证IO模拟I2C驱动DS1307时钟芯片

使用了#include <gpiod.h>内部库作为IO驱动

点击查看代码
`#ifndef	__DS1307_H
#define __DS1307_H

#define NUM_LEDS 21         // 控制4个GPIO引脚
#define CHIPNAME "gpiochip0"  // GPIO 芯片的名称

#define WRITE_CMD				0x00
#define READ_CMD				0x01

#define DEV_ADDR                0xD0//器件地址,0x68<<1

#define DS1307_I2C_ADDR 	0x68
#define DS1307_REG_SECOND 	0x00
#define DS1307_REG_MINUTE 	0x01
#define DS1307_REG_HOUR  	0x02
#define DS1307_REG_DOW    	0x03
#define DS1307_REG_DATE   	0x04
#define DS1307_REG_MONTH  	0x05
#define DS1307_REG_YEAR   	0x06
#define DS1307_REG_CONTROL 	0x07
#define DS1307_REG_UTC_HR	0x08
#define DS1307_REG_UTC_MIN	0x09
#define DS1307_REG_CENT    	0x10
#define DS1307_REG_RAM   	0x11
#define DS1307_TIMEOUT		1000

uint16_t DS1307_GetYear(struct gpiod_line *sda, struct gpiod_line *scl);
uint8_t DS1307_GetDay(struct gpiod_line *sda, struct gpiod_line *scl);
uint8_t DS1307_GetMonth(struct gpiod_line *sda, struct gpiod_line *scl);
uint8_t DS1307_GetDate(struct gpiod_line *sda, struct gpiod_line *scl);
uint8_t DS1307_GetHour(struct gpiod_line *sda, struct gpiod_line *scl);
uint8_t DS1307_GetHourMode(struct gpiod_line *sda, struct gpiod_line *scl);
void DS1307_SetHourMode(struct gpiod_line *sda, struct gpiod_line *scl,uint8_t mode);
void DS1307_SetAMPM(struct gpiod_line *sda, struct gpiod_line *scl,uint8_t data);
uint8_t DS1307_GetAMPM(struct gpiod_line *sda, struct gpiod_line *scl);
uint8_t DS1307_GetMinute(struct gpiod_line *sda, struct gpiod_line *scl);
uint8_t DS1307_GetSecond(struct gpiod_line *sda, struct gpiod_line *scl);
void DS1307_SetYear(struct gpiod_line *sda, struct gpiod_line *scl,uint16_t year);
void DS1307_SetDay(struct gpiod_line *sda, struct gpiod_line *scl,uint8_t day);
void DS1307_SetMonth(struct gpiod_line *sda, struct gpiod_line *scl,uint8_t month);
void DS1307_SetDate(struct gpiod_line *sda, struct gpiod_line *scl,uint8_t date);
void DS1307_SetHour(struct gpiod_line *sda, struct gpiod_line *scl,uint8_t hour);
void DS1307_SetMinute(struct gpiod_line *sda, struct gpiod_line *scl,uint8_t min);
void DS1307_SetSecond(struct gpiod_line *sda, struct gpiod_line *scl,uint8_t sec);
bool DS1307_ReadHaltFlag(struct gpiod_line *sda, struct gpiod_line *scl);
void DS1307_SetHaltFlag(struct gpiod_line *sda, struct gpiod_line *scl);
void DS1307_ClearHaltFlag(struct gpiod_line *sda, struct gpiod_line *scl);
void DS1307_SQWEnable(struct gpiod_line *sda, struct gpiod_line *scl);
void DS1307_SQWDisable(struct gpiod_line *sda, struct gpiod_line *scl);
void DS1307_SetSqureWaveFreq(struct gpiod_line *sda, struct gpiod_line *scl,uint8_t rate);
void DS1307_OutHigh(struct gpiod_line *sda, struct gpiod_line *scl);
void DS1307_OutLow(struct gpiod_line *sda, struct gpiod_line *scl);
void DS1307_Init(struct gpiod_line *sda, struct gpiod_line *scl);


#endif`

`#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <errno.h>
#include <wiringPi.h>
#include <termios.h>
#include <time.h>
#include <sys/syscall.h>
#include <signal.h>
#include <sys/wait.h>
#include <gpiod.h>

#define TRUE 1
#define FALSE 0
#define ML302_PWR_IO 21
#define ML302_RESET_IO 7
#ifndef BOOL
	typedef int BOOL;
#endif

typedef signed char int8_t;
typedef unsigned char uint8_t;
typedef const char cint8_t;

typedef signed short int16_t;
typedef unsigned short uint16_t;

typedef unsigned int uint32_t;

/********************************************************************************
 * I2C驱动函数
 * I2C驱动函数
 * I2C驱动函数
 *********************************************************************************/
//延迟函数,控制 I2C 速度
static void i2c_delay(void) {
	usleep(1000);  // 可以根据需要调整
}
// 设置 SDA 和 SCL 的电平
static void set_gpio_value(struct gpiod_line *line, int value) {
	gpiod_line_set_value(line, value);
	i2c_delay();
}
// I2C 起始信号
static void i2c_start(struct gpiod_line *sda, struct gpiod_line *scl) {
	set_gpio_value(sda, 1);
	set_gpio_value(scl, 1);
	set_gpio_value(sda, 0);  // SDA 拉低,开始信号
	set_gpio_value(scl, 0);  // SCL 拉低,准备传输
}
// I2C 结束信号
static void i2c_stop(struct gpiod_line *sda, struct gpiod_line *scl) {
	set_gpio_value(sda, 0);
	set_gpio_value(scl, 1);
	set_gpio_value(sda, 1);  // SDA 拉高,停止信号
}
// 等待从设备发送 ACK 信号
static int i2c_wait_ack(struct gpiod_line *sda, struct gpiod_line *scl) {
	int ack;
	uint16_t wait_time=0;
	
	gpiod_line_release(sda);//释放总线
	gpiod_line_request_input(sda, "i2c_read");  // 设置 SDA 为输入模式
	
	do{
		wait_time++;
		if (wait_time>=200)
		{
			printf("i2c_wait_ack no recv\r\n");
			ack = 1;
			break;
		}
		ack = gpiod_line_get_value(sda);  // 读取 ACK 位
	}while(ack);
	set_gpio_value(scl, 1);  // 拉高时钟
	set_gpio_value(scl, 0);  // 拉低时钟 
	
	gpiod_line_release(sda);//释放总线
	gpiod_line_request_output(sda, "sda", 1);//设置 SDA 为输入模式
	return ack;
}
// 发送 NACK 信号
static void i2c_send_nack(struct gpiod_line *sda, struct gpiod_line *scl) {
	gpiod_line_release(sda);//释放总线
	gpiod_line_request_output(sda, "i2c", 1);  // 设置 SDA 为输出模式
	set_gpio_value(sda, 1);  // 发送 NACK (SDA 为高电平)
	set_gpio_value(scl, 1);  // 拉高时钟
	set_gpio_value(scl, 0);  // 拉低时钟
}
// I2C 写入 1 位数据
static void i2c_write_bit(struct gpiod_line *sda, struct gpiod_line *scl, int bit) {
	set_gpio_value(sda, bit);
	set_gpio_value(scl, 1);  // 时钟线拉高,数据稳定传输
	set_gpio_value(scl, 0);  // 时钟线拉低,准备下一位
}
// I2C 写入 1 字节数据
static void i2c_write_byte(struct gpiod_line *sda, struct gpiod_line *scl, unsigned char byte) {
	for (int i = 0; i < 8; i++) {
		i2c_write_bit(sda, scl, (byte & 0x80) != 0);  // 最高位先发送
		byte <<= 1;
	}
}
// I2C 读取 1 位数据
static int i2c_read_bit(struct gpiod_line *sda, struct gpiod_line *scl) {
	int bit;
	
	gpiod_line_release(sda);//释放总线
	gpiod_line_request_input(sda, "i2c_read");  // 设置 SDA 为输入模式
	
	set_gpio_value(scl, 1);  // 拉高时钟
	bit = gpiod_line_get_value(sda);  // 读取 SDA 线的电平
	set_gpio_value(scl, 0);  // 拉低时钟
	
	gpiod_line_release(sda);//释放总线
	gpiod_line_request_output(sda, "sda", 0);
	
	return bit;
}
// I2C 读取 1 字节数据
static unsigned char i2c_read_byte(struct gpiod_line *sda, struct gpiod_line *scl) {
	unsigned char byte = 0;
	for (int i = 0; i < 8; i++) {
		byte <<= 1;
		byte |= i2c_read_bit(sda, scl);
	}
	return byte;
}
/***********************************************************************************************************************
 * DS1307驱动函数
 * DS1307驱动函数
 * DS1307驱动函数
 *********************************************************************************************************************/
/**
 * @brief Decodes the raw binary value stored in registers to decimal format.
 * @param bin Binary-coded decimal value retrieved from register, 0 to 255.
 * @return Decoded decimal value.
 */
static uint8_t BCDToDec(uint8_t bin) {
#if(0)
	return (((bin & 0xf0) >> 4) * 10) + (bin & 0x0f);
#else
	unsigned char temp;
	
	temp=bin/16;
	bin=bin%16;
	bin=bin+temp*10;
	return(bin);
#endif
}
/**
 * @brief Encodes a decimal number to binaty-coded decimal for storage in registers.
 * @param dec Decimal number to encode.
 * @return Encoded binary-coded decimal value.
 */
static uint8_t DecToBCD(uint8_t dec) {
	return ((dec % 10) + ((dec / 10) << 4));
}
/********************************************************************************
 * 函 数 名: uint8_t DS1307_Read(sda,scl,uint8_t address)
 * 功能说明: 向DS1307寄存器读取数据
 * 形    参:寄存器地址
 * 返 回 值: 读出的数据
 *********************************************************************************/
static uint8_t DS1307_Read(struct gpiod_line *sda, struct gpiod_line *scl,uint8_t address)
{
	uint8_t dat;
	i2c_start(sda, scl);
	i2c_write_byte(sda, scl,DEV_ADDR | WRITE_CMD);//器件寻址+写
	if(i2c_wait_ack(sda, scl) == 1)
	{
		printf("i2c_write_byte(sda, scl,0xd0) nonono\r\n");//
	}
	i2c_write_byte(sda, scl,address);//发送寄存器地址
	if(i2c_wait_ack(sda, scl) == 1)
	{
		printf("i2c_write_byte(sda, scl,address) nonono\r\n");//
	}
	i2c_stop(sda, scl);
	i2c_start(sda, scl);//重新启动IIC总线
	i2c_write_byte(sda, scl,0xd1);	//发送设备地址,读指令m
	if(i2c_wait_ack(sda, scl) == 1)
	{
		printf("i2c_write_byte(sda, scl,0xd1) nonono\r\n");//
	}
	dat=i2c_read_byte(sda, scl); //读一个字节数据
	i2c_send_nack(sda, scl);	
	i2c_stop(sda, scl);
	return dat;
}
/*
*********************************************************************************************************
*	函 数 名: DS1307_Write(uint8_t address , uint8_t dat)
*	功能说明: 向DS1307寄存器写数据
*	形    参:address:寄存器地址,dat:要写入的数据
*	返 回 值: 无
*********************************************************************************************************
*/
static void DS1307_Write(struct gpiod_line *sda, struct gpiod_line *scl, uint8_t address , uint8_t dat)
{ 
	i2c_start(sda, scl);
	i2c_write_byte(sda, scl,DEV_ADDR | WRITE_CMD);//器件寻址+写
	if(i2c_wait_ack(sda, scl) == 1)
	{
		printf("i2c_write_byte(sda, scl,DEV_ADDR | WRITE_CMD) nonono\r\n");//
	}
	i2c_write_byte(sda, scl,address);//发送寄存器地址
	if(i2c_wait_ack(sda, scl) == 1)
	{
		printf("i2c_write_byte(sda, scl,address) nonono\r\n");//
	}
	i2c_write_byte(sda, scl,dat);//写一个字节数据
	if(i2c_wait_ack(sda, scl) == 1)
	{
		printf("i2c_write_byte(sda, scl,dat) nonono\r\n");//
	}
	i2c_stop(sda, scl);
}
/*******************************************************************************
 * 函数名:DS1307_GetYear
 * 功  能:获取年份
 * 参  数:无			
 * 返回值:年份,十进制
 * 说  明:将BCD码转为十进制
 *******************************************************************************/
uint16_t DS1307_GetYear(struct gpiod_line *sda, struct gpiod_line *scl)
{
	uint16_t temp = 0;
	temp = DS1307_Read(sda,scl,DS1307_REG_YEAR);
	return BCDToDec(temp);
}
/*******************************************************************************
 * 函数名:DS1307_GetDay
 * 功  能:获取星期几
 * 参  数:无			
 * 返回值:星期几,十进制,1~7
 * 说  明:无
 *******************************************************************************/
uint8_t DS1307_GetDay(struct gpiod_line *sda, struct gpiod_line *scl)
{
	uint8_t temp = 0;
	temp = DS1307_Read(sda,scl,DS1307_REG_DOW);
	return BCDToDec(temp & 0x07);
}
/*******************************************************************************
 * 函数名:DS1307_GetMonth
 * 功  能:获取月份
 * 参  数:无			
 * 返回值:月份,十进制,1~12
 * 说  明:无
 *******************************************************************************/
uint8_t DS1307_GetMonth(struct gpiod_line *sda, struct gpiod_line *scl)
{
	uint8_t temp = 0;
	temp = DS1307_Read(sda,scl,DS1307_REG_MONTH);
	return BCDToDec(temp & 0x1F);
}
/*******************************************************************************
 * 函数名:DS1307_GetDate
 * 功  能:获取日期
 * 参  数:无			
 * 返回值:日,十进制,1~31
 * 说  明:无
 *******************************************************************************/
uint8_t DS1307_GetDate(struct gpiod_line *sda, struct gpiod_line *scl)
{
	uint8_t temp = 0;
	temp = DS1307_Read(sda,scl,DS1307_REG_DATE);
	return BCDToDec(temp & 0x3F);
}
/*******************************************************************************
 * 函数名:DS1307_GetHour
 * 功  能:获取小时
 * 参  数:无			
 * 返回值:小时,十进制,1~12或0~23
 * 说  明:返回的值需要结合小时模式及AM/PM位区分具体时间
 *******************************************************************************/
uint8_t DS1307_GetHour(struct gpiod_line *sda, struct gpiod_line *scl)
{
	uint8_t temp = 0;
	temp = DS1307_Read(sda,scl,DS1307_REG_HOUR);
	if ((temp & 0x40) == 0x40)//12小时模式
	{
		return BCDToDec(temp & 0x1F);
	}else//24小时模式
	{
		return BCDToDec(temp & 0x3F);
	}
}
/*******************************************************************************
 * 函数名:DS1307_GetHourMode
 * 功  能:获取小时模式
 * 参  数:无			
 * 返回值:0,24小时模式,1,12小时模式
 * 说  明:bit6
 *******************************************************************************/
uint8_t DS1307_GetHourMode(struct gpiod_line *sda, struct gpiod_line *scl)
{
	uint8_t temp = 0;
	temp = DS1307_Read(sda,scl,DS1307_REG_HOUR);
	temp &= 0x40;
	return (temp >> 6);
}
/*******************************************************************************
 * 函数名:DS1307_SetHourMode
 * 功  能:设置小时模式
 * 参  数:mode,0,24小时模式,1,12小时模式			
 * 返回值:无
 * 说  明:bit6,datasheet要求,更改模式时,小时必须重新初始化,
  因此先读取原小时时间,再设置模式,再将小时写入寄存器
 *******************************************************************************/
void DS1307_SetHourMode(struct gpiod_line *sda, struct gpiod_line *scl,uint8_t mode)
{
	uint8_t hour = 0;//原时间
	uint8_t temp = 0;//原模式
	uint8_t reg = 0;//写入寄存器的值
	temp = DS1307_GetHourMode(sda,scl);
	if (mode != temp)//修改模式
	{
		reg |= ((mode & 0x01) << 6);//模式在bit6
		hour = DS1307_Read(sda,scl,DS1307_REG_HOUR);;//读取原寄存器的值,保存原时间        
		if (mode == 0)//改为24小时模式,之前是12小时模式,先判断AM/PM
		{
			if ((hour & 0x20) == 0x20)//bit5,1=PM
			{
				hour &= 0x1F;//提取0~4位的时间
				hour = BCDToDec(hour);//BCD转为十进制
				hour += 12;
				reg |= DecToBCD(hour);//BCD
			}else//AM
			{
				hour &= 0x1F;//提取0~4位的时间
				reg |= hour;
			}
		}else//改为12小时模式,之前是24小时模式
		{
			hour &= 0x3F;
			hour = BCDToDec(hour);//BCD转为十进制
			if (hour > 12)//PM
			{
				hour -= 12;
				reg |= DecToBCD(hour);//BCD
				reg |= 0x20;//bit5置1
			}else//AM
			{
				reg |= DecToBCD(hour);//BCD
				reg &= 0xDF;//bit5置0
			}
		}
	}
	DS1307_Write(sda,scl,DS1307_REG_HOUR, reg);	
}
/*******************************************************************************
 * 函数名:DS1307_SetAMPM
 * 功  能:设置AM/PM模式
 * 参  数:data,0为AM上午,1为PM下午		
 * 返回值:无
 * 说  明:小时寄存器bit5,须在12小时模式下使用
 *******************************************************************************/
void DS1307_SetAMPM(struct gpiod_line *sda, struct gpiod_line *scl,uint8_t data)
{
	uint8_t temp = 0;
	temp = DS1307_Read(sda,scl,DS1307_REG_HOUR);//先把原数据读出
	(data == 0) ? (temp &= 0xDF) : (temp |= 0x20);
	DS1307_Write(sda,scl,DS1307_REG_HOUR, temp);
}
/*******************************************************************************
 * 函数名:DS1307_GetAMPM
 * 功  能:读取AM/PM模式
 * 参  数:无		
 * 返回值:0为AM上午,1为PM下午
 * 说  明:小时寄存器bit5,须在12小时模式下使用
 *******************************************************************************/
uint8_t DS1307_GetAMPM(struct gpiod_line *sda, struct gpiod_line *scl)
{
	uint8_t temp = 0;
	temp = DS1307_Read(sda,scl,DS1307_REG_HOUR);
	return ((temp & 0x20) >> 5);
}
/*******************************************************************************
 * 函数名:DS1307_GetMinute
 * 功  能:获取分钟
 * 参  数:无			
 * 返回值:分钟,十进制,0~59
 * 说  明:无
 *******************************************************************************/
uint8_t DS1307_GetMinute(struct gpiod_line *sda, struct gpiod_line *scl)
{
	uint8_t temp = 0;
	temp = DS1307_Read(sda,scl,DS1307_REG_MINUTE);
	return BCDToDec(temp & 0x7F);
}
/*******************************************************************************
 * 函数名:DS1307_GetSecond
 * 功  能:获取秒
 * 参  数:无			
 * 返回值:秒,十进制,0~59
 * 说  明:无
 *******************************************************************************/
uint8_t DS1307_GetSecond(struct gpiod_line *sda, struct gpiod_line *scl)
{
	uint8_t temp = 0;
	temp = DS1307_Read(sda,scl,DS1307_REG_SECOND);
	return BCDToDec(temp & 0x7F);
}
/*******************************************************************************
 * 函数名:DS1307_SetYear
 * 功  能:写入年份
 * 参  数:year:年份,十进制,2000~2099			
 * 返回值:无
 * 说  明:将十进制转为BCD码
 *******************************************************************************/
void DS1307_SetYear(struct gpiod_line *sda, struct gpiod_line *scl,uint16_t year)
{
	uint8_t temp = DecToBCD(year);
	DS1307_Write(sda,scl,DS1307_REG_YEAR, temp);	
}
/*******************************************************************************
 * 函数名:DS1307_SetDay
 * 功  能:写入星期几
 * 参  数:day:星期几,1~7			
 * 返回值:无
 * 说  明:无
 *******************************************************************************/
void DS1307_SetDay(struct gpiod_line *sda, struct gpiod_line *scl,uint8_t day)
{
	DS1307_Write(sda,scl,DS1307_REG_DOW, day & 0x07);	
}
/*******************************************************************************
 * 函数名:DS1307_SetMonth
 * 功  能:写入月份
 * 参  数:month:月份,1~12			
 * 返回值:无
 * 说  明:转为BCD码
 *******************************************************************************/
void DS1307_SetMonth(struct gpiod_line *sda, struct gpiod_line *scl,uint8_t month)
{
	uint8_t temp = DecToBCD(month);
	DS1307_Write(sda,scl,DS1307_REG_MONTH, temp & 0x1F);
}
/*******************************************************************************
 * 函数名:DS1307_SetDate
 * 功  能:写入日
 * 参  数:date:日,1~31			
 * 返回值:无
 * 说  明:无
 *******************************************************************************/
void DS1307_SetDate(struct gpiod_line *sda, struct gpiod_line *scl,uint8_t date)
{
	uint8_t temp = DecToBCD(date);
	DS1307_Write(sda,scl,DS1307_REG_DATE, temp & 0x3F);
}
/*******************************************************************************
 * 函数名:DS1307_SetHour
 * 功  能:写入小时
 * 参  数:hour:小时,1~12或0~23		
 * 返回值:无
 * 说  明:无
 *******************************************************************************/
void DS1307_SetHour(struct gpiod_line *sda, struct gpiod_line *scl,uint8_t hour)
{
	uint8_t temp = DecToBCD(hour);
	DS1307_Write(sda,scl,DS1307_REG_HOUR, temp & 0x3F);
}
/*******************************************************************************
 * 函数名:DS1307_SetMinute
 * 功  能:写入分钟
 * 参  数:min:分钟,0~59		
 * 返回值:无
 * 说  明:无
 *******************************************************************************/
void DS1307_SetMinute(struct gpiod_line *sda, struct gpiod_line *scl,uint8_t min)
{
	uint8_t temp = DecToBCD(min);
	DS1307_Write(sda,scl,DS1307_REG_MINUTE, temp & 0x7F);
}
/*******************************************************************************
 * 函数名:DS1307_SetSecond
 * 功  能:写入秒
 * 参  数:sec:秒,0~59		
 * 返回值:无
 * 说  明:无
 *******************************************************************************/
void DS1307_SetSecond(struct gpiod_line *sda, struct gpiod_line *scl,uint8_t sec)
{
	uint8_t temp = DecToBCD(sec);
	DS1307_Write(sda,scl,DS1307_REG_SECOND, temp & 0x7F);
}
/*******************************************************************************
 * 函数名:DS1307_ReadHaltFlag
 * 功  能:读Halt标志
 * 参  数:无			
 * 返回值:无
 * 说  明:无
 *******************************************************************************/
bool DS1307_ReadHaltFlag(struct gpiod_line *sda, struct gpiod_line *scl)
{
	bool temp = 0;
	temp = ((DS1307_Read(sda,scl,DS1307_REG_SECOND) & 0x80) == 0x80) ? 1 : 0;
	return temp;
}
/*******************************************************************************
 * 函数名:DS1307_SetHaltFlag
 * 功  能:Halt标志置1
 * 参  数:无			
 * 返回值:无
 * 说  明:先读80寄存器,再写入CH位
 *******************************************************************************/
void DS1307_SetHaltFlag(struct gpiod_line *sda, struct gpiod_line *scl)
{
	uint8_t temp = 0;
	temp = DS1307_GetSecond(sda,scl);
	temp |= 0x80;
	DS1307_Write(sda,scl,DS1307_REG_SECOND, temp);
}
/*******************************************************************************
 * 函数名:DS1307_ClearHaltFlag
 * 功  能:Halt标志置0
 * 参  数:无			
 * 返回值:无
 * 说  明:先读80寄存器,再写入CH位,该位为0,时钟才开始工作
 *******************************************************************************/
void DS1307_ClearHaltFlag(struct gpiod_line *sda, struct gpiod_line *scl)
{
	uint8_t temp = 0;
	temp = DS1307_GetSecond(sda,scl);
	temp &= 0x7F;
	DS1307_Write(sda,scl,DS1307_REG_SECOND, temp);
}
/*******************************************************************************
 * 函数名:DS1307_SQWEnable
 * 功  能:使能方波输出
 * 参  数:无			
 * 返回值:无
 * 说  明:bit4写1
 *******************************************************************************/
void DS1307_SQWEnable(struct gpiod_line *sda, struct gpiod_line *scl)
{
	uint8_t temp = 0;
	temp = DS1307_Read(sda,scl,DS1307_REG_CONTROL);
	temp |= 0x10;
	DS1307_Write(sda,scl,DS1307_REG_CONTROL, temp);
}
/*******************************************************************************
 * 函数名:DS1307_SQWDisable
 * 功  能:禁止方波输出
 * 参  数:无			
 * 返回值:无
 * 说  明:bit4写0
 *******************************************************************************/
void DS1307_SQWDisable(struct gpiod_line *sda, struct gpiod_line *scl)
{
	uint8_t temp = 0;
	temp = DS1307_Read(sda,scl,DS1307_REG_CONTROL);
	temp &= 0xEF;
	DS1307_Write(sda,scl,DS1307_REG_CONTROL, temp);
}
/*******************************************************************************
 * 函数名:DS1307_SetSqureWaveFreq
 * 功  能:设置方波频率
 * 参  数:rate:0,1Hz;1,4.096kHz;2,8.192kHz;3,32.768kHz			
 * 返回值:无
 * 说  明:已经使能方波输出的情况下使用,设置RS0/RS1即bit0/bit1位
 *******************************************************************************/
void DS1307_SetSqureWaveFreq(struct gpiod_line *sda, struct gpiod_line *scl,uint8_t rate)
{
	uint8_t temp = 0;
	temp = DS1307_Read(sda,scl,DS1307_REG_CONTROL);
	rate &= 0x03; 
	switch (rate)
	{
		case 0: temp &= 0xFC; break;//1Hz
		case 1: temp &= 0xFD; temp |=0x01; break;//4.096kHz
		case 2: temp |= 0x02; temp &=0xFE; break;//8.192kHz
		case 3: temp |= 0x03; break;//32.768kHz
		default: break;
	}
	DS1307_Write(sda,scl,DS1307_REG_CONTROL, temp);
}
/*******************************************************************************
 * 函数名:DS1307_OutHigh
 * 功  能:Out引脚输出高电平
 * 参  数:无			
 * 返回值:无
 * 说  明:bit7写1,在禁止方波输出的情况下使用
 *******************************************************************************/
void DS1307_OutHigh(struct gpiod_line *sda, struct gpiod_line *scl)
{
	uint8_t temp = 0;
	temp = DS1307_Read(sda,scl,DS1307_REG_CONTROL);
	temp |= 0x80;
	DS1307_Write(sda,scl,DS1307_REG_CONTROL, temp);
}
/*******************************************************************************
 * 函数名:DS1307_OutLow
 * 功  能:Out引脚输出低电平
 * 参  数:无			
 * 返回值:无
 * 说  明:bit7写0,在禁止方波输出的情况下使用
 *******************************************************************************/
void DS1307_OutLow(struct gpiod_line *sda, struct gpiod_line *scl)
{
	uint8_t temp = 0;
	temp = DS1307_Read(sda,scl,DS1307_REG_CONTROL);
	temp &= 0x7F;
	DS1307_Write(sda,scl,DS1307_REG_CONTROL, temp);
}
/*******************************************************************************
 * 函数名:DS1307_Init
 * 功  能:初始化时钟芯片
 * 参  数:无			
 * 返回值:无
 * 说  明:
 *******************************************************************************/
void DS1307_Init(struct gpiod_line *sda, struct gpiod_line *scl)
{
	uint8_t temp = 0;
	temp = DS1307_Read(sda,scl,0x08);//读RAM第一字节
	if (temp != 0x5A)//不正确,重新初始化
	{        
		DS1307_SetYear(sda,scl,24);//24年
		DS1307_SetDay(sda,scl,3);//星期3
		DS1307_SetMonth(sda,scl,1);//1月
		DS1307_SetDate(sda,scl,12);//12日
		DS1307_SetHourMode(sda,scl,0);//0,24小时模式,1,12小时模式
		DS1307_SetHour(sda,scl,23);
		DS1307_SetMinute(sda,scl,18);
		DS1307_SetSecond(sda,scl,1);
		DS1307_ClearHaltFlag(sda,scl);//清除Halt标志
		DS1307_Write(sda,scl,0x08, 0x5A);//写入0x5A        
	}
}
//示例代码
#if(0)
int main(int argc, char *argv[])
{
	struct gpiod_line *sda, *scl;
// 打开 GPIO 芯片
	struct gpiod_chip *chip = gpiod_chip_open_by_name(CHIPNAME);
	if (!chip) {
		perror("Open gpiochip failed");
		return 1;
	}
	
	scl = gpiod_chip_get_line(chip, 76);
	sda = gpiod_chip_get_line(chip, 75);
	if (!scl || !sda) {
		perror("Get GPIO line failed");
		gpiod_chip_close(chip);
		return 1;
	}
	if ((gpiod_line_request_output(scl, "scl", 0) < 0) || (gpiod_line_request_output(sda, "sda", 0) < 0)) {
		perror("Request GPIO as output failed");
		gpiod_chip_close(chip);
		return 1;
	}
	
	DS1307_Init(sda,scl);
	
	DS1307_SetYear(sda,scl,24);//24年
	DS1307_SetDay(sda,scl,3);//星期3
	DS1307_SetMonth(sda,scl,1);//1月
	DS1307_SetDate(sda,scl,12);//12日
	DS1307_SetHourMode(sda,scl,0);//0,24小时模式,1,12小时模式
	DS1307_SetHour(sda,scl,23);
	DS1307_SetMinute(sda,scl,18);
	DS1307_SetSecond(sda,scl,1);
	DS1307_ClearHaltFlag(sda,scl);//清除Halt标志
	DS1307_Write(sda,scl,0x08, 0x5A);//写入0x5A  
	
	while (1) {
		printf("getyear = [%d]\r\n",DS1307_GetYear(sda,scl));//24
		printf("getmonth = [%d]\r\n",DS1307_GetMonth(sda,scl));//1
		printf("getday = [%d]\r\n",DS1307_GetDate(sda,scl));//31
		printf("gethour = [%d]\r\n",DS1307_GetHour(sda,scl));//23
		printf("getminute = [%d]\r\n",DS1307_GetMinute(sda,scl));//18
		printf("getsecond = [%d]\r\n",DS1307_GetSecond(sda,scl));//1
		printf("getweek = [%d]\r\n",DS1307_GetDay(sda,scl));//3
		sleep(1);
	}
	
	// 释放 GPIO
	gpiod_line_release(sda);
	gpiod_line_release(scl);
	gpiod_chip_close(chip);
	return 0;
}
#endif
`
posted @ 2024-09-14 11:33  BUG_KING  阅读(32)  评论(0编辑  收藏  举报