給大家分享一個 stm8單片機用IIC總線方式讀寫24c02存儲芯片 里面是自己寫的程序
完整源碼下載:
4.I2C 24C02.rar
(396.59 KB, 下載次數: 85)
2017-3-15 09:05 上傳
點擊文件名下載附件
下面是部分文件預覽:
- #include"i2c.h"
- uint8_t receive[N],send[N]; //全局數組變量
- void I2C_Start() //發送起始信號——在SCL為高電平期間,SDA由高拉低
- {
- SDA_OUT;
- SDA_1;
- SCL_1;
- Delay_us(3);
- SDA_0;
- Delay_us(5);
- SCL_0;
- Delay_us(1);
- }
- void I2C_Stop() //結束信號——在SCL為高電平期間,SDA由低拉高
- {
- SDA_OUT;
- SDA_0;
- SCL_0;
- Delay_us(1);
- SCL_1;
- Delay_us(3);
- SDA_1;
- Delay_us(5);
- SCL_0;
- Delay_us(1);
- }
- void I2C_Ack() //檢測應答——第9個時鐘周期時,由24C16將SDA拉低
- {
- SDA_1;
- Delay_us(3);
- SDA_IN;
- Delay_us(1);
- SCL_1;
- Delay_us(2);
- SCL_0;
- Delay_us(3);
- }
- uint8_t I2C_Ack2() //檢測應答2
- {
- SDA_1;
- Delay_us(3);
- SDA_IN;
- Delay_us(2);
- SCL_1;
- Delay_us(2);
- // while(SDA); //很快能完成應答,不需要等待,防止硬件故障導致出錯
- SCL_0;
- Delay_us(2);
- return SDA;
- }
- uint8_t I2C_Send(uint8_t buffer) //發送1個字節的數據
- {
- uint8_t temp = 0;
- uint8_t BitCnt = 7;
-
- SDA_OUT; //SDA為輸出
- Delay_us(1);
- if((buffer&0x80)==0) //由高位開始發送
- SDA_0;
- else
- SDA_1;
- Delay_us(1);
- SCL_1;
- Delay_us(1);
- temp = buffer<<1;
- buffer = temp;
- while(BitCnt)
- {
- if((buffer&0x80)==0)
- {
- SCL_0;
- SDA_0;
- }
- else
- {
- SCL_0;
- SDA_1;
- }
- Delay_us(3);
- SCL_1;
- Delay_us(2);
- temp = buffer<<1;
- buffer = temp;
- BitCnt--;
- }
- SCL_0;
- if(I2C_Ack2()) //發送8位數據后,檢測應答 0:無應答 1:有應答
- return 0;
- else
- return 1;
- }
- uint8_t I2C_Receive() //接收一個字節的數據
- {
- uint8_t ReceiveData,i;
- SDA_IN; //SDA為輸入
- Delay_us(1);
- for(i=0;i<8;i++) //SCL高電平時,記錄SDA,由高位開始
- {
- SCL_1;
- Delay_us(2); //延時的時間
- if(SDA==0)
- ReceiveData &= 0xfe;
- else
- ReceiveData |= 0x01;
- if(i<7)
- ReceiveData = ReceiveData<<1;
-
- SCL_0;
- Delay_us(1);
- }
- return ReceiveData;
- }
- void I2C_NoAck() //接收數據后不發送應答
- {
- SDA_1;
- SDA_OUT;
- SDA_1;
- Delay_us(1);
- SCL_1;
- Delay_us(2);
- SCL_0;
- Delay_us(2);
- SDA_0;
- Delay_us(2);
- }
- void I2C_SendAck() //接收數據后發送應答,由主機發送,告知24C16已經接收到一個字節的數據
- {
- SDA_OUT;
- SDA_0;
- Delay_us(1);
- SCL_1;
- Delay_us(3);
- SCL_0;
- SDA_0;
- Delay_us(2);
- }
- void I2C_Write_Byte(uint8_t addr,uint8_t data) //向24C06寫入數據——單字節寫
- {
- I2C_Start(); //起始信號
- I2C_Send(0xa0); //發送器件地址
- I2C_Send(addr); //發送字節地址
- I2C_Send(data); //發送數據
- I2C_Stop(); //結束信號
- }
- void I2C_Write_Page(uint8_t addr,uint8_t data) //向24C06寫入數據——頁寫 16個字節
- {
- uint8_t i,j,k,p;
-
- if((N/16)==0) //判斷N是否小于16 是:一次頁寫即可完成 否:需要多次頁寫
- {
- I2C_Start(); //起始信號
- I2C_Send(0xa0); //發送器件地址
- I2C_Send(addr); //發送字節地址
- for(j=0;j<N;j++)
- {
- send[j] = data+j;
- I2C_Send(send[j]); //發送數據
- }
- I2C_Stop(); //結束信號
- Delay_ms(5);
- }
- else //多次頁寫
- {
- for(i=0;i<(N/16);i++) //i次頁寫
- {
- I2C_Start(); //起始信號
- I2C_Send(0xa0); //發送器件地址
- I2C_Send(addr+i*16); //發送字節地址
- for(j=0;j<16;j++)
- {
- send[i*16+j] = data+i*16+j;
- I2C_Send(send[i*16+j]); //發送數據
- }
- I2C_Stop(); //結束信號
- Delay_ms(5);
- }
-
- if(N%16) //寫剩余的數據
- {
- p=N-(N%16);
- I2C_Start(); //起始信號
- I2C_Send(0xa0); //發送器件地址
- I2C_Send(addr+p); //發送字節地址
- for(k=0;k<(N%16);k++)
- {
- send[i*16+k] = data+i*16+k;
- I2C_Send(send[i*16+k]); //發送數據
- }
- I2C_Stop(); //結束信號
- Delay_ms(5);
- }
- }
- }
- void I2C_Read2(uint8_t add_start)//連續讀
- {
- uint8_t i;
-
- I2C_Start(); //起始信號
- I2C_Send(0xa0); //發送器件地址——寫
- I2C_Send(add_start); //發送字節地址
- I2C_Start(); //起始信號
- I2C_Send(0xa1); //發送器件地址——讀
- for(i=0;i<N-1;i++)
- {
- receive[i]=I2C_Receive();
- I2C_SendAck(); //主機發送應答,繼續讀
- }
- receive[i]=I2C_Receive();
- I2C_NoAck(); //第九個周期發送不應答
- I2C_Stop(); //停止信號
- // return receive;
- }
-
- uint8_t I2C_Read(uint8_t addr) //從24C06讀出數據
- {
- uint8_t receive;
- I2C_Start(); //起始信號
- I2C_Send(0xa0); //發送器件地址——寫
- I2C_Send(addr); //發送字節地址
- I2C_Start(); //起始信號
- I2C_Send(0xa1); //發送器件地址——讀
- receive=I2C_Receive(); //讀出數據
- I2C_Stop(); //停止信號,結束讀數據操作
- return receive;
- }
- void I2C_Ack_Check() //應答查詢
- {
- I2C_Start();
- I2C_Send(0xa0);
- I2C_Ack2();
- }
- /*
- void test_1(uint8_t add,uint8_t data) //單次測試
- {
- uint8_t test=0;
- I2C_Write_Byte(add,data);
- Delay_ms(5);
- test = I2C_Read(add);
- if(test==data)
- LED = LED1;
- else
- LED = LED2;
- }
- void test_write(uint8_t add,uint8_t data) //測試_寫
- {
-
- I2C_Write_Byte(add,data);
- Delay_ms(5);
- }
- uint8_t test_read(uint8_t add) //測試_讀
- {
- uint8_t test=0;
- test = I2C_Read(add);
- return test;
- }
- void test1(uint8_t add_start) //測試函數1
- {
- uint8_t read[N]={0},write[N]={0},i,k=0;
-
- for(i=0;i<N;i++)
- {
- write[i]=0x02+i;
- test_write(add_start+i,write[i]);
- }
-
- for(i=0;i<N;i++)
- {
- read[i]=test_read(add_start+i);
- }
- for(i=0;i<N;i++)
- {
- if(write[i]==read[i])
- k+=1;
- }
- if(k==N)
- LED = LED1;
- else
- LED = LED2;
- }
- */
- void test2(uint8_t add_start,uint8_t data) //測試函數2
- {
- uint8_t i,k=0;
- I2C_Write_Page(add_start,data);
- I2C_Read2(add_start);
- for(i=0;i<N;i++)
- {
- if(receive[i]==send[i])
- k+=1;
- }
- if(k==N)
- LED = LED1;
- else
- LED = LED2;
- for(i=0;i<N;i++)
- {
- receive[i]=0;
- send[i]=0;
- }
-
- }
- #pragma vector=5 //PA口的中斷服務函數
- __interrupt void PORTA_IRQHandler(void)
- {
- Delay_ms(20); //軟件消抖
- if(!(PA_IDR&0x04))
- {
- Delay_ms(20);
- while(!(PA_IDR&0x04));
- test2(0x00,0x06);
- }
- }
復制代碼
|