日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

GPIO模拟I2C程序实现

發布時間:2025/4/16 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 GPIO模拟I2C程序实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
GPIO模擬I2C程序實現.

I2C是由Philips公司發明的一種串行數據通信協議,僅使用兩根信號線:SerialClock(簡稱SCL)和SerialData(簡稱SDA)。I2C是總線結構,1個Master,1個或多個Slave,各Slave設備以7位地址區分,地址后面再跟1位讀寫位,表示讀(=1)或者寫(=0),所以我們有時也可看到8位形式的設備地址,此時每個設備有讀、寫兩個地址,高7位地址其實是相同的。
I2C數據格式如下:
無數據:SCL=1,SDA=1;
開始位(Start):當SCL=1時,SDA由1向0跳變;
停止位(Stop):當SCL=1時,SDA由0向1跳變;
數據位:當SCL由0向1跳變時,由發送方控制SDA,此時SDA為有效數據,不可隨意改變SDA;
當SCL保持為0時,SDA上的數據可隨意改變;
地址位:定義同數據位,但只由Master發給Slave;
應答位(ACK):當發送方傳送完8位時,發送方釋放SDA,由接收方控制SDA,且SDA=0;
否應答位(NACK):當發送方傳送完8位時,發送方釋放SDA,由接收方控制SDA,且SDA=1。
當數據為單字節傳送時,格式為:
開始位,8位地址位(含1位讀寫位),應答,8位數據,應答,停止位。
當數據為一串字節傳送時,格式為:
開始位,8位地址位(含1位讀寫位),應答,8位數據,應答,8位數據,應答,……,8位數據,應答,停止位。
需要注意的是:
1,SCL一直由Master控制,SDA依照數據傳送的方向,讀數據時由Slave控制SDA,寫數據時由Master控制SDA。當8位數據傳送完畢之后,應答位或者否應答位的SDA控制權與數據位傳送時相反。
2,開始位“Start”和停止位“Stop”,只能由Master來發出。
3,地址的8位傳送完畢后,成功配置地址的Slave設備必須發送“ACK”。否則否則一定時間之后Master視為超時,將放棄數據傳送,發送“Stop”。
4,當寫數據的時候,Master每發送完8個數據位,Slave設備如果還有空間接受下一個字節應該回答“ACK”,Slave設備如果沒有空間接受更多的字節應該回答“NACK”,Master當收到“NACK”或者一定時間之后沒收到任何數據將視為超時,此時Master放棄數據傳送,發送“Stop”。
5,當讀數據的時候,Slave設備每發送完8個數據位,如果Master希望繼續讀下一個字節,Master應該回答“ACK”以提示Slave準備下一個數據,如果Master不希望讀取更多字節,Master應該回答“NACK”以提示Slave設備準備接收Stop信號。
6,當Master速度過快Slave端來不及處理時,Slave設備可以拉低SCL不放(SCL=0將發生“線與”)以阻止Master發送更多的數據。此時Master將視情況減慢或結束數據傳送。

7,I2C規程運用主/從雙向通訊。器件發送數據到總線上,則定義為發送器,器件接收據

定義為接收器。主器件和從器件都可以工作于接收和發送狀態。 總線必須由主器件(通常

為微控制器)控制,主器件產生串行時鐘(SCL)控制總線的傳輸方向,并產生起始和停止

條件。SDA線上的數據狀態僅在SCL為低電平的期間才能改變,SCL為高電平的期間,SDA

狀態的改變被用來表示起始和停止條件。

?


在實際應用中,并沒有強制規定數據接收方必須對于發送的8位數據做出回應,尤其是在Master和Slave端都是用GPIO軟件模擬的方法來實現的情況下,編程者可以事先約定數據傳送的長度,不發送ACK,有時可以起到減少系統開銷的效果。

源碼:

/********************************************************************/

void i2c_init(void)
{
PACNT_init;
PADDR_init;
PADAT_init;

SCL_high;
SDA_high;
}

/********************************************************************/

