首页 > 系统相关 >必趣CB1核心板、H616主控linux验证IO模拟I2C驱动DS1307时钟芯片

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

时间:2024-09-14 11:36:54浏览次数:10  
标签:scl H616 struct DS1307 主控 必趣 gpiod line sda

使用了#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
  • 功 能:获取小时
  • 参 数:无
  • 返回值:小时,十进制,112或023
  • 说 明:返回的值需要结合小时模式及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:小时,112或023
  • 返回值:无
  • 说 明:无
    **/
    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

`

标签:scl,H616,struct,DS1307,主控,必趣,gpiod,line,sda
From: https://www.cnblogs.com/embedded-jee/p/18413615

相关文章

  • 【AD那些事 4 】AD铺铜之后如果发现铜皮与主控管脚的焊盘间距太小如何将其间距增大???????
    当我们画完板子之后,肯定会进行铺铜,那么AD铺铜之后如果发现铜皮与主控管脚的焊盘间距太小如何将其间距增大???????铺铜调大间距之后,可能会出现有些线的截断,到时可以将未连接的线进行过孔连接,背面铺铜     调整前                   ......
  • [Maxio] 海康C160SSD/256GB掉盘严重,联芸主控开卡成功分享/固件163个
    海康的固态硬盘掉盘严重,使用工具查看使用量离谱,论坛找了很多Maxio-MAS0902-MAS0901-工具都不成功,颗粒识别为Intel的,最近换了个MAS0902-B16AB17A-D2.0-V1.001.000-A.0.09.019-FT2000工具,颗粒选B16A03055成功开卡。固件收集了163个。.MAS0902-B16AB17A-D2.0-V1.001.000-......
  • 电赛2024年H题智能小车基于MSPM0G3507主控MCU(利用8路灰度加上MPU6050的解决方式)
    一.前言        前段时间,激烈的电赛刚刚结束,很荣幸啊,也是十分的不甘心,本次的湖北赛区H题只拿到了一个省二,看最终的排名,在H题中我们离省一也就差几名。但是整个比赛已经过去了,现在不甘与不舍,也没有任何意义了,只有接收这一现实了。    当时我们整个比赛要求一......
  • 低成本消费类电子主控推荐,PY32F002B单片机 多种封装可选
    今天给大家推荐一颗高性价比单片机,普冉的PY32F002B,专为超高性价比、精简的系统而设计,符合消费市场的基本设计需求,被低成本消费类电子广泛应用。PY32F002B单片机在低成本消费类电子领域具有极大成本优势,价格比部分八位单片机还要便宜,常用的TSSOP20只要5毛,我们还提供无丝印版本给有需......
  • 电子秤方案的主控芯片选型SIC8833
     电子秤的方案设计功能比较简单,四个压力模块和ADC芯片以及再加个主控芯片大约就构成了其核心功能的器件要求。ADC芯片的功能是将压力模块所得到压力值转化为可显示的数值,在通过LED或者LCD屏展现出来,就是后面我们测量物品或体重所得到的重量斤数。 主控芯片就是MCU,它是方案的......
  • Mixgo Feiyi主控简介
    元控·飞乙是一款不仅可以学习常见的传感器(声音、光线、温度、测距等)、执行器(马达、RGB灯等)和点阵屏显示的功能,还可以学习RFID读卡识别、磁场检测、物联网控制等功能的编程主控。主控造型设计上兼容乐高类积木,可以结合积木零件设计出多种具有不同功能的创意作品,增加学生的学习兴趣......
  • 家用空调主控板电路原理
    家用空调主控板电路原理电源电压整流电路:电路原理图:2、器件作用及工作原理:TRAN变压器:将220V电压转换为较低的安全电源电压。D1-D4整流二极管:主要型号为1N4007,反向耐压值为1000V,正向安全电流1A;E1,E2电解电容:位于整流电路后端,主要起滤波稳压作用,主要参数有额......
  • 集中式DTU站所终端2021版-主控核心单元
    适用范围:APT-6600J集中式DTU站所终端产品适用于10KV、35KV及以下的配电站、室内开闭所、配电房、户外环网柜、环网箱、箱变等。可实现数据实时采集,远程控制、故障就地动作、主站加密通讯、北斗/GPS对时,并集成线损测量、远程通讯模块、就地通讯模块、标准化运维等功能,最大支......
  • 集中式DTU与4、6、8、12、16回路DTU主控单元
    一、集中式DTU集中式DTU适用范围:集中式DTUAPT-6600站所终端适用于配电系统中变电站、户外开闭所、箱变、开关站、环网柜、配电室等场合中的检测和控制需求。集中式DTU主要功能:采集配电网实时运行数据进行处理和分析,通过通信通道(如光纤、载波、无线等),上传至配网主站,并......
  • 系统FM802,FM803主控和利时
    系统FM802,FM803主控和利时接近开关通常有两种:埋入型和非埋入型。所谓埋入型就是指接近开关的感应头不检测其圆周方向的金属目标,系统FM802,FM803主控和利时即传感器感应头必须露出金属安装支架一段距离且圆周方向一定范围内不得有金属目标物以免引起错误判断。系统FM802,FM803......