生活随笔
收集整理的這篇文章主要介紹了
GPIO模拟I2C
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
原來新的kernel中已經提供了一種通過兩個gpio口調用i2c-core的機制,而且還能在這兩個gpio口掛載多個設備,用起來就像真的i2c總線一樣。所以以后我們都應該用kernel中的這種機制!畢竟自己寫的模擬代碼不是很可靠的,而且不方便掛載多個設備(當然,你可以通過復雜的邏輯和方法去實現,但是這不值得,除非你是本著學習的目的)
不過這個自己寫的gpio模擬i2c的代碼通過對gpio的不停的拉高拉低來模擬scl和sda線的動作可以讓我們對i2c的操作和協議認識的更清楚。
代碼如下:?
[cpp]?view plaincopy
??? #define?DELAY???1??? #define?SCL?????89??? #define?SDA?????20??? #define?RST?????19??? #define?IRQ?????108??? void?i2c_start(void)?? {??????? ????gpio_direction_output(SDA,?1);???? ????gpio_direction_output(SCL,?1);?? ????udelay(DELAY);?? ?????? ????gpio_set_value(SDA,?0);?? ????udelay(DELAY);?????? ???????????? ????gpio_set_value(SCL,?0);?? ????udelay(DELAY);?? }?? void?i2c_stop(void)?? {??? ????gpio_set_value(SCL,?0);?? ????gpio_set_value(SDA,?0);?? ????udelay(DELAY);?? ?????? ????gpio_set_value(SCL,?1);?? ????udelay(DELAY);?? ????gpio_set_value(SDA,?1);?? ????udelay(DELAY);?? }?? void?i2c_send_ack(u8?ack)?? {?? ????if(ack)?? ????????gpio_direction_output(SDA,?1);??? ????else??? ????????gpio_direction_output(SDA,?0);?? ????udelay(DELAY);?? ?????? ????gpio_set_value(SCL,?1);?? ????udelay(DELAY);?? ?????? ????gpio_set_value(SCL,?0);?? ????udelay(DELAY);???? }?? u8?i2c_receive_ack(void)?? {?? ????u8?rc?=?0;?? ?????? ????gpio_direction_input(SDA);?? ????gpio_set_value(SCL,?1);?? ????udelay(DELAY);?? ?????? ????if(gpio_get_value(SDA))?{?? ????????rc?=?1;?? ????}?? ????gpio_set_value(SCL,?0);?? ????gpio_direction_output(SDA,?1);???????????????? ????return?rc;?? }?? u8?i2c_send_byte(u8?send_byte)?? {?? ????u8?rc?=?0;?? ????u8?out_mask?=?0x80;?? ????u8?value;?? ????u8?count?=?8;?? ????while(count?>?0)?{?????????????????? ????????value?=?((send_byte?&?out_mask)???1?:?0);????? ????????if?(value?==?1)?{????????????????????????????????????? ????????????gpio_set_value(SDA,?1);??????? ????????}?????? ????????else?{???????????????????????????????????? ????????????gpio_set_value(SDA,?0);?? ????????}?????? ????????udelay(DELAY);?? ???????????????????????????????????? ????????gpio_set_value(SCL,?1);??????????????????????? ????????udelay(DELAY);?? ??????????????????????? ????????gpio_set_value(SCL,?0);??????? ????????udelay(DELAY);?? ???????????????????? ????????out_mask?>>=?1;???????? ????????count--;????????? ????}?? ?????? ????gpio_set_value(SDA,?1);???? ????rc?=?i2c_receive_ack();?? ????return?rc;?? }?? void?i2c_read_byte(u8?*buffer,?u8?ack)?? {?? ????u8?count?=?0x08;?? ????u8?data?=?0x00;?? ????u8?temp?=?0;?? ?????? ????gpio_direction_input(SDA);??? ????while(count?>?0)?{?? ????????gpio_set_value(SCL,?1);?? ????????udelay(DELAY);?? ????????temp?=?gpio_get_value(SDA);??????? ????????data?<<=?1;?? ????????if?(temp)?? ????????????data?|=?0x01;?? ????????gpio_set_value(SCL,?0);?? ????????udelay(DELAY);?? ????????count--;?? ????}?? ????i2c_send_ack(ack);?? ????*buffer?=?data;??????????? }?? ?? u8?i2c_write(u8?device_id,?u8?reg_address,?u8*?data,?u8?len)?? {?? ????u8?rc?=?0;?? ????u8?i;?? ????i2c_start();???? ?????? ????rc?|=?i2c_send_byte(?(device_id?<<?1)?|?0x00?);?? ????rc?|=?i2c_send_byte(reg_address);?? ????if(data==NULL?||0==len)?{?? ????????i2c_stop();?? ????????return?rc;?? ????}?? ?????????? ????for(i=0;?i<len;?i++)?{?? ????????rc?|=?i2c_send_byte(*data);?? ????????data++;?? ????}?? ?????? ????i2c_stop();??????? ????if(rc)?{?? ????????printk("ERROR!??ssd2531_i2c_write?failed/n");?? ????}?? ????return?rc;???? }?? ?? u8?i2c_read(u8?device_id,?u8?reg_address,?u8?*buffer,?u8?len)?? {?? ????u8?rc?=?0;?? ????u8?i;?? ?????? ????i2c_start();???? ????rc?|=?i2c_send_byte(?(device_id?<<?1)?|?0x00?);?? ????rc?|=?i2c_send_byte(reg_address);?? ????i2c_start();?? ????rc?|=?i2c_send_byte(?(device_id?<<?1)?|?0x01?);?? ?????? ????for(i=0;i<len;i++)?{?? ????????i2c_read_byte(buffer++,?!(len-i-1));?? ????}?? ?????? ????i2c_stop();??? ????if(rc)?{?? ????????printk("ERROR!???ssd2531_i2c_read?failed/n");?? ????????return?rc;?? ????}?? ????return?rc;???? }?? ??
[cpp]?view plaincopy
??? #define?DELAY???1?? #define?SCL?????89?? #define?SDA?????20?? #define?RST?????19?? #define?IRQ?????108?? void?i2c_start(void)?? {??????? ????gpio_direction_output(SDA,?1);???? ????gpio_direction_output(SCL,?1);?? ????udelay(DELAY);?? ?????? ????gpio_set_value(SDA,?0);?? ????udelay(DELAY);?????? ???????????? ????gpio_set_value(SCL,?0);?? ????udelay(DELAY);?? }?? void?i2c_stop(void)?? {??? ????gpio_set_value(SCL,?0);?? ????gpio_set_value(SDA,?0);?? ????udelay(DELAY);?? ?????? ????gpio_set_value(SCL,?1);?? ????udelay(DELAY);?? ????gpio_set_value(SDA,?1);?? ????udelay(DELAY);?? }?? void?i2c_send_ack(u8?ack)?? {?? ????if(ack)?? ????????gpio_direction_output(SDA,?1);??? ????else??? ????????gpio_direction_output(SDA,?0);?? ????udelay(DELAY);?? ?????? ????gpio_set_value(SCL,?1);?? ????udelay(DELAY);?? ?????? ????gpio_set_value(SCL,?0);?? ????udelay(DELAY);???? }?? u8?i2c_receive_ack(void)?? {?? ????u8?rc?=?0;?? ?????? ????gpio_direction_input(SDA);?? ????gpio_set_value(SCL,?1);?? ????udelay(DELAY);?? ?????? ????if(gpio_get_value(SDA))?{?? ????????rc?=?1;?? ????}?? ????gpio_set_value(SCL,?0);?? ????gpio_direction_output(SDA,?1);???????????????? ????return?rc;?? }?? u8?i2c_send_byte(u8?send_byte)?? {?? ????u8?rc?=?0;?? ????u8?out_mask?=?0x80;?? ????u8?value;?? ????u8?count?=?8;?? ????while(count?>?0)?{?????????????????? ????????value?=?((send_byte?&?out_mask)???1?:?0);????? ????????if?(value?==?1)?{????????????????????????????????????? ????????????gpio_set_value(SDA,?1);??????? ????????}?????? ????????else?{???????????????????????????????????? ????????????gpio_set_value(SDA,?0);?? ????????}?????? ????????udelay(DELAY);?? ???????????????????????????????????? ????????gpio_set_value(SCL,?1);??????????????????????? ????????udelay(DELAY);?? ??????????????????????? ????????gpio_set_value(SCL,?0);??????? ????????udelay(DELAY);?? ???????????????????? ????????out_mask?>>=?1;???????? ????????count--;????????? ????}?? ?????? ????gpio_set_value(SDA,?1);???? ????rc?=?i2c_receive_ack();?? ????return?rc;?? }?? void?i2c_read_byte(u8?*buffer,?u8?ack)?? {?? ????u8?count?=?0x08;?? ????u8?data?=?0x00;?? ????u8?temp?=?0;?? ?????? ????gpio_direction_input(SDA);??? ????while(count?>?0)?{?? ????????gpio_set_value(SCL,?1);?? ????????udelay(DELAY);?? ????????temp?=?gpio_get_value(SDA);??????? ????????data?<<=?1;?? ????????if?(temp)?? ????????????data?|=?0x01;?? ????????gpio_set_value(SCL,?0);?? ????????udelay(DELAY);?? ????????count--;?? ????}?? ????i2c_send_ack(ack);?? ????*buffer?=?data;??????????? }?? ?? u8?i2c_write(u8?device_id,?u8?reg_address,?u8*?data,?u8?len)?? {?? ????u8?rc?=?0;?? ????u8?i;?? ????i2c_start();???? ?????? ????rc?|=?i2c_send_byte(?(device_id?<<?1)?|?0x00?);?? ????rc?|=?i2c_send_byte(reg_address);?? ????if(data==NULL?||0==len)?{?? ????????i2c_stop();?? ????????return?rc;?? ????}?? ?????????? ????for(i=0;?i<len;?i++)?{?? ????????rc?|=?i2c_send_byte(*data);?? ????????data++;?? ????}?? ?????? ????i2c_stop();??????? ????if(rc)?{?? ????????printk("ERROR!??ssd2531_i2c_write?failed/n");?? ????}?? ????return?rc;???? }?? ?? u8?i2c_read(u8?device_id,?u8?reg_address,?u8?*buffer,?u8?len)?? {?? ????u8?rc?=?0;?? ????u8?i;?? ?????? ????i2c_start();???? ????rc?|=?i2c_send_byte(?(device_id?<<?1)?|?0x00?);?? ????rc?|=?i2c_send_byte(reg_address);?? ????i2c_start();?? ????rc?|=?i2c_send_byte(?(device_id?<<?1)?|?0x01?);?? ?????? ????for(i=0;i<len;i++)?{?? ????????i2c_read_byte(buffer++,?!(len-i-1));?? ????}?? ?????? ????i2c_stop();??? ????if(rc)?{?? ????????printk("ERROR!???ssd2531_i2c_read?failed/n");?? ????????return?rc;?? ????}?? ????return?rc;???? }?? ??
總結
以上是生活随笔為你收集整理的GPIO模拟I2C的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。