linux下i2c与时钟芯片pcf8563通信(二)

linux 下 i2c 的驱动 以及 与时钟芯片 pcf8563之间的通信(二)

 
 2012/7/10

linux下i2c驱动与通信(二)

by:韩大卫 @吉林师范大学


在i2c-test的基础上, 使用i2c与Pcf8563通信,通过发送和接收数据,对rtc芯片进行set 和get操作。 

既然是操作时间,可以使用struct rtc_time,  定义如下:

struct rtc_time {
        int tm_sec;
        int tm_min;
        int tm_hour;
        int tm_mday;
}

在pcf8563_get_datetime() 中:


struct i2c_msg msgs[] = {
                { client->addr, 0, 1, buf },    /* setup read ptr */
                { client->addr, I2C_M_RD, 13, buf },    /* read status + date */
        };


定义了两个msg,  在i2c-octeon 中分别进入了

ret = octeon_i2c_simple_write()


ret = octeon_i2c_read()


进入simple_write()作用是将第一个buf  即offset  写入寄存器,这样在read函数即可直接读此寄存器。


2012.7.11  .14:50

出现这样一个问题:

root@juson:/han# ./i2c-test 
strlen(buf) = 1
buf[0] = 8 
root@juson:/han# ./i2c-test -r
strlen(buf) = 1
buf[0] = 8 
root@juson:/han# ./i2c-test -l
2012年 07月 11日 星期三 21:49:41
root@juson:/han# ./i2c-test 
strlen(buf) = 13
buf[0] = 8 
buf[1] = 40 
buf[2] = 43 
buf[3] = 49 
buf[4] = 21 
buf[5] = 11 
buf[6] = 3 
buf[7] = 7 
buf[8] = 12 
buf[9] = a0 
buf[10] = 84 
buf[11] = b2 
buf[12] = b5 



有少两情况下会出现strlen(buf) = 13


过一会:
root@juson:/han# ./i2c-test 
strlen(buf) = 13
buf[0] = 8 
buf[1] = 40 
buf[2] = 54 
buf[3] = 53 
buf[4] = 21 
buf[5] = 11 
buf[6] = 3 
buf[7] = 7 
buf[8] = 12 
buf[9] = a0 
buf[10] = 84 
buf[11] = b2 
buf[12] = b5 
root@juson:/han# ./i2c-test 
strlen(buf) = 13
buf[0] = 8 
buf[1] = 40 
buf[2] = 55 
buf[3] = 53 
buf[4] = 21 
buf[5] = 11 
buf[6] = 3 
buf[7] = 7 
buf[8] = 12 
buf[9] = a0 
buf[10] = 84 
buf[11] = b2 
buf[12] = b5 

这次是全部是root@juson:/han# ./i2c-test 
strlen(buf) =13 的情况。 

代码中:

for(i = 0; i< strlen(buf); i++)
              printf("buf[%d] = %x\n",i,buf[i]);

本意是想看经过read_data(addr, offset, buf) 后, buf中成员有多少被赋值了,但忘记了一个地方:

strlen(buf)

这个函数是遇到buf中的0,或者'\0' 就截止的,恰好 第二个寄存器01h control_status 的值有时候恰好为0x0,或者0x40,这样,当为0x0时候strlen(buf) 就为1了。


01h control_status_2 0 0 STOP 0 TESTC 0 0 0

改为 for(i = 0; i< 13; i++)
 printf("buf[%d] = %x\n",i,buf[i]);

可以看出,strlen(buf) = 13
buf[0] = 8
buf[1] = 40
buf[2] = 43
buf[3] = 15
buf[4] = 22
buf[5] = 11
buf[6] = 3
buf[7] = 7
buf[8] = 12
buf[9] = a0
buf[10] = 84
buf[11] = b2
buf[12] = b5

另一种情况:

strlen(buf) = 1
buf[0] = 8
buf[1] = 0
buf[2] = 39
buf[3] = 15
buf[4] = 22
buf[5] = 11
buf[6] = 3
buf[7] = 7
buf[8] = 12
buf[9] = a0
buf[10] = 84
buf[11] = b2
buf[12] = b5


