EEPROM 24c02 [I2C代碼封裝-保存實(shí)現(xiàn)流水燈]
這里把EEPROM 24c02封裝起來,今后可以直接調(diào)用,其連線方式為:SDA-P2.1;SCL-P2.0;WP-VCC
>_<:i2c.c
1 /*-----------------------------------------------
2 名稱:IIC協(xié)議
3 內(nèi)容:函數(shù)是采用軟件延時(shí)的方法產(chǎn)生SCL脈沖,固對高晶振頻率要作 一定的修改....(本例是1us機(jī)器
4 周期,即晶振頻率要小于12MHZ)
5 ------------------------------------------------*/
6 #include "i2c.h"
7 #define _Nop() _nop_() //定義空指令
8 bit ack; //應(yīng)答標(biāo)志位
9 sbit SDA=P2^1;
10 sbit SCL=P2^0;
11 /*------------------------------------------------
12 uS延時(shí)函數(shù),含有輸入?yún)?shù) unsigned char t,無返回值
13 unsigned char 是定義無符號字符變量,其值的范圍是
14 0~255 這里使用晶振12M,精確延時(shí)請使用匯編,大致延時(shí)
15 長度如下 T=tx2+5 uS
16 ------------------------------------------------*/
17 void DelayUs2x(unsigned char t)
18 {
19 while(--t);
20 }
21 /*------------------------------------------------
22 mS延時(shí)函數(shù),含有輸入?yún)?shù) unsigned char t,無返回值
23 unsigned char 是定義無符號字符變量,其值的范圍是
24 0~255 這里使用晶振12M,精確延時(shí)請使用匯編
25 ------------------------------------------------*/
26 void DelayMs(unsigned char t)
27 {
28 while(t--)
29 {
30 //大致延時(shí)1mS
31 DelayUs2x(245);
32 DelayUs2x(245);
33 }
34 }
35 /*------------------------------------------------
36 啟動(dòng)總線
37 ------------------------------------------------*/
38 void Start_I2c()
39 {
40 SDA=1; //發(fā)送起始條件的數(shù)據(jù)信號
41 _Nop();
42 SCL=1;
43 _Nop(); //起始條件建立時(shí)間大于4.7us,延時(shí)
44 _Nop();
45 _Nop();
46 _Nop();
47 _Nop();
48 SDA=0; //發(fā)送起始信號
49 _Nop(); //起始條件鎖定時(shí)間大于4μ
50 _Nop();
51 _Nop();
52 _Nop();
53 _Nop();
54 SCL=0; //鉗住I2C總線,準(zhǔn)備發(fā)送或接收數(shù)據(jù)
55 _Nop();
56 _Nop();
57 }
58 /*------------------------------------------------
59 結(jié)束總線
60 ------------------------------------------------*/
61 void Stop_I2c()
62 {
63 SDA=0; //發(fā)送結(jié)束條件的數(shù)據(jù)信號
64 _Nop(); //發(fā)送結(jié)束條件的時(shí)鐘信號
65 SCL=1; //結(jié)束條件建立時(shí)間大于4μ
66 _Nop();
67 _Nop();
68 _Nop();
69 _Nop();
70 _Nop();
71 SDA=1; //發(fā)送I2C總線結(jié)束信號
72 _Nop();
73 _Nop();
74 _Nop();
75 _Nop();
76 }
77 /*----------------------------------------------------------------
78 字節(jié)數(shù)據(jù)傳送函數(shù)
79 函數(shù)原型: void SendByte(unsigned char c);
80 功能: 將數(shù)據(jù)c發(fā)送出去,可以是地址,也可以是數(shù)據(jù),發(fā)完后等待應(yīng)答,并對
81 此狀態(tài)位進(jìn)行操作.(不應(yīng)答或非應(yīng)答都使ack=0 假)
82 發(fā)送數(shù)據(jù)正常,ack=1; ack=0表示被控器無應(yīng)答或損壞。
83 ------------------------------------------------------------------*/
84 void SendByte(unsigned char c)
85 {
86 unsigned char BitCnt;
87 for(BitCnt=0;BitCnt<8;BitCnt++) //要傳送的數(shù)據(jù)長度為8位
88 {
89 if((c< 90 else SDA=0; 91 _Nop(); 92 SCL=1; //置時(shí)鐘線為高,通知被控器開始接收數(shù)據(jù)位 93 _Nop(); 94 _Nop(); //保證時(shí)鐘高電平周期大于4μ 95 _Nop(); 96 _Nop(); 97 _Nop(); 98 SCL=0; 99 } 100 _Nop(); 101 _Nop(); 102 SDA=1; //8位發(fā)送完后釋放數(shù)據(jù)線,準(zhǔn)備接收應(yīng)答位 103 _Nop(); 104 _Nop(); 105 SCL=1; 106 _Nop(); 107 _Nop(); 108 _Nop(); 109 if(SDA==1)ack=0; 110 else ack=1; //判斷是否接收到應(yīng)答信號 111 SCL=0; 112 _Nop(); 113 _Nop(); 114 } 115 /*---------------------------------------------------------------- 116 字節(jié)數(shù)據(jù)傳送函數(shù) 117 函數(shù)原型: unsigned char RcvByte(); 118 功能: 用來接收從器件傳來的數(shù)據(jù),并判斷總線錯(cuò)誤(不發(fā)應(yīng)答信號), 119 發(fā)完后請用應(yīng)答函數(shù)。 120 ------------------------------------------------------------------*/ 121 unsigned char RcvByte() 122 { 123 unsigned char retc; 124 unsigned char BitCnt; 125 126 retc=0; 127 SDA=1; //置數(shù)據(jù)線為輸入方式 128 for(BitCnt=0;BitCnt<8;BitCnt++) 129 { 130 _Nop(); 131 SCL=0; //置時(shí)鐘線為低,準(zhǔn)備接收數(shù)據(jù)位 132 _Nop(); 133 _Nop(); //時(shí)鐘低電平周期大于4.7us 134 _Nop(); 135 _Nop(); 136 _Nop(); 137 SCL=1; //置時(shí)鐘線為高使數(shù)據(jù)線上數(shù)據(jù)有效 138 _Nop(); 139 _Nop(); 140 retc=retc<<1; 141 if(SDA==1)retc=retc+1; //讀數(shù)據(jù)位,接收的數(shù)據(jù)位放入retc中 142 _Nop(); 143 _Nop(); 144 } 145 SCL=0; 146 _Nop(); 147 _Nop(); 148 return(retc); 149 } 150 /*---------------------------------------------------------------- 151 應(yīng)答子函數(shù) 152 原型: void Ack_I2c(void); 153 ----------------------------------------------------------------*/ 154 void Ack_I2c(void) 155 { 156 SDA=0; 157 _Nop(); 158 _Nop(); 159 _Nop(); 160 SCL=1; 161 _Nop(); 162 _Nop(); //時(shí)鐘低電平周期大于4μ 163 _Nop(); 164 _Nop(); 165 _Nop(); 166 SCL=0; //清時(shí)鐘線,鉗住I2C總線以便繼續(xù)接收 167 _Nop(); 168 _Nop(); 169 } 170 /*---------------------------------------------------------------- 171 非應(yīng)答子函數(shù) 172 原型: void NoAck_I2c(void); 173 ----------------------------------------------------------------*/ 174 void NoAck_I2c(void) 175 { 176 SDA=1; 177 _Nop(); 178 _Nop(); 179 _Nop(); 180 SCL=1; 181 _Nop(); 182 _Nop(); //時(shí)鐘低電平周期大于4μ 183 _Nop(); 184 _Nop(); 185 _Nop(); 186 SCL=0; //清時(shí)鐘線,鉗住I2C總線以便繼續(xù)接收 187 _Nop(); 188 _Nop(); 189 } 190 /*---------------------------------------------------------------- 191 向無子地址器件發(fā)送字節(jié)數(shù)據(jù)函數(shù) 192 函數(shù)原型: bit ISendByte(unsigned char sla,ucahr c); 193 功能: 從啟動(dòng)總線到發(fā)送地址,數(shù)據(jù),結(jié)束總線的全過程,從器件地址sla. 194 如果返回1表示操作成功,否則操作有誤。 195 注意: 使用前必須已結(jié)束總線。 196 ----------------------------------------------------------------*/ 197 /*bit ISendByte(unsigned char sla,unsigned char c) 198 { 199 Start_I2c(); //啟動(dòng)總線 200 SendByte(sla); //發(fā)送器件地址 201 if(ack==0)return(0); 202 SendByte(c); //發(fā)送數(shù)據(jù) 20