uint8 i2c_write(uint8 slave_address, uint8 *buffer, int byte_count, int freq)
{
????uint8 out_mask = 0x80;
????uint8 value = 0x00;
??uint8 send_byte = 0x00;
??uint8 status = 0x81;
??int count = 8;
??int clk_count = 0;
int i = 0;

/* Set delay value based on frequency. */
int D = (int) ((4000/freq) - 14);

slave_address = (slave_address & 0xFE);
?????????
??i2c_start();
??delay(500);
??
?? send_byte = slave_address;
????????
?? for(i = 0; i <= byte_count; i++)
?? {????
????count = 8;??
????out_mask = 0x80;
?????????
????/* Send data bytes one bit at a time. */???
????while(count > 0)
????{????????????
???? value = ((send_byte & out_mask) ? 1 : 0);
??????if (value == 1)
??????{
?????? PADAT_init;
????????SDA_high;}
??????else
??????{
?????? PADAT_init;
?????? SDA_low;}
???????
??????delay(D);?????
???????????????????
????????PADAT_init;
??????SCL_high;
??????
??????/* Clock stretching wait statement.??Wait until clock is released
??????by slave.??Only effects program on first iteration.??*/
?? while (((GPIO_PADAT & 0x0200) ? 1 : 0) == 0){;}

??????delay(2*D);??
???????
??????PADAT_init;
??????SCL_low;
??????delay(D);?
???????
??????out_mask >>= 1;?
??????count--;???
???? }
?????
???? PADAT_init;
???? SDA_high;??/* Let go of data pin. */
???? delay(D);?
??????
???? if (((GPIO_PADAT & 0x0400) ? 1 : 0) == 1)
???? {?
??????status = 0xA1; /* Transfer complete, bus busy, acknowledge not received. */
??????break; } /* If not acknowledged, exit loop. */
?????
????PADAT_init;
???? SCL_high;
???? delay(2*D);??
????
???? PADAT_init;
???? SCL_low;
???? status = 0xA0;??/* Transfer complete, bus busy, acknowledge received. */
???? delay(D);?
?????
???? send_byte = buffer[i];??????
????}
????
????PADAT_init;
????SDA_high;
????SCL_low;???
delay(100);
return(status);
}

/********************************************************************/

uint8 i2c_read(uint8 slave_address, uint8 *buffer, int byte_count, int freq)
{
uint8 input_byte = 0x00;
uint8 value = 0x00;
uint8 out_mask = 0x80;
uint8 status = 0x81;
int count = 8;
int clk_count = 0;
int i = 0;

/* Set delay value based on frequency. */
int D = (int) ((4000/freq) - 14);

slave_address = (slave_address | 0x01);
???
i2c_start();
delay(500);
???????????????
/**********??Write Address Procedure **********/
??
?? while(count > 0)
?? {
????value = ((slave_address & out_mask) ? 1 : 0);
???? if (value == 1)
???? {
??????PADAT_init;
?????? SDA_high;}
???? else
???? {
??????PADAT_init;
??????SDA_low;}
??????delay(D);??????
???????????????????
??????PADAT_init;
???? SCL_high;
??????
???? /* Clock stretching wait.??Wait until clock is released
???? by slave.??*/
???? while (((GPIO_PADAT & 0x0200) ? 1 : 0) == 0){;}

???? delay(2*D);?
???????
???? PADAT_init;
???? SCL_low;
???? delay(D);??
???????
???? out_mask >>= 1;?
???? count--;?????????
??}
?????
????PADAT_init;
??SDA_high;??/* Let go of data pin. */
????delay(D);
????SCL_high;
????delay(2*D);??
????
????/* If not acknowleged, set status accordingly and exit read process. */
????if (((GPIO_PADAT & 0x0400) ? 1 : 0) == 1)
????{
???? status = 0xA1;
???? return(status);}
????
????PADAT_init;
????SCL_low;
????delay(D);

/**********??Begin Read Procedure **********/

/* Release SDA and SCL to initiate transfer. */
PADAT_init;????
SDA_high;
SCL_high;

for(i = 0; i < byte_count; i++)
{
??count = 8;
??input_byte = 0x00;
???
??PADAT_init;
??SCL_high;
???
??/* Clock stretching wait.??Wait until clock is released
???? by slave.??*/
??while (((GPIO_PADAT & 0x0200) ? 1 : 0) == 0){;}
???????????
??/* Loop for bit-by-bit read of data. */
??while(count > 0)?
??{
????PADAT_init;
????SCL_high;
????delay(D);??
????delay(4); /* Required to make read and write clocks the same freq. */
????
?? if ((GPIO_PADAT & 0x0600) == 0x0600)
????input_byte++;
??
?? delay(D);??
???
?? PADAT_init;
?? SCL_low;
?? delay(2*D);?
??????
?? if (count == 1)
????break;
?? else??
????input_byte <<= 1;
??
?? count--;
??}

??/* Write input byte to "read_buffer". */
??buffer[i] = input_byte;
????
??if(i == (byte_count - 1))
?? break;
?????
???? /* Below is the acknowledge procedure. */?????
???? PADAT_init;
???? SDA_low;
???? delay(D);??
???? SCL_high;?????
??delay(2*D);??
????
???? PADAT_init;
???? SCL_low;
???? delay(D);??
???? SDA_high;?
???? status = 0xA0;?
}?????

/* Standard protocol calls for the last read byte to
????not receive an acknowledge from the master. */?????
PADAT_init;
????SDA_high;
????SCL_high;?????
delay(2*D);?
?????
?? PADAT_init;
?? SCL_low;
?? delay(D);??
?? SDA_high;
?? status = 0xA1;
?? return(status);
}

