且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

I.MX6 I2C DS1337 disable square-wave output

更新时间:2022-08-12 21:11:37

                   linux I2C DS1337 disable square-wave output


                        \\\\\\\\\\\-*- 目录 -*-//////////
                        |   一、DS1337访问寄存器说明:    
                        |   二、cat main.c
                        |   三、cat i2c_data.c
                        |   四、cat i2c_data.h
                        |   五、cat Android.mk
                        --------------------------------

一、DS1337控制寄存器说明:    
    1. reference: 
       1. DS1337 I2C Serial Real-Time Clock
       2. How to: wire the DS1337 RTC?
           http://forum.arduino.cc/index.php?topic=20937.02. SPECIAL-PURPOSE REGISTERS 
       The DS1337 has two additional registers (control and status) that control the RTC, alarms, and square-wave output. 
    3. Control Register (0Eh) 
       +-------+-------+-------+-------+-------+-------+-------+-------+
       | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | 
       +-------+-------+-------+-------+-------+-------+-------+-------+
       | EOSC  | 0     | 0     | RS2   | RS1   | INTCN | A2IE  | A1IE  | 
       +-------+-------+-------+-------+-------+-------+-------+-------+
       1. Bit 7: Enable Oscillator (EOSC). This active-low bit when set to logic 0 starts the oscillator. When this bit is set to logic 1, the oscillator is stopped. This bit is enabled (logic 0) when power is first applied.
       2. Bits 4 and 3: Rate Select (RS2 and RS1). These bits control the frequency of the square-wave output when the square wave has been enabled. The table below shows the square-wave frequencies that can be selected with the RS bits. These bits are both set to logic 1 (32kHz) when power is first applied.
       3. SQW/INTB Output:
           +------+-----+-----+-----------+------+
           | NTCN | RS2 | RS1 | SQW/INTB  | A2IE | 
           |      |     |     |  OUTPUT   |      | 
           +------+-----+-----+-----------+------+
           | 0    | 0   | 0   | 1Hz       | X    | 
           +------+-----+-----+-----------+------+
           | 0    | 0   | 1   | 4.096kHz  | X    | 
           +------+-----+-----+-----------+------+
           | 0    | 1   | 0   | 8.192kHz  | X    | 
           +------+-----+-----+-----------+------+
           | 0    | 1   | 1   | 32.768kHz | X    | 
           +------+-----+-----+-----------+------+
           | 1    | X   | X   | A2F       | 1    | 
           +------+-----+-----+-----------+------+
       4. Bit 2: Interrupt Control (INTCN). This bit controls the relationship between the two alarms and the interrupt output  pins. When the INTCN bit is set to logic 1, a match between the timekeeping registers and the alarm 1 registers l activates the INTA pin (provided that the alarm is enabled) and a match between the timekeeping registers and the alarm 2 registers activates the SQW/INTB pin (provided that the alarm is enabled). When the INTCN bit is set to logic 0, a square wave is output on the SQW/INTB pin. This bit is set to logic 0 when power is first applied. 
       5. Bit 1: Alarm 2 Interrupt Enable (A2IE). When set to logic 1, this bit permits the alarm 2 flag (A2F) bit in the status register to assert INTA (when INTCN = 0) or to assert SQW/INTB (when INTCN = 1). When the A2IE bit is set to logic 0, the A2F bit does not initiate an interrupt signal. The A2IE bit is disabled (logic 0) when power is first applied. 
       6. Bit 0: Alarm 1 Interrupt Enable (A1IE). When set to logic 1, this bit permits the alarm 1 flag (A1F) bit in the status register to assert INTA. When the A1IE bit is set to logic 0, the A1F bit does not initiate the INTA signal. The A1IE bit is disabled (logic 0) when power is first applied. 
    

二、cat main.c
    #include <stdio.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include "i2c-dev.h"
    #include "i2c.h"
    #include "i2c_data.h"


    int main ( int argc, char ** argv ) {
        int fd,ret;
    
        fd = open( "/dev/i2c-2", O_RDWR );
        if ( fd < 0 ) {
            perror( "open error\n" );
        }
        
        unsigned char ch = 0;
        // 通过测试秒数来判断访问芯片DS1337没问题
        // terminal output: get data from ds1337 0x00: 54
        i2c_data_read_byte( fd, 0x68, 0x00, &ch );
        printf( "get data from ds1337 0x00: %x\n", ch );
    
        i2c_data_read_byte( fd, 0x68, 0x0e, &ch );
        // terminal output: get data from ds1337 0x0e: 18
        printf( "get data from ds1337 0x0e: %x\n", ch );
    
        // 关闭方波输出
        ch = 0x98;
        i2c_data_write_byte( fd, 0x68, 0x0e, ch );
    
        i2c_data_read_byte( fd, 0x68, 0x0e, &ch );
        // terminal output: get data from ds1337 0x0e: 98
        printf( "get data from ds1337 0x0e: %x\n", ch );
    
        i2c_data_read_byte( fd, 0x68, 0x0F, &ch );
        // terminal output: get data from ds1337 0x0f: 0
        printf( "get data from ds1337 0x0f: %x\n", ch );
    
        close( fd );
    
        return 0;
    }


