×
单片机 > 单片机程序设计 > 详情

EEPROM 24c02 [读取存储多字节]

发布时间:2020-06-04 发布时间:
|

先将数据存进去,然后再读出来显示在数码管上。

除了代码里定义的连线外还要把p0连接到8位数码管的8针上。

  1 /*-----------------------------------------------

  2 名称:IIC协议 EEPROM24c02

  3 内容:此程序用于检测EEPROM性能,测试方法如下:写入24c02一些数据,然后在内存中清除这些数据,

  4 掉电后主内存将失去这些信息,然后从24c02中调入这些数据。看是否与写入的相同。

  5 函数是采用软件延时的方法产生SCL脉冲,固对高晶振频率要作 一定的修改....(本例是1us机器

  6 周期,即晶振频率要小于12MHZ)

  7 ------------------------------------------------*/  

  8 #include          //头文件的包含

  9 #include

 10 

 11 #define  _Nop()  _nop_()        //定义空指令

 12 

 13 // 常,变量定义区

 14 unsigned char code dofly_DuanMa[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,

 15 0x77,0x7c,0x39,0x5e,0x79,0x71};// 显示段码值0~F

 16 unsigned char code dofly_WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码

 17 

 18 sbit LATCH1=P2^2;

 19 sbit LATCH2=P2^3;

 20 

 21 sbit SDA=P2^1;            //模拟I2C数据传送位

 22 sbit SCL=P2^0;            //模拟I2C时钟控制位

 23 

 24 bit ack;                  //应答标志位

 25 

 26 void DelayUs2x(unsigned char t);//函数声明 

 27 void DelayMs(unsigned char t);

 28 /*------------------------------------------------

 29 uS延时函数,含有输入参数 unsigned char t,无返回值

 30 unsigned char 是定义无符号字符变量,其值的范围是

 31 0~255 这里使用晶振12M,精确延时请使用汇编,大致延时

 32 长度如下 T=tx2+5 uS 

 33 ------------------------------------------------*/

 34 void DelayUs2x(unsigned char t)

 35 {   

 36     while(--t);

 37 }

 38 /*------------------------------------------------

 39 mS延时函数,含有输入参数 unsigned char t,无返回值

 40 unsigned char 是定义无符号字符变量,其值的范围是

 41 0~255 这里使用晶振12M,精确延时请使用汇编

 42 ------------------------------------------------*/

 43 void DelayMs(unsigned char t)

 44 {

 45     

 46     while(t--)

 47     {

 48         //大致延时1mS

 49         DelayUs2x(245);

 50         DelayUs2x(245);

 51     }

 52 }

 53 /*------------------------------------------------

 54 启动总线

 55 ------------------------------------------------*/

 56 void Start_I2c()

 57 {

 58     SDA=1;   //发送起始条件的数据信号

 59     _Nop();

 60     SCL=1;

 61     _Nop();    //起始条件建立时间大于4.7us,延时

 62     _Nop();

 63     _Nop();

 64     _Nop();

 65     _Nop();    

 66     SDA=0;     //发送起始信号

 67     _Nop();    //起始条件锁定时间大于4μ

 68     _Nop();

 69     _Nop();

 70     _Nop();

 71     _Nop();       

 72     SCL=0;    //钳住I2C总线,准备发送或接收数据

 73     _Nop();

 74     _Nop();

 75 }

 76 /*------------------------------------------------

 77 结束总线

 78 ------------------------------------------------*/

 79 void Stop_I2c()

 80 {

 81     SDA=0;    //发送结束条件的数据信号

 82     _Nop();   //发送结束条件的时钟信号

 83     SCL=1;    //结束条件建立时间大于4μ

 84     _Nop();

 85     _Nop();

 86     _Nop();

 87     _Nop();

 88     _Nop();

 89     SDA=1;    //发送I2C总线结束信号

 90     _Nop();

 91     _Nop();

 92     _Nop();

 93     _Nop();

 94 }

 95 /*----------------------------------------------------------------

 96 字节数据传送函数               

 97 函数原型: void  SendByte(unsigned char c);

 98 功能:  将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对

 99 此状态位进行操作.(不应答或非应答都使ack=0 假)     

100 发送数据正常,ack=1; ack=0表示被控器无应答或损坏。

101 ------------------------------------------------------------------*/

