单片机
返回首页

51单片机连接24C02-C语言测试代码

2017-01-18 来源:eefocus

我总结3点需要注意的地方


1.关闭非IIC通信器件,比如我的开发板SDA和SCL也连接了DS1302,造成干扰会没有结果。


2.IIC通信的应答,发送端在SCL为0时将SDA置1,等待接收端拉低SDA;接收端在拉低SDA持续一个周期后,应将SDA置1释放总线。


主机作为发送端等待应答


SDA=1;

SCL=1;

while(SDA);

SCL=0;

主机作为接收端,进行应答或不应答


SDA=0;    //不应答则为1    

SCL=1;

SCL=0;

SDA=1;

3.24C02在写入周期完成后还有有内部写入时间Twr,所以可以查手册加入适当时间的延时函数,或者使用查询应答的方式进行延时等待。


总之,关键是注意参考数据手册及IIC总线规范,尤其是芯片的特别说明以及时序的控制,再结合代码就能弄懂了。


下面是我写的代码,用上了所有的功能,包括 Current Read 对应的函数 readnext() 。多字节写入时不用考虑分页问题,函数自动解决,直接给数组即可。使用数码管显示结果。


  1 #include

  2 

  3 sbit RST=P2^4;    //用来关闭ds1302

  4 

  5 

  6 sbit SDA=P2^0;                         

  7 sbit SCL=P2^1;

  8 //内部使用的函数

  9 bit start(unsigned char dev);

 10 void stop(void);

 11 bit write_byte(unsigned char dat);

 12 unsigned char read_byte(bit ack);

 13 void waitack(void);

 14 //外部使用

 15 void writes(unsigned char address,unsigned char dat[],unsigned char num);

 16 void reads(unsigned char address,unsigned char dat[],unsigned char num);

 17 unsigned char read(unsigned char address);

 18 void write(unsigned char address,unsigned char dat);

 19 unsigned char readnext(void);

 20 

 21 /*数码管部分*/

 22 sbit du=P2^6;

 23 sbit we=P2^7;

 24 void display(void);

 25 void delayms(unsigned time);

 26 unsigned char code table[]={

 27 0x3f,0x06,0x5b,0x4f,

 28 0x66,0x6d,0x7d,0x07,

 29 0x7f,0x6f,0x77,0x7c,

 30 0x39,0x5e,0x79,0x71};

 31 unsigned char num[6]={0};

 32 

 33 

 34 void main(void)

 35 {

 36     //测试用数据

 37     unsigned char a[9]={2,3,5,7,13,15,11,4,8};

 38     unsigned char b[13]={0};

 39 

 40     RST=0;    //关闭ds1302消除影响

 41 

 42     write(11,6);

 43     write(12,1);

 44     writes(2,a,9);

 45     b[9]=readnext();    //b[9]=6

 46     b[10]=readnext();    //b[10]=1

 47     reads(2,b,9);        //b[0-8]=a[0-8]

 48     b[11]=readnext();    //b[11]=6

 49     b[12]=read(12);        //b[12]=1

 50     

 51     num[5]=b[3];

 52     num[4]=b[6];

 53     num[3]=b[9];

 54     num[2]=b[10];

 55     num[1]=b[11];

 56     num[0]=b[12];

 57     

 58     while(1)

 59     {

 60         display();

 61     } 

 62 }

 63 

 64 //传入设备地址,返回设备是否应答

 65 bit start(unsigned char dev)

 66 {    

 67     SDA=1;

 68     SCL=1;

 69     SDA=0;

 70     SCL=0;

 71     return write_byte(dev);

 72 }

 73 

 74 void stop(void)

 75 {

 76     SDA=0;

 77     SCL=1;

 78     SDA=1;

 79 }

 80 

 81 //传入要写入的字节,返回设备是否应答

 82 bit write_byte(unsigned char dat)

 83 {

 84     unsigned char i=8;

 85     bit ack;

 86     while(i--)

 87     {

 88         dat<<=1;

 89         SDA=CY;

 90         SCL=1;

 91         SCL=0;

 92     }

 93     SDA=1;        //接收设备应答

 94     SCL=1;

 95     ack=~SDA;

 96     SCL=0;

 97     return ack;

 98 }

 99 

100 //在写入后等待24c02完成内部写入

101 //恢复响应的时间为手册中的twr

102 void waitack(void)    

103 {                        

104     while(!start(0xa0));                

105     stop();

106 }

107 

108 //传入是否应答设备,返回读取的字节

109 unsigned char read_byte(bit ack)

110 {

111     unsigned char i=8,ret;

112     

113     while(i--)

114     {

115         ret<<=1;

116         SCL=1;

117         ret|=SDA;

118         SCL=0;

119     }

120     SDA=~ack;    //应答或不应答设备

121     SCL=1;

122     SCL=0;

123     SDA=1;    //应答时要注意的时序

124     return ret;

125 }

126 

127 //传入写入地址,数组,写入字节数

128 //函数自动进行分页写入

129 void writes(unsigned char address,unsigned char dat[],unsigned char num)

130 {

131     unsigned char i;

132     

133     for(i=0;i

134     {

135         start(0xa0);

136         write_byte(address);

137         do

138             write_byte(dat[i++]);

139         while(++address&0x07 && i

140         stop();

141         waitack();    //延时等待以完成内部写入

142     }    

143 }

144 

145 //传入读取地址,接收用的数组,读取字节数

146 void reads(unsigned char address,unsigned char dat[],unsigned char num)

147 {

148     unsigned char i;    

149 

150     start(0xa0);

151     write_byte(address);

152 

153     start(0xa1);

154 

155     for(i=0;i

156         dat[i]=read_byte(1);

157 

158     dat[i]=read_byte(0);

159     stop();

160 }

161 

162 void write(unsigned char address,unsigned char dat)

163 {

164     writes(address,&dat,1);

165 }

166 

167 unsigned char read(unsigned char address)

168 {

169     unsigned char ret;

170     reads(address,&ret,1);

171     return ret;

172 }

173 

174 //对应手册中的Current Read

175 unsigned char readnext(void)

176 {

177     unsigned char ret;

178     start(0xa1);

179     ret=read_byte(0);

180     stop();

181     return ret;

182 }

183 

184 void delayms(unsigned time)

185 {

186     unsigned i,j;

187 

188     for(i=time;i>0;i--)

189         for(j=110;j>0;j--)

190         ;

191 }

192 

193 void display(void)

194 {

195     unsigned char i;

196     

197     for(i=0;i<6;i++)

198     {

199         P0=0;

200         du=1;

201         du=0;

202 

203         P0=~(0x20>>i);

204         we=1;

205         we=0;

206 

207         P0=table[num[i]];

208         du=1;

209         du=0;

210 

211         delayms(1);

212     }

213 }


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

  • SOC系统级芯片设计实验

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

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

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

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

精选电路图
  • CCD图像传感器在微光电视系统中的应用

  • 离子检测器电路分析

  • 一个简单的立体声平衡指示器电路

  • 分享一个电网倾角计电路

  • 电谐波图形均衡器示意图

  • 一种构建12V和230V双直流电源的简单方法

    相关电子头条文章