三、cat i2c_data.c
    #include <stdio.h>
    #include <string.h>
    #include <linux/types.h>
    #include <stdlib.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/ioctl.h>
    #include <errno.h>
    #include "i2c-dev.h"
    #include "i2c.h"
    #include "i2c_data.h"
     
    // A demo for test
    int eepromDemo ( int argc, char **argv ) {
        int fd,ret;
    
        fd = open("/dev/i2c-3",O_RDWR);
        if ( fd < 0 ) {
            perror("open error\n");
        }
        
        unsigned char buf[] = {'x', 'x', 'x', '0', 'y', 'm', '\0'};
        i2c_data_write_byte( fd, 0x50, 0, 'z' );
        i2c_data_write_byte( fd, 0x50, 1, 'j' );
        i2c_data_write_byte( fd, 0x50, 2, 'f' );
        //printf("i2c function test: %s\n", buf);
        //i2c_data_write_byte (fd, 0x50, 3, buf[1]);
        //i2c_data_read_str (fd, 0x50, 0, buf, array_size(buf)-1);
    
        //unsigned char ch = 0;
        i2c_data_read_byte(fd, 0x50, 1, &ch);
        
        close(fd);
    
        return 0;
    }
    
    /*****************************************************************************
     * 函数说明:
     *     往i2c设备写数据,写一串字节
     * 参数说明:
     *     1. fd:     文件描述符
     *     2. addr:   i2c设备地址
     *     3. offset: i2c设备内寄存器偏移地址
     *     4. buf:    字节数组
     *     5. count:  字节数组长度
     * 返回值:
     *     正常返回写入的个数,如果出错,返回错误码
     ****************************************************************************/
    int i2c_data_write_str (int fd, int addr, int offset, unsigned char *buf, int count) {
        int ret = 0;
        struct i2c_rdwr_ioctl_data i2c_data;
    
        i2c_data.nmsgs = 1;     /* 每次只写一个字节 */
        i2c_data.msgs  = (struct i2c_msg*)malloc(i2c_data.nmsgs*sizeof(struct i2c_msg));
        if(!i2c_data.msgs)
        {
            perror("i2c_data_write_str function malloc error.\n");
            return -1;
        }
    
        ioctl(fd, I2C_TIMEOUT, 1); /*超时时间*/
        ioctl(fd, I2C_RETRIES, 2); /*重复次数*/
    
        (i2c_data.msgs[0]).buf = (unsigned char*)malloc(2);
    
        int i = 0;
        for (i = 0; i < count; i++) {
    
            (i2c_data.msgs[0]).len      = 2;
            (i2c_data.msgs[0]).addr     = addr;     //i2c 设备地址
            (i2c_data.msgs[0]).flags    = 0;        //write
            (i2c_data.msgs[0]).buf[0]   = (unsigned char)offset+i;   // i2c 写入目标的地址
            (i2c_data.msgs[0]).buf[1]   = (unsigned char)buf[i];     //the data to write
    
            ret = ioctl(fd, I2C_RDWR, (unsigned long)&i2c_data);
            if(ret < 0) {
                perror("i2c_data_write_str ioctl error");
                return ret;
            }   
        }   
    
        free((i2c_data.msgs[0]).buf);
        free(i2c_data.msgs);
        return i;
    }
    
    /************************************************************************
     * 函数说明:
     *     往i2c设备写数据,写一个字节
     * 参数说明:
     *     1. fd:     文件描述符
     *     2. addr:   i2c设备地址
     *     3. offset: i2c设备内寄存器偏移地址
     *     4. buf:    要写入的字节
     * 返回值:
     *     正常返回0,出错,返回错误码;
     ************************************************************************/
    int i2c_data_write_byte (int fd, int addr, int offset, unsigned char buf) {
    
        int ret = 0;
        struct i2c_rdwr_ioctl_data i2c_data;
    
        i2c_data.nmsgs = 1; /* 每次只写一个字节 */
        i2c_data.msgs  = (struct i2c_msg*)malloc(i2c_data.nmsgs*sizeof(struct i2c_msg));
        if(!i2c_data.msgs)
        {
            perror("i2c_data_write_byte function malloc error.\n");
            return -1;
        }
    
        ioctl(fd,I2C_TIMEOUT,4); /*超时时间*/
        ioctl(fd,I2C_RETRIES,8); /*重复次数*/
    
        (i2c_data.msgs[0]).buf      = (unsigned char*)malloc(2);
    
        (i2c_data.msgs[0]).len      = 2;
        (i2c_data.msgs[0]).addr     = addr;     //i2c 设备地址
        (i2c_data.msgs[0]).flags    = 0;        //write
        (i2c_data.msgs[0]).buf[0]   = (unsigned char)offset;    // i2c 写入目标的地址
        (i2c_data.msgs[0]).buf[1]   = (unsigned char)buf;       //the data to write
    
        ret = ioctl(fd, 0x0707, (unsigned long)&i2c_data);
        if(ret < 0) {
            perror("i2c_data_write_byte ioctl error");
            return ret;
        }   
    
        free((i2c_data.msgs[0]).buf);
        free(i2c_data.msgs);
        return ret;
    }
    
    /*************************************************************************
     * 函数说明:
     *     从i2c设备读数据,读一个字节
     * 参数说明:
     *     1. fd:     文件描述符
     *     2. addr:   i2c设备地址
     *     3. offset: i2c设备内寄存器偏移地址
     *     4. buf:    保存读出的字节指针
     * 返回值:
     *     正常返回0,出错,返回错误码;
     ************************************************************************/
    int i2c_data_read_byte (int fd, int addr, int offset, unsigned char *buf) {
        int ret;
        struct i2c_rdwr_ioctl_data i2c_data;
    
        i2c_data.nmsgs = 2; /*读时序为2个开始信号*/
        i2c_data.msgs  = (struct i2c_msg*)malloc(i2c_data.nmsgs*sizeof(struct i2c_msg));
        if(!i2c_data.msgs) {
            perror("i2c_data_read_byte functionmalloc error");
            exit(1);
        }
    
        ioctl(fd,I2C_TIMEOUT,1); /*超时时间*/
        ioctl(fd,I2C_RETRIES,2); /*重复次数*/
    
        (i2c_data.msgs[0]).len      = 1;        //i2c 目标数据的地址
        (i2c_data.msgs[0]).addr     = addr;     // i2c 设备地址
        (i2c_data.msgs[0]).flags    = 0;        //write
        (i2c_data.msgs[0]).buf      = (unsigned char*)malloc(1);
        (i2c_data.msgs[0]).buf[0]   = offset;   //i2c 数据地址
    
        (i2c_data.msgs[1]).len      = 1;        //读出的数据
        (i2c_data.msgs[1]).addr     = addr;     // i2c 设备地址
        (i2c_data.msgs[1]).flags    = I2C_M_RD; //read
        (i2c_data.msgs[1]).buf      = (unsigned char*)malloc(1);//存放返回值的地址。
        (i2c_data.msgs[1]).buf[0]   = 0;        //初始化读缓冲
    
        ret = ioctl(fd, I2C_RDWR, (unsigned long)&i2c_data);
        if(ret<0) {
            perror("i2c_data_read_byte ioctl error.\n");
            return ret;
        }
    
        //printf("buff[0] = %x\n",i2c_data.msgs[1].buf[0]);
        *buf = i2c_data.msgs[1].buf[0];
    
        free((i2c_data.msgs[0]).buf);
        free((i2c_data.msgs[1]).buf);
        free(i2c_data.msgs);
    
        return ret;
    }
    
    /**********************************************************************************
     * 函数说明:
     *     从i2c设备读数据,读一串字节
     * 参数说明:
     *     1. fd:     文件描述符
     *     2. addr:   i2c设备地址
     *     3. offset: i2c设备内寄存器偏移地址
     *     4. buf:    保存从i2c设备读出数据的字节数组指针
     *     5. count:  要读的字节个数
     * 返回值:
     *     正常返回0,如果出错,返回错误码
     **********************************************************************************/
    int i2c_data_read_str (int fd, int addr, int offset, unsigned char *buf, int count) {
        int ret;
        struct i2c_rdwr_ioctl_data i2c_data;
    
        i2c_data.nmsgs = 2; 
        i2c_data.msgs  = (struct i2c_msg*)malloc(i2c_data.nmsgs*sizeof(struct i2c_msg));
        if(!i2c_data.msgs) {
            perror("i2c_data_read_byte functionmalloc error");
            exit(1);
        }
    
        ioctl(fd, I2C_TIMEOUT, 1); /*超时时间*/
        ioctl(fd, I2C_RETRIES, 2); /*重复次数*/
    
        (i2c_data.msgs[0]).len      = 1;        //i2c 目标数据的地址
        (i2c_data.msgs[0]).addr     = addr;     // i2c 设备地址
        (i2c_data.msgs[0]).flags    = 0;        //write
        (i2c_data.msgs[0]).buf      = (unsigned char*)malloc(1);
        (i2c_data.msgs[0]).buf[0]   = offset;   //i2c 数据地址
    
        (i2c_data.msgs[1]).len      = count;    //读出的数据
        (i2c_data.msgs[1]).addr     = addr;     // i2c 设备地址
        (i2c_data.msgs[1]).flags    = I2C_M_RD; //read
        (i2c_data.msgs[1]).buf      = buf;      //存放返回值的地址。
    
        ret = ioctl(fd, I2C_RDWR, (unsigned long)&i2c_data);
        if(ret<0) {
            perror("i2c_data_read_byte ioctl error.\n");
            return ret;
        }
        //buf[count] = 0;
        //printf("buf = %s\n", buf);
    
        free((i2c_data.msgs[0]).buf);
        free(i2c_data.msgs);
    
        return 0;
    }