/********************************************************************/

void i2c_start(void)
{
int clk_count = 0;
uint8 compare = 0x00;

PADAT_init;??
SDA_high;
delay(100);

PADAT_init;??
SCL_high;
delay(100);

/* Clock stretching wait.??Wait until clock is released
????by slave.??*/
while (((GPIO_PADAT & 0x0200) ? 1 : 0) == 0){;}????
??
PADAT_init;
SDA_low;
delay(100);
?????
????PADAT_init;??
SCL_low;
delay(100);
}

/********************************************************************/

uint8 i2c_stop(void)
{
uint8 status = 0x00;
int clk_count = 0;
??
PADAT_init;
SCL_low;
delay(100);

PADAT_init;
SDA_low;
delay(100);
????
????PADAT_init;?
SCL_high;

/* Clock stretching wait statement.??Wait until clock is released
????by slave.??*/
while (((GPIO_PADAT & 0x0200) ? 1 : 0) == 0){;}
??????
delay(100);
????
????PADAT_init;?
SDA_high;
status = 0x81; /* Set bus idle. */
return(status);
}

/********************************************************************/

void delay(int value)
{
int clk_count = 0;
while (clk_count < value)
{clk_count++;}
}

/********************************************************************/

?

第二個例子

函數定義:

gpio_iic.h:

#ifndef __IIC_GPIO__
#define __IIC_GPIO__
void delay();
/*
設置scl引腳電平,0低電平,1高電平,其他值無效,返回值一直為0,留著它用。
*/
int set_scl( int value );

/*
得到scl引腳電平,0低電平,1高電平,必須是這兩個值,其他函數需要調用。
*/
int get_scl();

/*
設置sda引腳電平,0低電平,1高電平,其他值無效,返回值一直為0,留著它用。
*/
int set_sda( int value );

/*
得到sda引腳電平,0低電平,1高電平,必須是這兩個值,其他函數需要調用。
*/
int get_sda();


/*
重新發送iic start位,這個是在傳送數據過程中使用。
*/
void iic_restart();

/*
發送iic start位,這里假設總線空閑,此時SDL與SCL都為高電平。
*/
void iic_start();

/*
發送stop位,這里假設scl此時為低電平。
*/
void iic_stop();

/*
發送一個bit0,這里假設scl此時為低電平,sda電平不定。
*/
void send_bit0();

/*
發送一個bit 1,這里假設scl此時為低電平,sda電平不定。
?*/
void send_bit1();

/*
接收一個bit位,返回值只能是0或1。
?*/
int receive_bit();

/*
發送ACK,實際上是發送一個bit0.
*/
void send_ack();

/*
接收ACK。
*/
int receive_ack();

/*
接收一個字節。
*/
char receive_byte();

/*
接收一個buf,返回值總是為0,它不能保證從器件一定能收到ACK,也不能保證從器件正在工作。
*/
int receive_buf( char *buf, int buf_size );

/*
發送一個字節,返回ACK的值,發送時,沒有收到ACK會重試n次,這是常。
?*/
int send_byte( char data_byte );