这时候strlen就出现了让人迷惑的显示!


15:50 。出现了段错误:

这条语句:
   tm->tm_sec = bcd2bin(buf[PCF8563_REG_SC] & 0x7F);
 52         /*
 53         tm->tm_min = buf[PCF8563_REG_MN] & 0x7F;
 54         tm->tm_hour = buf[PCF8563_REG_HR] & 0x3F; // rtc hr 0-23 
 55         tm->tm_mday = buf[PCF8563_REG_DM] & 0x3F;


  tm->tm_sec = bcd2bin(buf[PCF8563_REG_SC] & 0x7F);
检查了struct rtc_time{
成员都是对的。怎么会段错误。
肯定的指针的问题。

struct rtc_time *tm;

 tm->tm_min = buf[PCF8563_REG_MN] & 0x7F;
       tm->tm_hour = buf[PCF8563_REG_HR] & 0x3F; // rtc hr 0-23 
          tm->tm_mday = buf[PCF8563_REG_DM] & 0x3F;

平时运行的时候都没有出现问题,但本身是有问题的。

错误原因:  *tm 本身是野指针 !
定义了这个指针后:要用malloc 对tm 进行分配内存。


struct rtc_time *tm = (struct rtc_time*)malloc(sizeof(struct rtc_time));


总结: 使用指针时候,一定要谨慎!  一定要先malloc, 再对其内容操作!


17:39
另一个问题:

unsigned char data;

data 最大只能存255, 256就是0了。
那么
write_data(0x51,0x08,data) 的时候,  

年份不能直接传给data,否则会溢出。

就是2012:07:11 时候,如果将2012直接赋值给data,那么会产生溢出,data不会是原来的值。

2012 的bin是: 11111011100

unsigned char data 之能保存8bit,
1101 1100

十进制是220。


怎么办:

先参考pcf8563_set_datetime。中的代码:
unsigned char buf[9];

        /* hours, minutes and seconds */
        buf[PCF8563_REG_SC] = bin2bcd(tm->tm_sec);
        buf[PCF8563_REG_MN] = bin2bcd(tm->tm_min);
        buf[PCF8563_REG_HR] = bin2bcd(tm->tm_hour);

        buf[PCF8563_REG_DM] = bin2bcd(tm->tm_mday);

        /* month, 1 - 12 */
        buf[PCF8563_REG_MO] = bin2bcd(tm->tm_mon + 1);

        /* year and century */
        buf[PCF8563_REG_YR] = bin2bcd(tm->tm_year % 100);
        if (pcf8563->c_polarity ? (tm->tm_year >= 100) : (tm->tm_year < 100))
                buf[PCF8563_REG_MO] |= PCF8563_MO_C;

        buf[PCF8563_REG_DW] = tm->tm_wday & 0x07;


buf[PCF8563_REG_YR] = bin2bcd(tm->tm_year % 100);


%100,  就可以把最后的8bit取得。

 if (pcf8563->c_polarity ? (tm->tm_year >= 100) : (tm->tm_year < 100))
                buf[PCF8563_REG_MO] |= PCF8563_MO_C;


这样把PCF8563_REG_MO的 PCF8563_MO_C bit  决定是否置位。

2012.7.12

一个新的小问题:

  if(*(ptr+2)             ==      ':'){
                tm->tm_hour     =       atoi(ptr);
                tm->tm_min      =       atoi(ptr + 3);  
                tm->tm_sec      =       atoi(ptr + 6); 
             
        }   
        else if(*(ptr+4)        ==      ':'){
                tm->tm_year     =       atoi(ptr);
                tm->tm_mon      =       atoi(ptr + 5); 
                tm->tm_mday     =       atoi(ptr + 8); 
                    
                if(*(ptr+10)    ==      '-'){
                tm->tm_hour     =       atoi(ptr + 11);
                tm->tm_min      =       atoi(ptr + 14); 
                tm->tm_sec      =       atoi(ptr + 17);
       
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值