单片机
返回首页

[51单片机] EEPROM 24c02 [I2C代码封装-保存实现流水灯]

2020-06-13 来源:elecfans

这里把EEPROM 24c02封装起来,今后可以直接调用,其连线方式为:SDA-P2.1;SCL-P2.0;WP-VCC


>_<:i2c.c


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

  2 名称:IIC协议 

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

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

  5 ------------------------------------------------*/  

  6 #include 'i2c.h'

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

  8 bit ack;                  //应答标志位

  9 sbit SDA=P2^1;

 10 sbit SCL=P2^0;

 11 /*------------------------------------------------

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

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

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

 15 长度如下 T=tx2+5 uS 

 16 ------------------------------------------------*/

 17 void DelayUs2x(unsigned char t)

 18 {   

 19     while(--t);

 20 }

 21 /*------------------------------------------------

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

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

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

 25 ------------------------------------------------*/

 26 void DelayMs(unsigned char t)

 27 {

 28     while(t--)

 29     {

 30         //大致延时1mS

 31         DelayUs2x(245);

 32         DelayUs2x(245);

 33     }

 34 }

 35 /*------------------------------------------------

 36 启动总线

 37 ------------------------------------------------*/

 38 void Start_I2c()

 39 {

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

 41     _Nop();

 42     SCL=1;

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

 44     _Nop();

 45     _Nop();

 46     _Nop();

 47     _Nop();    

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

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

 50     _Nop();

 51     _Nop();

 52     _Nop();

 53     _Nop();       

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

 55     _Nop();

 56     _Nop();

 57 }

 58 /*------------------------------------------------

 59 结束总线

 60 ------------------------------------------------*/

 61 void Stop_I2c()

 62 {

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

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

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

 66     _Nop();

 67     _Nop();

 68     _Nop();

 69     _Nop();

 70     _Nop();

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

 72     _Nop();

 73     _Nop();

 74     _Nop();

 75     _Nop();

 76 }

 77 /*----------------------------------------------------------------

 78 字节数据传送函数               

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

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

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

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

 83 ------------------------------------------------------------------*/

 84 void  SendByte(unsigned char c)

 85 {

 86     unsigned char BitCnt;

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

 88     {

 89         if((c< 90         else  SDA=0;                

 91         _Nop();

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

 93         _Nop(); 

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

 95         _Nop();

 96         _Nop();

 97         _Nop();         

 98         SCL=0; 

 99     }

100     _Nop();

101     _Nop();

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

103     _Nop();

104     _Nop();   

105     SCL=1;

106     _Nop();

107     _Nop();

108     _Nop();

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

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

111     SCL=0;

112     _Nop();

113     _Nop();

114 }

115 /*----------------------------------------------------------------

116 字节数据传送函数               

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

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

119 发完后请用应答函数。  

120 ------------------------------------------------------------------*/    

121 unsigned char  RcvByte()

122 {

123     unsigned char retc;

124     unsigned char BitCnt;

125 

126     retc=0; 

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

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

129     {

130         _Nop();           

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

132         _Nop();

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

134         _Nop();

135         _Nop();

136         _Nop();

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

138         _Nop();

139         _Nop();

140         retc=retc<<1;

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

142         _Nop();

143         _Nop(); 

144     }

145     SCL=0;    

146     _Nop();

147     _Nop();

148     return(retc);

149 }

150 /*----------------------------------------------------------------

151 应答子函数

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();              //时钟低电平周期大于4μ

163     _Nop();

164     _Nop();

165     _Nop();  

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

167     _Nop();

168     _Nop();    

169 }

170 /*----------------------------------------------------------------

171 非应答子函数

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();              //时钟低电平周期大于4μ

183     _Nop();

184     _Nop();

185     _Nop();  

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

187     _Nop();

188     _Nop();    

189 }

190 /*----------------------------------------------------------------

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

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

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

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

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

196 ----------------------------------------------------------------*/

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

198 {

199     Start_I2c();               //启动总线

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

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

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

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

204     Stop_I2c();                 //结束总线

205     return(1);

206 }

207 */

208 /*----------------------------------------------------------------

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

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

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

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

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

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

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

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

217 {

218     unsigned char i;

219     for(i=0;i220     { 

221         Start_I2c();               //启动总线

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

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

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

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

226         

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

228         

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

230         Stop_I2c();                  //结束总线

231         DelayMs(2);               //必须延时等待芯片内部自动处理数据完毕

232         s++;

233         suba++;

234     } 

235     return(1);

236 }

237 

238 /*----------------------------------------------------------------

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

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

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

242 址sla,返回值在c.

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

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

245 ----------------------------------------------------------------*/

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

247 {

248     Start_I2c();                //启动总线

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

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

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

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

253     Stop_I2c();               //结束总线

254     return(1);

255 }

256 */

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

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

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

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

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

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

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

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

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

266 {

267     unsigned char i;

268     

269     Start_I2c();               //启动总线

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

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

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

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

274     

275     Start_I2c();

276     SendByte(sla+1);

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

278     

279     for(i=0;i280     { 

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

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

283         s++;

284     } 

285     *s=RcvByte();

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

287     Stop_I2c();                    //结束总线

288     return(1);

289 }

>_<:i2c.h


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

 2   名称:IIC协议 头文件

 3 ------------------------------------------------*/  

 4 #ifndef __I2C_H__

 5 #define __I2C_H__           

 6 #include           //头文件的包含

 7 #include

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

 9 /*-----------------------------------------------

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

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

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

13  长度如下 T=tx2+5 uS 

14 ------------------------------------------------*/

15 void DelayUs2x(unsigned char t);

16 /*------------------------------------------------

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

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

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

20 ------------------------------------------------*/

21 void DelayMs(unsigned char t);

22 /*------------------------------------------------

23                     启动总线

24 ------------------------------------------------*/

25 void Start_I2c();

26 /*------------------------------------------------

27                     结束总线

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

29 void Stop_I2c();

30 /*----------------------------------------------------------------

31                  字节数据传送函数               

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

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

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

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

36 ------------------------------------------------------------------*/

37 void  SendByte(unsigned char c);

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

39                  字节数据传送函数               

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

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

42      发完后请用应答函数。  

43 ------------------------------------------------------------------*/    

44 unsigned char  RcvByte();

45 /*----------------------------------------------------------------

46                      应答子函数

47 原型:  void Ack_I2c(void);

48 ----------------------------------------------------------------*/

49 void Ack_I2c(void);

50 /*----------------------------------------------------------------

51                      非应答子函数

52 原型:  void NoAck_I2c(void);

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

54 void NoAck_I2c(void);

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

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

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

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

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

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

61 ----------------------------------------------------------------*/

62 bit ISendByte(unsigned char sla,unsigned char c);

63 

64 /*----------------------------------------------------------------

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

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

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

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

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

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

71 ----------------------------------------------------------------*/

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

73 /*----------------------------------------------------------------

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

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

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

77           址sla,返回值在c.

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

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

80 ----------------------------------------------------------------*/

81 bit IRcvByte(unsigned char sla,unsigned char *c);

82 /*----------------------------------------------------------------

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

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

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

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

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

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

89 ----------------------------------------------------------------*/

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

91 #endif

>_<:下面是main函数中如何调用封装好的函数来实现流水灯的效果的:

>_<:流水灯8个的连线这里用的是P1


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

 2 名称:IIC协议 24c02存储花样灯程序

 3 内容:将表格内容写入24c02,然后批量删除这些数据,

 4 并从24c02中读取数据并显示

 5 ------------------------------------------------*/  

 6 #include                 

 7 #include 'i2c.h'

 8 /*------------------------------------------------

 9 花样灯表格

10 ------------------------------------------------*/

11 unsigned char      dat[]={0x7f,0xbf,0xdf,0xef,

12 0xf7,0xfb,0xfd,0xfe,

13 0xff,0xff,0x00,0x00,

14 0x55,0x55,0xaa,0xaa

15 };//ram允许情况可以无限添加

16 /*------------------------------------------------

17   主函数

18 ------------------------------------------------*/

19 main()

20 {

21     //bit flag;

22     unsigned char i;

23     ISendStr(0xae,80,dat,16);            //写入24c02

24     DelayMs(1);                          //写入后必须延时等待24c02内部

25     //烧录数据处理完毕方可继续其他操作

26     for(i=0;i<16;i++)                    //清除数据

27         dat[i]=0;

28     IRcvStr(0xae,80,dat,16);             //从24c02读出数据 

29     while(1)

30     {

31         for(i=0;i<16;i++)              //查表

32         {

33             DelayMs(200);

34             P1=dat[i];

35         }

36     }

37 }


进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • PIC单片机控制的遥控防盗报警器电路

  • 红外线探测报警器

  • 使用ESP8266从NTP服务器获取时间并在OLED显示器上显示

  • 用NE555制作定时器

  • RS-485基础知识:处理空闲总线条件的两种常见方法

  • 基于ICL296的大电流开关稳压器电源电路

    相关电子头条文章