查看: 1861|回复: 4

[S32] 【我的项目666--智能楼宇门禁】驱动I2C外设DS3231

[复制链接]
  • TA的每日心情
    开心
    2018-4-20 15:04
  • 签到天数: 8 天

    [LV.3]偶尔看看II

    49

    主题

    188

    帖子

    1

    金牌会员

    Rank: 6Rank: 6

    积分
    2972
    最后登录
    2023-7-24
    发表于 2018-7-16 01:57:14 | 显示全部楼层 |阅读模式
    本帖最后由 donatello1996 于 2018-7-18 23:25 编辑

        在Linux的嵌入式系统中,通常都会预先安装一个甚至多个的I2C设备树,这样,Linux嵌入式系统要与I2C从机通信甚至要比单片机更简单。首先,我们可以在/dev目录下找到跟I2C通信总线有关的文件:
    33.jpg
    如图,在米尔IOT板子里面,I2C-1被启用,然后查阅官方文档可得知,I2C-1总线对应开发板的I2C_2的一组引脚:
    34.jpg
    然后,我们就可以将这组引脚连上一个I2C外设,这里我连上一个通信方式非常简单的I2C外设——DS3231:
    IMG_20180715_235703R.jpg
    连上之后,我们就可以使用
    1. i2cdetect -y 1
    复制代码

    命令查看DS3231设备:
    我们都知道DS3231的器件从机地址就是0x68,因此,这个0x68就是DS3231:
    35.jpg
    然后,我们可以用
    1. i2cdump -y 1 0x68
    复制代码
    将DS3231的内容导出:
    36.jpg
    在DS3231中,0x00-0x06这7个寄存器对应秒、分、时、星期、日期、月、年,我们再dump一次看看读数变化:
    37.jpg
    可以看到现在的时间是00:03:09,因为我的DS3231没有装纽扣电池,因此没有掉电保存功能,不供电的时候不走时。


    在Linux中,读写I2C外设数据的方式均是通过ioctl函数,用户可通过这个函数访问内核存储空间,其中ioctl函数的第一个参数是文件号,这个参数


    决定ioctl函数访问哪个设备的存储空间,如:
    1. int i2c1_fd;
    复制代码



    即为访问/dev/i2c-1的存储空间。另外,在Linux中,对I2C器件的相关操作和结构体/宏定义等保存在
    1. #include<linux/i2c.h>
    复制代码

    两个头文件中,添加头文件路径,即可支持
    1. struct i2c_rdwr_ioctl_data XXX;
    复制代码

    i2c_rdwr_ioctl_data结构体,里面存放了与I2C通信有关的数据,如器件地址,读/写位,读/写长度等。
    看看程序:
    1.     if ((i2c1_fd=open("/dev/i2c-1",O_RDWR))<0)
    2.     {
    3.         printf("Fail to open I2C device\n");
    4.         return 0;
    5.     }
    6.     pcf8951_data.nmsgs=2;
    7.     pcf8951_data.msgs=(struct i2c_msg*)malloc(pcf8951_data.nmsgs*sizeof(struct i2c_msg));
    8.     if(!pcf8951_data.msgs)
    9.     {
    10.         printf("malloc error\n");
    11.         return 0;
    12.     }
    13.     Clear_Screen(0xff00ffff);
    14.     LCD_Effect();
    15.     while(1)

    16.     {
    17.         /*
    18.         if (read(keys_fd, &t, sizeof(t)) == sizeof(t))
    19.         {
    20.             if(t.type==EV_KEY)
    21.                 if(t.value==0)
    22.                     system("echo 0 > /sys/class/gpio/gpio9/value");
    23.                 else if(t.value==1)
    24.                     system("echo 1 > /sys/class/gpio/gpio9/value");
    25.         }
    26.         */
    27.         pcf8951_data.nmsgs=2;
    28.         (pcf8951_data.msgs[0]).len=1;
    29.         (pcf8951_data.msgs[0]).addr=I2C_ADDR;
    30.         (pcf8951_data.msgs[0]).flags=0;
    31.         (pcf8951_data.msgs[0]).buf=(unsigned char*)malloc(1);
    32.         (pcf8951_data.msgs[0]).buf[0]=0x00;

    33.         (pcf8951_data.msgs[1]).len=7;
    34.         (pcf8951_data.msgs[1]).addr=I2C_ADDR;
    35.         (pcf8951_data.msgs[1]).flags=I2C_M_RD;
    36.         (pcf8951_data.msgs[1]).buf=(unsigned char*)malloc(7);
    37.         (pcf8951_data.msgs[1]).buf[0]=0;
    38.         (pcf8951_data.msgs[1]).buf[1]=0;
    39.         (pcf8951_data.msgs[1]).buf[2]=0;
    40.         (pcf8951_data.msgs[1]).buf[3]=0;
    41.         (pcf8951_data.msgs[1]).buf[4]=0;
    42.         (pcf8951_data.msgs[1]).buf[5]=0;
    43.         (pcf8951_data.msgs[1]).buf[6]=0;
    44.         if(ioctl(i2c1_fd,I2C_RDWR,&pcf8951_data)<0)
    45.             continue;

    46.         sec=BCDtoBYTE((pcf8951_data.msgs[1]).buf[0]);
    47.         min=BCDtoBYTE((pcf8951_data.msgs[1]).buf[1]);
    48.         hour=BCDtoBYTE((pcf8951_data.msgs[1]).buf[2]);
    49.         day=BCDtoBYTE((pcf8951_data.msgs[1]).buf[3]);
    50.         month=BCDtoBYTE((pcf8951_data.msgs[1]).buf[4]);
    51.         year=BCDtoBYTE((pcf8951_data.msgs[1]).buf[5]);

    52.         Show_ASCII(122,10,0,0xff00ffff,sec%10+'0');
    53.         Show_ASCII(106,10,0,0xff00ffff,sec/10+'0');

    54.         Show_ASCII(90,10,0,0xff00ffff,':');
    55.         Show_ASCII(74,10,0,0xff00ffff,min%10+'0');
    56.         Show_ASCII(58,10,0,0xff00ffff,min/10+'0');
    57.         Show_ASCII(42,10,0,0xff00ffff,':');
    58.         Show_ASCII(26,10,0,0xff00ffff,hour%10+'0');
    59.         Show_ASCII(10,10,0,0xff00ffff,hour/10+'0');
    60.         LCD_Effect();
    61.         usleep(100*1000);
    62.     }
    复制代码
    看看效果:
    6.gif


    我知道答案 目前已有4人回答
    今天心情不错
    回复

    使用道具 举报

  • TA的每日心情
    郁闷
    2018-2-7 18:18
  • 签到天数: 5 天

    [LV.2]偶尔看看I

    13

    主题

    126

    帖子

    1

    金牌会员

    Rank: 6Rank: 6

    积分
    1628
    最后登录
    2021-7-13
    发表于 2018-7-16 18:34:05 | 显示全部楼层
    楼主代码贴的有问题吧?显示的都是源码。
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情

    2017-1-4 08:05
  • 签到天数: 11 天

    [LV.3]偶尔看看II

    85

    主题

    1629

    帖子

    1

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    2569

    优秀版主

    最后登录
    2019-3-28
    发表于 2018-7-22 09:27:56 | 显示全部楼层
    LZ应该没有写过超过1W行的工程,一坨一坨的
    回复 支持 反对

    使用道具 举报

  • TA的每日心情

    2021-4-15 13:25
  • 签到天数: 184 天

    [LV.7]常住居民III

    2

    主题

    573

    帖子

    3

    金牌会员

    Rank: 6Rank: 6

    积分
    1171
    最后登录
    2021-4-15
    发表于 2018-7-30 13:48:16 | 显示全部楼层
    真实真实
    该会员没有填写今日想说内容.
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2018-4-20 15:04
  • 签到天数: 8 天

    [LV.3]偶尔看看II

    49

    主题

    188

    帖子

    1

    金牌会员

    Rank: 6Rank: 6

    积分
    2972
    最后登录
    2023-7-24
     楼主| 发表于 2018-11-24 20:35:40 | 显示全部楼层
    技术范儿 发表于 2018-7-22 09:27
    LZ应该没有写过超过1W行的工程,一坨一坨的

    很抱歉还真写过,只不过社区的试用活动,能调通功能即可,没有对代码做什么规范化管理
    今天心情不错
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2024-5-8 20:54 , Processed in 0.179542 second(s), 34 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表