102 void  SendByte(unsigned char c)

103 {

104     unsigned char BitCnt;

105     

106     for(BitCnt=0;BitCnt<8;BitCnt++)  //要传送的数据长度为8位

107     {

108         if((c<

109         else  SDA=0;                

110         _Nop();

111         SCL=1;               //置时钟线为高,通知被控器开始接收数据位

112         _Nop(); 

113         _Nop();             //保证时钟高电平周期大于4μ

114         _Nop();

115         _Nop();

116         _Nop();         

117         SCL=0; 

118     }

119     _Nop();

120     _Nop();

121     SDA=1;               //8位发送完后释放数据线,准备接收应答位

122     _Nop();

123     _Nop();   

124     SCL=1;

125     _Nop();

126     _Nop();

127     _Nop();

128     if(SDA==1)ack=0;     

129     else ack=1;        //判断是否接收到应答信号

130     SCL=0;

131     _Nop();

132     _Nop();

133 }

134 /*----------------------------------------------------------------

135 字节数据传送函数               

136 函数原型: unsigned char  RcvByte();

137 功能:  用来接收从器件传来的数据,并判断总线错误(不发应答信号),

138 发完后请用应答函数。  

139 ------------------------------------------------------------------*/    

140 unsigned char  RcvByte()

141 {

142     unsigned char retc;

143     unsigned char BitCnt;

144     

145     retc=0; 

146     SDA=1;             //置数据线为输入方式

147     for(BitCnt=0;BitCnt<8;BitCnt++)

148     {

149         _Nop();           

150         SCL=0;       //置时钟线为低,准备接收数据位

151         _Nop();

152         _Nop();      //时钟低电平周期大于4.7us

153         _Nop();

154         _Nop();

155         _Nop();

156         SCL=1;       //置时钟线为高使数据线上数据有效

157         _Nop();

158         _Nop();

159         retc=retc<<1;

160         if(SDA==1)retc=retc+1; //读数据位,接收的数据位放入retc中

161         _Nop();

162         _Nop(); 

163     }

164     SCL=0;    

165     _Nop();

166     _Nop();

167     return(retc);

168 }

169 /*----------------------------------------------------------------

170 应答子函数

171 原型:  void Ack_I2c(void);

172 ----------------------------------------------------------------*/

173 void Ack_I2c(void)

174 {

175     SDA=0;     

176     _Nop();

177     _Nop();

178     _Nop();      

179     SCL=1;

180     _Nop();

181     _Nop();              //时钟低电平周期大于4μ

182     _Nop();

183     _Nop();

184     _Nop();  

185     SCL=0;               //清时钟线,钳住I2C总线以便继续接收

186     _Nop();

187     _Nop();    

188 }

189 /*----------------------------------------------------------------

190 非应答子函数

191 原型:  void NoAck_I2c(void);

192 ----------------------------------------------------------------*/

193 void NoAck_I2c(void)

194 {

195     SDA=1;

196     _Nop();

197     _Nop();

198     _Nop();      

199     SCL=1;

200     _Nop();

201     _Nop();              //时钟低电平周期大于4μ

202     _Nop();

203     _Nop();

204     _Nop();  

205     SCL=0;                //清时钟线,钳住I2C总线以便继续接收

206     _Nop();

207     _Nop();    

208 }

209 /*----------------------------------------------------------------

210 向无子地址器件发送字节数据函数               

211 函数原型: bit  ISendByte(unsigned char sla,ucahr c);  

212 功能:     从启动总线到发送地址,数据,结束总线的全过程,从器件地址sla.

213 如果返回1表示操作成功,否则操作有误。

214 注意:    使用前必须已结束总线。

215 ----------------------------------------------------------------*/

216 /*bit ISendByte(unsigned char sla,unsigned char c)

217 {

218     Start_I2c();               //启动总线

219     SendByte(sla);             //发送器件地址

220     if(ack==0)return(0);

221     SendByte(c);               //发送数据

222     if(ack==0)return(0);

223     Stop_I2c();                 //结束总线

224     return(1);

225 }

226 */

227 

228 /*----------------------------------------------------------------

229 向有子地址器件发送多字节数据函数               

230 函数原型: bit  ISendStr(unsigned char sla,unsigned char suba,ucahr *s,unsigned char no);  

231 功能:     从启动总线到发送地址,子地址,数据,结束总线的全过程,从器件

232 地址sla,子地址suba,发送内容是s指向的内容,发送no个字节。

233 如果返回1表示操作成功,否则操作有误。

234 注意:    使用前必须已结束总线。

235 ----------------------------------------------------------------*/

236 bit ISendStr(unsigned char sla,unsigned char suba,unsigned char *s,unsigned char no)

237 {

238     unsigned char i;

239     

240     Start_I2c();               //启动总线

241     SendByte(sla);             //发送器件地址

242     if(ack==0)return(0);

243     SendByte(suba);            //发送器件子地址

244     if(ack==0)return(0);

245     

246     for(i=0;i

247     {   

248         SendByte(*s);            //发送数据

249         DelayMs(1);

250         if(ack==0)return(0);

251         s++;

252     } 

253     Stop_I2c();                  //结束总线

254     return(1);

255 }

256 

257 /*----------------------------------------------------------------

258 向无子地址器件读字节数据函数               

259 函数原型: bit  IRcvByte(unsigned char sla,ucahr *c);  

260 功能:     从启动总线到发送地址,读数据,结束总线的全过程,从器件地

261 址sla,返回值在c.

262 如果返回1表示操作成功,否则操作有误。

263 注意:    使用前必须已结束总线。

264 ----------------------------------------------------------------*/

265 /*bit IRcvByte(unsigned char sla,unsigned char *c)

266 {

267     Start_I2c();                //启动总线

268     SendByte(sla+1);            //发送器件地址

269     if(ack==0)return(0);

270     *c=RcvByte();               //读取数据

271     NoAck_I2c();              //发送非就答位

272     Stop_I2c();               //结束总线

273     return(1);

274 }

275 

276 */

277 /*----------------------------------------------------------------

278 向有子地址器件读取多字节数据函数               

279 函数原型: bit  ISendStr(unsigned char sla,unsigned char suba,ucahr *s,unsigned char no);  

280 功能:     从启动总线到发送地址,子地址,读数据,结束总线的全过程,从器件

281 地址sla,子地址suba,读出的内容放入s指向的存储区,读no个字节。

282 如果返回1表示操作成功,否则操作有误。

283 注意:    使用前必须已结束总线。

284 ----------------------------------------------------------------*/

285 bit IRcvStr(unsigned char sla,unsigned char suba,unsigned char *s,unsigned char no)

286 {

287     unsigned char i;

288     

289     Start_I2c();               //启动总线

290     SendByte(sla);             //发送器件地址

291     if(ack==0)return(0);

292     SendByte(suba);            //发送器件子地址

293     if(ack==0)return(0);

294     

295     Start_I2c();

296     SendByte(sla+1);

297     if(ack==0)return(0);

298     

299     for(i=0;i

300     {   

301         *s=RcvByte();              //发送数据

302         Ack_I2c();                //发送就答位 

303         s++;

304     } 

305     *s=RcvByte();

306     NoAck_I2c();                 //发送非应位

307     Stop_I2c();                    //结束总线

308     return(1);

309 }

310 /*------------------------------------------------

311 主函数

312 ------------------------------------------------*/

313 void main()

314 {

315     unsigned char dofly[4]={1,2,3,4};          // 显示码值 1234

316     unsigned char i;

317     

318     ISendStr(0xae,4,dofly,4);                   //写入24c02

319     DelayMs(200);

320     dofly[0]=0;                                  //清除当前数据

321     dofly[1]=0;

322     dofly[2]=0;

323     dofly[3]=0;

324     IRcvStr(0xae,4,dofly,4);                  //调用存储数据

325     

326     while(1)

327     { 

328        P0=dofly_DuanMa[dofly[i]];//显示存储数据

329        LATCH1=1;                  //锁存

330        LATCH1=0;

331        

332        P0=dofly_WeiMa[i];  //取位码

333        LATCH2=1;          // 锁存

334        LATCH2=0;

335        DelayMs(200);      //延时用于演示显示数据

336        DelayMs(200);

337        i++;

338        if(i==4)

339            i=0;

340     }

341 }



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
如何为单片机选择合适的负载电容