⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i2c.c

📁 MSP430方案,用于脉冲采集器,其功能众多,上传代码仅供参考,不得用于商业
💻 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 + -