/*
發送一個buf,返回值是成功發送,收到ACK的字節數量。
*/
int send_buf( char *buf, int buf_size );

#endif


gpio_iic.c:

#include "gpio_iic.h"
//#define __80C52__
#define __MINI2440__
#ifdef __MINI2440__
#include <linux/gpio.h>
#include <linux/delay.h>
#include <mach/regs-gpio.h>
#endif

#ifdef __80C52__
#include <reg52.h>
sbit SCL? = P1^0;
sbit SDA??? = P1^1;
#endif


void delay()
{
#ifdef __MINI2440__
???? udelay(1);
#endif
#ifdef __80C52__
???? int i = 0;
???? for( i = 0; i < 10000; i ++ );
#endif
}
/*
設置scl引腳電平,0低電平,1高電平,其他值無效,返回值一直為0,留著它用。
*/
int set_scl( int value )
{

#ifdef __MINI2440__
//??? s3c2410_gpio_cfgpin(S3C2410_GPE(15), S3C2410_GPE15_IICSDA);
//???? s3c2410_gpio_cfgpin(S3C2410_GPE(14), S3C2410_GPE14_IICSCL);
???? s3c2410_gpio_cfgpin(S3C2410_GPE(14), S3C2410_GPIO_OUTPUT);
???? switch( value )
???? {
???? case 0:
????? s3c2410_gpio_setpin(S3C2410_GPE(14), 0); // IICSCL
????? break;
???? case 1:
????? s3c2410_gpio_setpin(S3C2410_GPE(14), 1); // IICSCL
????? break;
???? default:
????? break;
???? }
#endif

#ifdef __80C52__
???? if ( 0 == value )
????? SCL = 0;
???? else if ( 1 == value )
????? SCL = 1;
#endif
???? return 0;??????????????????
}


/*
得到scl引腳電平,0低電平,1高電平,必須是這兩個值,其他函數需要調用。
*/
int get_scl()
{
#ifdef __MINI2440__
???? s3c2410_gpio_cfgpin(S3C2410_GPE(14), S3C2410_GPIO_INPUT);
???? return s3c2410_gpio_getpin(S3C2410_GPE(14)) > 0 ? 1: 0;
#endif

#ifdef __80C52__
???? return SCL;
#endif
}

?

/*
設置sda引腳電平,0低電平,1高電平,其他值無效,返回值一直為0,留著它用。
*/
int set_sda( int value )
{
#ifdef __MINI2440__
???? s3c2410_gpio_cfgpin(S3C2410_GPE(15), S3C2410_GPIO_OUTPUT);
???? switch( value )
???? {
???? case 0:
????? s3c2410_gpio_setpin(S3C2410_GPE(15), 0); // IICSDA
????? break;
???? case 1:
????? s3c2410_gpio_setpin(S3C2410_GPE(15), 1); // IICSDA
????? break;
???? default:
????? break;
???? }
#endif
#ifdef __80C52__
???? if ( 0 == value )
????? SDA = 0;
???? else if ( 1 == value )
????? SDA = 1;????
#endif????????
???? return 0;
}

?

/*
得到sda引腳電平,0低電平,1高電平,必須是這兩個值,其他函數需要調用。
*/
int get_sda()
{
#ifdef __MINI2440__
???? int sda_pin = 0;
???? s3c2410_gpio_cfgpin(S3C2410_GPE(15), S3C2410_GPIO_INPUT);
???? sda_pin = s3c2410_gpio_getpin(S3C2410_GPE(15)) > 0 ? 1:0;
???? return sda_pin;
#endif
#ifdef __80C52__
???? return SDA;
#endif
}


/*
重新發送iic start位,這個是在傳送數據過程中使用。
*/
void iic_restart()
{
???? set_scl( 0 );
???? delay();
???? set_sda( 1 );
???? delay();
???? set_scl( 1 );
???? delay();
???? set_sda( 0 );
???? delay();
???? set_scl( 0 );
???? delay();
}


/*
發送iic start位,這里假設總線空閑,此時SDL與SCL都為高電平。
*/
void iic_start()
{
???? set_sda( 0 );
???? delay();
???? set_scl( 0 );
???? delay();
}

/*
發送stop位,這里假設scl此時為低電平。
*/
void iic_stop()
{
???? set_sda( 0 );
???? delay();
???? set_scl( 1 );
???? delay();
???? set_sda( 1 );????????
???? delay();
}


/*
發送一個bit0,這里假設scl此時為低電平,sda電平不定。
*/
void send_bit0()
{
???? set_sda( 0 );
???? delay();
???? set_scl( 1 );
???? delay();
???? set_scl( 0 );
???? delay();
}

/*
發送一個bit 1,這里假設scl此時為低電平,sda電平不定。
?*/
void send_bit1()
{
???? set_sda( 1 );
???? delay();
???? set_scl( 1 );
???? delay();
???? set_scl( 0 );
???? delay();
}

/*
接收一個bit位,返回值只能是0或1。
?*/
int receive_bit()
{
???? int value = -1;

???? set_sda( 1 );
???? delay();
???? set_scl( 0 );
???? delay();
???? set_scl( 1 );
???? delay();
???? value = get_sda();
???? set_scl( 0 );
???? return value;????
}

/*
發送ACK,實際上是發送一個bit0.
*/
void send_ack( )
{
???? send_bit0();
}

/*
接收ACK。
*/
int receive_ack()
{
???? int ack = 1;
???? set_sda( 1 );
???? delay();
???? set_scl( 1 );
???? delay();
???? ack = get_sda();????????
???? delay();
???? set_scl( 0 );
???? return ack;
}

/*
接收一個字節。
*/
char receive_byte( )
{
???? int i = 0;
???? int recv_data = 0;
???? for ( i = 0; i < 8; i++ )
???? {
????? recv_data = recv_data | receive_bit();
????? if ( 7 == i )
?????????? break;
????? recv_data <<= 1;
???? }
???? send_ack();
???? return recv_data;????
}

/*
接收一個buf,返回值總是為0,它不能保證從器件一定能收到ACK,也不能保證從器件正在工作。
*/
int receive_buf( char *buf, int buf_size )
{
???? int i = 0;
???? for( i = 0; i < buf_size; i ++ )
???? {
????? buf[i] = receive_byte();
???? }
???? return buf_size;
}

/*
發送一個字節,返回ACK的值,發送時,沒有收到ACK會重試n次,這是常。
?*/
int send_byte( char data_byte )
{
???? int retry_count = 8;//重試次數。
???? int i = 0;
???? int ack = 1;????????
???? char send_data = 0;
???? send_data = data_byte;
???? do{
????? for ( i = 0; i < 8; i ++ )
????? {
?????????? if ( 0x80 & send_data )
??????????? send_bit1();
?????????? else
??????????? send_bit0();
?????????? send_data <<= 1;
????? }
????? ack = receive_ack();
????? if ( 0 == ack )
?????????? break;
????? send_data = data_byte;
????? retry_count --;
???? }
???? while( retry_count >= 0 );
???? return ack;
}

/*
發送一個buf,返回值是成功發送,收到ACK的字節數量。
*/
int send_buf( char *buf, int buf_size )
{
???? int i = 0;
???? int count = 0;
???? for ( i = 0; i < buf_size; i ++ )
???? {
????? if (0 != send_byte( buf[i] ) )
?????????? break;
????? count ++;
???? }
???? return count;????????
}

?

下面是可以用來讀寫at24c02的測試代碼,在mini2440板測試通過,

static void m24c02_send( int addr, char *buf,? int buf_size)
{
???? int count = 0;
???? int rev = -1;
??? iic_start();
??? rev = send_byte( 0xa0 );
??? rev = send_byte( (addr >> 0) & 0xff );
??? count = send_buf( buf, buf_size );
??? iic_stop();
?
}

static void m24c02_recv( int addr , char *buf, int buf_size )
{
????? iic_start();
??? send_byte( 0xa0 );
??? send_byte( (addr >> 0) & 0xff );
????? iic_restart();
??? send_byte( 0xa1 );
??? receive_buf( buf, buf_size );
??? iic_stop();
}?

?

?