四、cat i2c_data.h
    /**************************************************************************************
     * 声明:
     *     这个函数库主要用于读写i2c设备,提供了以下功能:
     *         1. 读一串字节:i2c_data_read_str()
     *         2. 读一个字节:i2c_data_read_byte()
     *         3. 写一串字节:i2c_data_write_str()
     *         4. 写一个字节:i2c_data_write_byte()
     *
     *
     *                                      write by zengjf     2015-4-28
     **************************************************************************************/
    #ifndef __I2C_DATA_H__
        #define __I2C_DATA_H__
    
    #define array_size(array_buffer) (sizeof(array_buffer)/sizeof(*array_buffer))
    
    /**********************************************************************************
     * 函数说明:
     *     往i2c设备写数据,写一串字节
     * 参数说明:
     *     1. fd:     文件描述符
     *     2. addr:   i2c设备地址
     *     3. offset: i2c设备内寄存器偏移地址
     *     4. buf:    字节数组
     *     5. count:  字节数组长度
     * 返回值:
     *     正常返回写入的个数,如果出错,返回错误码
     *********************************************************************************/
    int i2c_data_write_str (int fd, int addr, int offset, unsigned char *buf, int count);
    
    /**********************************************************************************
     * 函数说明:
     *     从i2c设备读数据,读一串字节
     * 参数说明:
     *     1. fd:     文件描述符
     *     2. addr:   i2c设备地址
     *     3. offset: i2c设备内寄存器偏移地址
     *     4. buf:    保存从i2c设备读出数据的字节数组指针
     *     5. count:  要读的字节个数
     * 返回值:
     *     正常返回0,如果出错,返回错误码
     **********************************************************************************/
    int i2c_data_read_str (int fd, int addr, int offset, unsigned char *buf, int count);
    
    /**********************************************************************************
     * 函数说明:
     *     往i2c设备写数据,写一个字节
     * 参数说明:
     *     1. fd:     文件描述符
     *     2. addr:   i2c设备地址
     *     3. offset: i2c设备内寄存器偏移地址
     *     4. buf:    要写入的字节
     * 返回值:
     *     正常返回0,出错,返回错误码;
     **********************************************************************************/
    int i2c_data_write_byte (int fd, int addr, int offset, unsigned char buf);
    
    /**********************************************************************************
     * 函数说明:
     *     从i2c设备读数据,读一个字节
     * 参数说明:
     *     1. fd:     文件描述符
     *     2. addr:   i2c设备地址
     *     3. offset: i2c设备内寄存器偏移地址
     *     4. buf:    保存读出的字节指针
     * 返回值:
     *     正常返回0,出错,返回错误码;
     **********************************************************************************/
    int i2c_data_read_byte (int fd, int addr, int offset, unsigned char *buf);
    
    #endif //__I2C_DATA_H__
        

五、cat Android.mk
    LOCAL_PATH := $(call my-dir)
    
    include $(CLEAR_VARS)
    
    LOCAL_MODULE    := linuxTest
    LOCAL_SRC_FILES := linuxTest.c i2c_data.c
    
    include $(BUILD_EXECUTABLE)