分享

GPIO模拟的I2C操作

 射天狼星 2014-09-17

GPIO模拟的I2C操作

 (2012-05-15 10:57:03)
标签: 

i2c

 

gpio

 

模拟

 

it

分类: 科技

下面是模拟程序,后来有一天我才知道,原来新的kernel中已经提供了一种通过两个gpio口调用i2c-core的机制,而且还能在这两个gpio口挂载多个设备,用起来就像真的i2c总线一样。所以以后我们都应该用kernel中的这种机制!毕竟自己写的模拟代码不是很可靠的,而且不方便挂载多个设备(当然,你可以通过复杂的逻辑和方法去实现,但是这不值得,除非你是本着学习的目的)

不过这个自己写的gpio模拟i2c的代码通过对gpio的不停的拉高拉低来模拟scl和sda线的动作可以让我们对i2c的操作和协议认识的更清楚。因此对于初学者来说还是有一较大价值的。其实,从经验上讲,每一个刚刚接触到嵌入式的同学都应该能够自己独立完成一个这样的模拟操作!这样你会提高的很快!

 

代码如下:

这不是完整的代码,仅仅提供模拟操作部分供大家参考。

 

  1.    
  2. #define DELAY   1   
  3. #define SCL     89   
  4. #define SDA     20   
  5. #define RST     19   
  6. #define IRQ     108   
  7. void i2c_start(void 
  8.       
  9.     gpio_direction_output(SDA, 1);    
  10.     gpio_direction_output(SCL, 1);  
  11.     udelay(DELAY);  
  12.       
  13.     gpio_set_value(SDA, 0);  
  14.     udelay(DELAY);      
  15.             
  16.     gpio_set_value(SCL, 0);  
  17.     udelay(DELAY);  
  18.  
  19. void i2c_stop(void 
  20.   
  21.     gpio_set_value(SCL, 0);  
  22.     gpio_set_value(SDA, 0);  
  23.     udelay(DELAY);  
  24.       
  25.     gpio_set_value(SCL, 1);  
  26.     udelay(DELAY);  
  27.     gpio_set_value(SDA, 1);  
  28.     udelay(DELAY);  
  29.  
  30. void i2c_send_ack(u8 ack)  
  31.  
  32.     if(ack)  
  33.         gpio_direction_output(SDA, 1);   
  34.     else   
  35.         gpio_direction_output(SDA, 0);  
  36.     udelay(DELAY);  
  37.       
  38.     gpio_set_value(SCL, 1);  
  39.     udelay(DELAY);  
  40.       
  41.     gpio_set_value(SCL, 0);  
  42.     udelay(DELAY);    
  43.  
  44. u8 i2c_receive_ack(void 
  45.  
  46.     u8 rc 0;  
  47.       
  48.     gpio_direction_input(SDA);  
  49.     gpio_set_value(SCL, 1);  
  50.     udelay(DELAY);  
  51.       
  52.     if(gpio_get_value(SDA))  
  53.         rc 1;  
  54.      
  55.     gpio_set_value(SCL, 0);  
  56.     gpio_direction_output(SDA, 1);                
  57.     return rc;  
  58.  
  59. u8 i2c_send_byte(u8 send_byte)  
  60.  
  61.     u8 rc 0;  
  62.     u8 out_mask 0x80;  
  63.     u8 value;  
  64.     u8 count 8;  
  65.     while(count 0)                  
  66.         value ((send_byte out_mask) 0);     
  67.         if (value == 1)                                     
  68.             gpio_set_value(SDA, 1);       
  69.              
  70.         else                                    
  71.             gpio_set_value(SDA, 0);  
  72.              
  73.         udelay(DELAY);  
  74.                                     
  75.         gpio_set_value(SCL, 1);                       
  76.         udelay(DELAY);  
  77.                        
  78.         gpio_set_value(SCL, 0);       
  79.         udelay(DELAY);  
  80.                     
  81.         out_mask >>= 1;        
  82.         count--;         
  83.      
  84.       
  85.     gpio_set_value(SDA, 1);    
  86.     rc i2c_receive_ack();  
  87.     return rc;  
  88.  
  89. void i2c_read_byte(u8 *buffer, u8 ack)  
  90.  
  91.     u8 count 0x08;  
  92.     u8 data 0x00;  
  93.     u8 temp 0;  
  94.       
  95.     gpio_direction_input(SDA);   
  96.     while(count 0)  
  97.         gpio_set_value(SCL, 1);  
  98.         udelay(DELAY);  
  99.         temp gpio_get_value(SDA);       
  100.         data <<= 1;  
  101.         if (temp)  
  102.             data |= 0x01;  
  103.         gpio_set_value(SCL, 0);  
  104.         udelay(DELAY);  
  105.         count--;  
  106.      
  107.     i2c_send_ack(ack);//0 ACK    NACK   
  108.     *buffer data;           
  109.  
  110. //向client的某个寄存器写入多个字节,len是要写入的数据的长度   
  111. u8 i2c_write(u8 device_id, u8 reg_address, u8* data, u8 len)  
  112.  
  113.     u8 rc 0;  
  114.     u8 i;  
  115.     i2c_start();    
  116.       
  117.     rc |= i2c_send_byte( (device_id << 1) 0x00 );  
  118.     rc |= i2c_send_byte(reg_address);  
  119.     if(data==NULL ||0==len)  
  120.         i2c_stop();  
  121.         return rc;  
  122.      
  123.           
  124.     for(i=0; i<len; i++)  
  125.         rc |= i2c_send_byte(*data);  
  126.         data++;  
  127.      
  128.       
  129.     i2c_stop();       
  130.     if(rc)  
  131.         printk("ERROR!  ssd2531_i2c_write failed/n");  
  132.      
  133.     return rc;    
  134.  
  135. //从某个register中读取len个字节放在长度为len的缓冲区buffer中   
  136. u8 i2c_read(u8 device_id, u8 reg_address, u8 *buffer, u8 len)  
  137.  
  138.     u8 rc 0;  
  139.     u8 i;  
  140.       
  141.     i2c_start();    
  142.     rc |= i2c_send_byte( (device_id << 1) 0x00 );  
  143.     rc |= i2c_send_byte(reg_address);  
  144.     i2c_start();//restart I2C      
  145.     rc |= i2c_send_byte( (device_id << 1) 0x01 );  
  146.       
  147.     for(i=0;i<len;i++)  
  148.         i2c_read_byte(buffer++, !(len-i-1));//  !(len-i-1)  这个用来保证在读到每个字节后发送一个ACK并能在最后一个字节读完后发送一个NACK   
  149.      
  150.       
  151.     i2c_stop();   
  152.     if(rc)  
  153.         printk("ERROR!   ssd2531_i2c_read failed/n");  
  154.         return rc;  
  155.      
  156.     return rc;    
  157.  
  158.  

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多