(1)基礎宏定義
#define GPIO_SCL???????????? S3C2410_GPF3 #define GPIO_SDA???????????? S3C2410_GPF0 #define GPIO_SDA_OUTP?? S3C2410_GPF0_OUTP? //設定SDA輸出 #define GPIO_SDA_INP????? S3C2410_GPF0_INP???? //設定SDA輸入 #define GPIO_SCL_OUTP?? S3C2410_GPF3_OUTP? //設定SCL輸出
void I2C_SCL_OUTP( void ) { s3c2410_gpio_cfgpin(GPIO_SCL,GPIO_SCL_OUTP); }
void I2C_SCL_Output(u8 value) { if(value) {??????????????????????????????????????????????? s3c2410_gpio_setpin(GPIO_SCL,value);? } else { s3c2410_gpio_setpin(GPIO_SCL,value );? } }
void I2C_SDA_Mode(u8 v_mode)?? //SDA輸出方向 { if(v_mode) {??????????????????????????????????????????????? s3c2410_gpio_cfgpin(GPIO_SDA, GPIO_SDA_OUTP);?? } else { s3c2410_gpio_cfgpin(GPIO_SDA, GPIO_SDA_INP);?? } }
void I2C_SDA_Output(u8 value) { if(value) {??????????????????????????????????????????????? s3c2410_gpio_setpin(GPIO_SDA,value);? } else { s3c2410_gpio_setpin(GPIO_SDA,value );? } }
u8 I2C_SDA_Read(void)??? //SDA讀數據 { return s3c2410_gpio_getpin(GPIO_SDA);? }
(2)基礎段
void I2C_Init(void) { I2C_SDA_Output(1); I2C_SCL_Output(1);????? //默認拉高 }
void I2C_Wait(void) { u16 i; for(i=0;i<200;i++); }
void I2C_Start(void) { I2C_SDA_Output(1); I2C_SCL_Output(1); I2C_Wait(); I2C_SDA_Output(0); I2C_Wait(); I2C_SCL_Output(0); } void I2C_Stop(void) { I2C_SDA_Output(0); I2C_Wait(); I2C_SCL_Output(1); I2C_Wait(); I2C_SDA_Output(1); }

? (3)讀寫單個字節的段
u8 I2C_Send_Byte(u8 bytedata) { u8 i,ack; I2C_SDA_Mode(1);? //SDA輸出 I2C_SCL_OUTP();
for (i = 0; i < 8; i++)? { if (bytedata & 0x80) { I2C_SDA_Output(1); } else { I2C_SDA_Output(0); } bytedata <<= 1; I2C_SCL_Output(1); udelay(3); I2C_SCL_Output(0); udelay(1); }???? I2C_SDA_Output(1);? //release udelay(3); I2C_SDA_Mode(0);? //設定SDA輸入 I2C_SCL_Output(1);?? udelay(3); ack = I2C_SDA_Read();?? //讀應答 I2C_SDA_Mode(1); I2C_SCL_Output(0); udelay(3); return ack;?? }
u8 I2C_Receive_Byte(void)? { u8 i; u8 bytedata = 0x00; u8 temp; I2C_SDA_Mode(0); for ( i = 0; i < 8; i++) { I2C_SCL_Output(1); udelay(3);
bytedata <<= 1; temp = I2C_SDA_Read(); printk("reda SDA'value is:%d\n",temp); if (temp) bytedata |= 0x01; printk("? bytedata is:%x\n",bytedata); I2C_SCL_Output(0); udelay(1); } I2C_SDA_Mode(1); return bytedata; }
(4)讀寫單個字節的I2C應用函數
u8 I2C_Byte_Write(u8 device_ID,u8 address,u8 bytedata) {?? u8 ack; printk("device_ID is:%x\n",device_ID); printk("address is:%x\n",address); printk("date is:%x\n",bytedata); I2C_Start();? ack=I2C_Send_Byte(device_ID); printk("ack is:%d\n",ack); if(ack)
I2C_Stop(); I2C_Send_Byte(address); I2C_Send_Byte(bytedata); I2C_Stop(); I2C_Wait(); return 0; }
u8 I2C_Byte_Read(u8 device_ID,u8 address) {?? u8 bytedata;
I2C_Start(); I2C_Send_Byte(device_ID); I2C_Send_Byte(address); I2C_Start(); I2C_Send_Byte(device_ID+1); bytedata = I2C_Receive_Byte();? //讀單個字節,不需要再發應答 I2C_Stop();??? return bytedata; }

總結

以上是生活随笔為你收集整理的GPIO模拟I2C程序实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。