📄 i2c.c
字号:
#include "i2c.h"
#include "hal.h"
#include "pub_func.h"
#include "data_flash.h"
#include "stdlib.h"
signed char CurrentTemperature;
void AptoticE2promStart(void)
{
_clr_wdt();
_disable_interrupt();
RTC_SDA_OUT|=RTC_SDA;
RTC_SCL_OUT|=RTC_SCL;
RTC_SDA_OUT&=~(RTC_SDA);
RTC_SCL_OUT&=~(RTC_SCL);
}
void AptoticE2promStop(void)
{
RTC_SDA_OUT&=~(RTC_SDA);
RTC_SCL_OUT|=RTC_SCL;
RTC_SDA_OUT|=RTC_SDA;
_enable_interrupt();
}
void AptoticE2promSck(void)
{
RTC_SCL_OUT|=RTC_SCL;
_NOP();
RTC_SCL_OUT&=~(RTC_SCL);
_NOP();
}
void AptoticE2promAck(void)
{
RTC_SDA_OUT&=~(RTC_SDA);
AptoticE2promSck();
}
void AptoticE2promNoAck(void)
{
RTC_SDA_OUT|=RTC_SDA;
AptoticE2promSck();
}
unsigned char AptoticE2promReadByte(void)
{
unsigned char rdbyte=0,BitCounter=8;
RTC_SDA_DIR&=~(RTC_SDA);
do{
rdbyte<<=1;
RTC_SCL_OUT|=RTC_SCL;
if(RTC_SDA_IN&RTC_SDA) rdbyte++;
RTC_SCL_OUT&=~(RTC_SCL);
}while(--BitCounter);
RTC_SDA_DIR|=(RTC_SDA);
return(rdbyte);
}
void AptoticE2promWriteByte(unsigned char wrbyte)
{
unsigned char BitCounter=8;
unsigned char wait=0;
do{
if(wrbyte&0x80) RTC_SDA_OUT|=RTC_SDA;
else RTC_SDA_OUT&=~(RTC_SDA);
AptoticE2promSck();
wrbyte<<=1;
}while(--BitCounter);
// 将WAITACK放入SENDBYTE又省空间又有效率
RTC_SDA_DIR&=~(RTC_SDA);
RTC_SCL_OUT|=RTC_SCL;
while(RTC_SDA_IN&RTC_SDA) // 循环等待ACK信号255次循环
{
wait++;
if(!wait)
{
ErrIndication=1;
break;
}
};
RTC_SCL_OUT&=~(RTC_SCL);
RTC_SDA_DIR|=RTC_SDA;
}
void AptoticE2promBegin(void)
{
for(;I2CTemp1>=0x100;I2CTemp1-=0x100)
{
I2CTemp0+=2;
}
AptoticE2promStart();
AptoticE2promWriteByte(I2CTemp0);
AptoticE2promWriteByte(I2CTemp1);
}
void AptoticDataRead(unsigned short addr,unsigned char *data,unsigned char len)
{
unsigned char i,j=0;
ReadRestar:
ErrIndication=0;
I2CTemp0=0xA0;
I2CTemp1=(unsigned short)addr;
for(i=0;i<len;i++,I2CTemp1++)
{
AptoticE2promBegin();
AptoticE2promStart();
AptoticE2promWriteByte(I2CTemp0+1);
data[i]=AptoticE2promReadByte();
AptoticE2promNoAck();
AptoticE2promStop();
}
if(ErrIndication)
{
j++;
if(j<3) goto ReadRestar;
}
}
void AptoticDataWrite(unsigned short addr,unsigned char *data,unsigned char len)
{
unsigned char i,j;
#ifdef TEST_COURSES
//LcdLightOn(1);
#endif
j=0;
WriteRestar:
I2CTemp1=addr;
ErrIndication=0;
I2CTemp0=0xA0;
RTC_WP_OUT&=~(RTC_WP);
for(i=0;i<len;i++,I2CTemp1++)
{
AptoticE2promBegin();
AptoticE2promWriteByte(data[i]);
AptoticE2promStop();
_delay(800);
}
RTC_WP_OUT|=RTC_WP;
if(ErrIndication)
{
j++;
if(j<3) goto WriteRestar;
}
}
void RealtimeOper(unsigned char addr,unsigned char *data,unsigned char len)
{
unsigned char i,j=0,mode;
OperRestar:
ErrIndication=0;
mode=addr&0x01;
I2CTemp0=addr&0xFE;
AptoticE2promStart();
AptoticE2promWriteByte(0x64);
AptoticE2promWriteByte(I2CTemp0);
for(i=0;i<len;i++)
{
if(mode)
{
data[i]=AptoticE2promReadByte();
if(i==len-1) AptoticE2promNoAck();
else AptoticE2promAck();
}
else
{
AptoticE2promWriteByte(data[i]);
}
}
AptoticE2promStop();
if(ErrIndication)
{
j++;
if(j<3) goto OperRestar;
}
}
void TemperatureRead(unsigned char addr,unsigned char *data,unsigned char len)
{
unsigned char i;
AptoticE2promStart();
AptoticE2promWriteByte(0x90);
AptoticE2promWriteByte(addr);
AptoticE2promStop();
AptoticE2promStart();
AptoticE2promWriteByte(0x91);
for(i=0;i<len;i++)
{
*(data+i)=AptoticE2promReadByte();
if(i==len-1) AptoticE2promNoAck();
else AptoticE2promAck();
}
AptoticE2promStop();
}
void TemperatureWrite(unsigned char addr,unsigned char *data,unsigned char len)
{
unsigned char i;
AptoticE2promStart();
AptoticE2promWriteByte(0x90);
AptoticE2promWriteByte(addr);
for(i=0;i<len;i++)
{
AptoticE2promWriteByte(*(data+i));
}
AptoticE2promStop();
}
// 温度补偿值(每一个单位可以补偿-3.05ppm)
// 公式:Frequency variation at any temperature=
// -0.035*(Any temperature-25)*(Any temperature-25)/1000000
const unsigned char _RTCCaliVal[]=
{
0,// 24 or 26 摄氏度---- 负0.035ppm/-3.05ppm=0.011
0,// 23 or 27 摄氏度---- 负0.140ppm/-3.05ppm=0.046
0,// 22 or 28 摄氏度---- 负0.315ppm/-3.05ppm=0.103
0,// 21 or 29 摄氏度---- 负0.560ppm/-3.05ppm=0.184
0,// 20 or 30 摄氏度---- 负0.875ppm/-3.05ppm=0.287
0,// 19 or 31 摄氏度---- 负1.260ppm/-3.05ppm=0.413
2,// 18 or 32 摄氏度---- 负1.715ppm/-3.05ppm=0.562
2,// 17 or 33 摄氏度---- 负2.240ppm/-3.05ppm=0.734
2,// 16 or 34 摄氏度---- 负2.835ppm/-3.05ppm=0.930
2,// 15 or 35 摄氏度---- 负3.500ppm/-3.05ppm=1.148
2,// 14 or 36 摄氏度---- 负4.235ppm/-3.05ppm=1.389
3,// 13 or 37 摄氏度---- 负5.040ppm/-3.05ppm=1.652
3,// 12 or 38 摄氏度---- 负5.915ppm/-3.05ppm=1.939
3,// 11 or 39 摄氏度---- 负6.860ppm/-3.05ppm=2.249
4,// 10 or 40 摄氏度---- 负7.875ppm/-3.05ppm=2.582
4,// 9 or 41 摄氏度---- 负8.960ppm/-3.05ppm=2.938
4,// 8 or 42 摄氏度---- 负10.115ppm/-3.05ppm=3.316
5,// 7 or 43 摄氏度---- 负11.340ppm/-3.05ppm=3.718
5,// 6 or 44 摄氏度---- 负12.635ppm/-3.05ppm=4.143
6,// 5 or 45 摄氏度---- 负14.000ppm/-3.05ppm=4.590
6,// 4 or 46 摄氏度---- 负15.435ppm/-3.05ppm=5.061
7,// 3 or 47 摄氏度---- 负16.940ppm/-3.05ppm=5.554
7,// 2 or 48 摄氏度---- 负18.515ppm/-3.05ppm=6.070
8,// 1 or 49 摄氏度---- 负20.160ppm/-3.05ppm=6.610
8,// 0 or 50 摄氏度---- 负21.875ppm/-3.05ppm=7.172
9,// -1 or 51 摄氏度---- 负23.660ppm/-3.05ppm=7.757
9,// -2 or 52 摄氏度---- 负25.515ppm/-3.05ppm=8.366
10,// -3 or 53 摄氏度---- 负27.440ppm/-3.05ppm=9.000
11,// -4 or 54 摄氏度---- 负29.435ppm/-3.05ppm=9.651
11,// -5 or 55 摄氏度---- 负31.500ppm/-3.05ppm=10.328
12,// -6 or 56 摄氏度---- 负33.635ppm/-3.05ppm=11.028
13,// -7 or 57 摄氏度---- 负35.840ppm/-3.05ppm=11.751
13,// -8 or 58 摄氏度---- 负38.115ppm/-3.05ppm=12.497
14,// -9 or 59 摄氏度---- 负40.460ppm/-3.05ppm=13.266
15,// -10 or 60 摄氏度---- 负42.875ppm/-3.05ppm=14.057
16,// -11 or 61 摄氏度---- 负45.360ppm/-3.05ppm=14.872
17,// -12 or 62 摄氏度---- 负47.915ppm/-3.05ppm=15.710
18,// -13 or 63 摄氏度---- 负50.540ppm/-3.05ppm=16.570
18,// -14 or 64 摄氏度---- 负53.235ppm/-3.05ppm=17.454
19,// -15 or 65 摄氏度---- 负56.000ppm/-3.05ppm=18.361
20,// -16 or 66 摄氏度---- 负58.835ppm/-3.05ppm=19.290
21,// -17 or 67 摄氏度---- 负61.740ppm/-3.05ppm=20.243
22,// -18 or 68 摄氏度---- 负64.715ppm/-3.05ppm=21.218
23,// -19 or 69 摄氏度---- 负67.760ppm/-3.05ppm=22.216
24,// -20 or 70 摄氏度---- 负70.875ppm/-3.05ppm=23.238
25,// -21 or 71 摄氏度---- 负74.060ppm/-3.05ppm=24.282
26,// -22 or 72 摄氏度---- 负77.315ppm/-3.05ppm=25.349
28,// -23 or 73 摄氏度---- 负80.640ppm/-3.05ppm=26.439
29,// -24 or 74 摄氏度---- 负84.035ppm/-3.05ppm=27.552
30,// -25 or 75 摄氏度---- 负87.500ppm/-3.05ppm=28.689
31,// -26 or 76 摄氏度---- 负91.035ppm/-3.05ppm=29.848
32,// -27 or 77 摄氏度---- 负94.640ppm/-3.05ppm=31.030
33,// -28 or 78 摄氏度---- 负98.315ppm/-3.05ppm=32.234
34,// -29 or 79 摄氏度---- 负102.06ppm/-3.05ppm=33.462
36,// -30 or 80 摄氏度---- 负105.875ppm/-3.05ppm=34.713
37,// -31 or 81 摄氏度---- 负109.760ppm/-3.05ppm=35.987
38,// -32 or 82 摄氏度---- 负113.715ppm/-3.05ppm=37.283
40,// -33 or 83 摄氏度---- 负117.740ppm/-3.05ppm=38.603
41,// -34 or 84 摄氏度---- 负121.835ppm/-3.05ppm=39.946
42,// -35 or 85 摄氏度---- 负126.000ppm/-3.05ppm=41.311
44,// -36 or 86 摄氏度---- 负130.235ppm/-3.05ppm=42.700
45,// -37 or 87 摄氏度---- 负134.540ppm/-3.05ppm=44.111
47,// -38 or 88 摄氏度---- 负138.915ppm/-3.05ppm=45.546
48,// -39 or 89 摄氏度---- 负143.360ppm/-3.05ppm=47.003
49,// -40 or 90 摄氏度---- 负147.875ppm/-3.05ppm=48.484
51,// -41 or 91 摄氏度---- 负152.460ppm/-3.05ppm=49.987
52,// -42 or 92 摄氏度---- 负157.115ppm/-3.05ppm=51.513
54,// -43 or 93 摄氏度---- 负161.840ppm/-3.05ppm=53.062
56,// -44 or 94 摄氏度---- 负166.635ppm/-3.05ppm=54.634
57,// -45 or 95 摄氏度---- 负171.500ppm/-3.05ppm=56.230
59,// -46 or 96 摄氏度---- 负176.435ppm/-3.05ppm=57.848
61,// -47 or 97 摄氏度---- 负181.440ppm/-3.05ppm=59.489
62,// -47 or 97 摄氏度---- 负186.515ppm/-3.05ppm=61.152
};
/******************************************
* 读取温度并进行时钟校准
* -----------------------------------------
* 可校准范围为-47至+97摄氏度,误差小于3.05ppm
******************************************/
void GetTemperature(void)
{
signed char temperature[6];
unsigned char rd_time=0,val;
// 使能温度传感器
temperature[0]=0x02;// Channel Sel=000;Fault Queue=00;OTI Polarity=active low;Cmp/Int=Int;Shut-down=0;
RTCCalibrate_START:
TemperatureWrite(0x01,(unsigned char *)&temperature[0],1);
// 等待温度传感器正常工作(>400uS)
_delay(1000);
// 读取温度传感器的工作状态
TemperatureRead(0x01,(unsigned char *)&temperature[1],1);
// 如果温度传感器没有工作的话,则重新使能温度传感器
if(temperature[1]&0x01)
{
if(++rd_time<3)
{
goto RTCCalibrate_START;
}
else
{
return;
}
}
// 读三次
for(rd_time=0;rd_time<3;rd_time++)
{
// 读温度传感器
TemperatureRead(0x00,(unsigned char *)&temperature[rd_time*2],2);
}
// 算温度平均值
CurrentTemperature=(signed char)(((signed char)temperature[0]+(signed char)temperature[2]+(signed char)temperature[4])/3);
// 写时钟校准寄存器
// 温度传感器停止工作
rd_time=0;
temperature[0]=0x03;// Channel Sel=000;Fault Queue=00;OTI Polarity=active low;Cmp/Int=Int;Shut-down=1;
RTCCalibrate_END:
TemperatureWrite(0x01,(unsigned char *)&temperature[0],1);
// 等待温度传感器进入IDEL状态(>400uS)
_delay(1000);
// 读取温度传感器的工作状态
TemperatureRead(0x01,(unsigned char *)&temperature[1],1);
// 如果温度传感器还在工作的话,则重新取消使能
if(!(temperature[1]&0x01))
{
if(++rd_time<3)
{
goto RTCCalibrate_END;
}
}
rd_time=abs(CurrentTemperature-30);
if(rd_time>72)
{
val=63;
}
else
{
val=_RTCCaliVal[rd_time];
}
val=127-val;
#ifdef _NO_RTC_CAL
val=0x3F;
#endif
RealtimeOper(0x70,(unsigned char *)&val,1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -