STM32/STM8技术william hill官网
直播中

Edtion_Len

10年用户 96经验值
擅长:可编程逻辑 电源/新能源 MEMS/传感技术 测量仪表 嵌入式技术 制造/封装 模拟技术 连接器 EMC/EMI设计 光电显示 存储技术 EDA/IC设计 处理器/DSP 接口/总线/驱动 控制/MCU RF/无线
私信 关注
[问答]

stm8l152c6的模拟I2C问题?

[size=14.4444446563721px]这是BMA250传感器,G_SDA_Read    读出来一直为1,请大家帮忙看看是哪里写错了,这个传感器在51单片机试验过可以用的,硬件连线也测过,还是找不出是怎么回事?

#ifndef BMA250_H
#define BMA250_H
//#include        "intrins.h"
#define uchar unsigned char
#define uint  unsigned int
#define nop Delay_Nop(2)
#define  G_SDA          PC_ODR_bit.ODR0
#define  G_SDA_Read     PC_IDR_bit.IDR0
#define  G_SCL          PC_ODR_bit.ODR1
unsigned char  SensorFirstFlag=1,StepUpFlag=0;
uchar rMode=0;
uchar XData=0;
uchar YData=0;
uchar ZData=0;
uchar XMode=0;
uchar YMode=0;
uchar ZMode=0;
uint SquareSum=0,SquareSumBuf1=0,SquareSumBuf2=0,AvgSquareSum=0;
uint SquareSumBuf3=0,SquareSumBuf4=0;
//A=X方+Y方+Z方的平方和
uint BN1=0,BN2=0,TestData=0, MeasureUpCnt=0,StepCnt=0,MeasureDownCnt=0;


/****************
                         BMA250加速度传感器实现

***********************************************************/

void Delay_Nop(unsigned int Nop_Sec)
{
    unsigned int Nop_i = 0;
    while(Nop_Sec--)
    {
        for(Nop_i = 0;Nop_i <10; Nop_i++)
          ;
    }
}


//系统时钟源,快时钟和慢,分频,模式选择
//void        FAST_CLK(void)
//{
//        STPFCK=0;  //Set 1 to stop Fast clock for power saving in Slow/Idle mode.
//                   //This bit can be changed only in Slow mode.
//        _nop_();
//        _nop_();
//        _nop_();
//        SELFCK=1;  //Select Fast Clock as System clock source
//        _nop_();
//        _nop_();
//        _nop_();
//        //TR0=0;
//        //TEST=1;
//}

//软件延时
void DelayB(uint n)
{       
       
        uint i,j;
        for(j=n;j>0;j--)
                 {for(i=500;i>0;i--)
                                 {
                                 }
                 }

       
}
//BMA250 IO初始化
void BMAIO_Init()
{
        PC_DDR_bit.DDR0 = 1;            //PC.0,G_SDA初始化
        PC_CR1_bit.C10 = 1;
        PC_CR2_bit.C20 = 1;

        PC_DDR_bit.DDR1 = 1;            //PC.1,G_SCL初始化
        PC_CR1_bit.C11 = 1;
        PC_CR2_bit.C21 = 1;

        G_SDA = 1;
        G_SCL = 1;
       
}


//I2C起始信号
void Start_GSensor()
{
        G_SCL=1;
        G_SDA=1;
        nop;
        nop;
        nop;
        G_SDA=0;
        nop;
        nop;
        G_SCL=0;
        nop;
        nop;
}

//I2C停止信号
void Stop_GSensor()
{
        G_SDA=0;
        nop;
        nop;
        G_SCL=1;
        nop;
        nop;
        nop;
        G_SDA=1;
        nop;
        nop;
        DelayB(3);
}

//I2C从机应答
void ACKS()
{
//        uint i=0;
//        P2|=0x08;//SDA(P2.3)为输入
//        P2OE&=~0x08;

        G_SDA=0;
        nop;
        G_SCL=1;
        nop;
        nop;
        nop;
//        //等待应答
//        while((G_SDA==1)&&(i<255))
//                i++;
        G_SCL=0;
        nop;
        G_SDA=1;
//        P2OE|=0x08;
//        P2|=0x08;
       
}

//I2C主机应答
void ACKM(void)
{   G_SDA=0;
        nop;
    G_SCL=1;
        nop;
        nop;
        nop;
    G_SCL=0;
        nop;
        G_SDA=1;
}

//告诉从机接收完毕
void NACK(void)
{   G_SDA=1;
    nop;
    G_SCL=1;
    nop;
        nop;
        nop;
    G_SCL=0;
        nop;
        G_SDA=0;
}
//I2C写入一个字节
void Write_GSensor(uchar t)
{
        uchar BitCnt;       
        for (BitCnt=0;BitCnt<8;BitCnt++)
        {
                if((t<                 {
                        G_SDA=1;
                }
                else
                {
                        G_SDA=0;
                }
                G_SCL=1;
                nop;
                G_SCL=0;
                nop;       
        }       
        ACKS();
}
//I2C读出字节
uchar Read_GSensor(void)
{
        uchar BitCnt;
        uchar ReadData=0;

        G_SDA = 1;
        PC_DDR_bit.DDR0 = 0;
                PC_CR2_bit.C20 = 0;
        Delay_Nop(4);
        G_SCL=0;
        ReadData=0;
        Delay_Nop(4);
        for(BitCnt=0;BitCnt<8;BitCnt++)
        {
                G_SCL=1;
                Delay_Nop(4);
                ReadData<<=1;
                if(G_SDA==1)
                {
                        ReadData|=1;
                }
                G_SCL=0;
                Delay_Nop(4);
        }
        PC_DDR_bit.DDR0 = 1;
        PC_CR2_bit.C20 = 1;
        return ReadData;
}
//写寄存器
void WriteG_Reg(uchar reg_addr,uchar reg_data)
{
        Start_GSensor();
        Write_GSensor(0x30);  //I2C从设备地址
        Write_GSensor(reg_addr);
        Write_GSensor(reg_data);
        Stop_GSensor();
}
////读寄存器
//uchar  ReadG_Reg(uchar reg_addr)
//{
//        uchar date;
//        Start_GSensor();
//        Write_GSensor(0x30);
//        ACKS();
//        Write_GSensor(reg_addr);
//        ACKS();
//        Start_GSensor();
//        Write_GSensor(0x31);
//        ACKS();
//        date=Read_GSensor();
//        NACK();
//        Stop_GSensor();
//        return date;       
//}

//BMA250传感器复位
void ResetGSensor(void)
{
         WriteG_Reg(0x14,0xb6);        //使能复位寄存器
         DelayB(180);
}

//BMA250加速度传感器寄存器初始化
void SetGSensorInit(void)
{
        WriteG_Reg(0x0f,0x05);        //设置加速度范围为+-4g
        WriteG_Reg(0x13,0x40);        //设置数据采集及输出,高位寄存器由低位决定       
        WriteG_Reg(0x10,0x10);        //设置数据过滤带宽为1000HZ
        WriteG_Reg(0x11,0x58);       
        //为写一个寄存器电源模式寄存器,置为不延时,低电压模式,休眠50MS
}

//置BMA250 1S休眠状态
void SetGSensorSleep(void)
{
        WriteG_Reg(0x11,0x5e);
        //设置电源模式寄存器值为0x5e,不延迟模式,低功耗运行,休眠时间为1s
}

//置BMA250 50MS工作状态
void SetGSensorWakeup(void)
{
        WriteG_Reg(0x11,0x58);       
        //为写一个寄存器电源模式寄存器,置为不延时,低电压模式,休眠50MS
}



//读取BMA加速度数据值
void ReadAxesData(void)
{
        Start_GSensor();
        Write_GSensor(0x30);
        Write_GSensor(0x02);       
        Start_GSensor();       
        Write_GSensor(0x31);
        XData=Read_GSensor(); ACKM();
        XData=Read_GSensor(); ACKM();
        YData=Read_GSensor(); ACKM();
        YData=Read_GSensor(); ACKM();
        ZData=Read_GSensor(); ACKM();
        ZData=Read_GSensor(); NACK();
        G_SDA=0;
        nop;
        nop;
        G_SCL=1;
        nop;
        nop;
        G_SDA=1;
        nop;
        nop;
}

uchar ReadMode(void)
{
        Start_GSensor();
        Write_GSensor(0x30);
        Write_GSensor(0x02);       
        Start_GSensor();       
        Write_GSensor(0x31);
        XMode=Read_GSensor(); ACKM();
        Read_GSensor(); ACKM();                  
        YMode=Read_GSensor(); ACKM();
        Read_GSensor(); ACKM();
        ZMode=Read_GSensor(); ACKM();
        Read_GSensor(); NACK();
        G_SDA=0;
        nop;
        nop;
        G_SCL=1;
        nop;
        nop;
        G_SDA=1;
        nop;
        nop;
        XMode&=0x01;
        YMode&=0x01;
        ZMode&=0x01;
        if(XMode||YMode||ZMode)
                return 1;
        return 0;
}


//步数计算
void GetSquareSum(void)
{
         if(XData & 0x80) XData=~XData+1;
         if(YData & 0x80) YData=~YData+1;
         if(ZData & 0x80) ZData=~ZData+1;
         SquareSum=XData*XData+YData*YData+ZData*ZData;
}
void CalcStep(void)
{
        if(SensorFirstFlag)                //第一次执行必须为1
        {
                SquareSumBuf1=SquareSum;
                SquareSumBuf2=SquareSum;
                SquareSumBuf3=SquareSum;
                SquareSumBuf4=SquareSum;
                AvgSquareSum=SquareSum;
                SensorFirstFlag=0;
        }
        SquareSumBuf4=SquareSumBuf3;
        SquareSumBuf3=SquareSumBuf2;
        SquareSumBuf2=SquareSumBuf1;
        SquareSumBuf1=SquareSum;

        SquareSum=SquareSumBuf1+SquareSumBuf2+SquareSumBuf3+SquareSumBuf4;
        SquareSum>>=2;
       
        BN1=AvgSquareSum;                  //前一个平方和Bn1的值
        AvgSquareSum=SquareSum;        //平方和Bn2的值
        BN2=AvgSquareSum;
        TestData=BN1-BN2;                   //相减后的测试值
        if(TestData&0x8000)        // 如果是负的,表示Bn>Bn1
        {
                 TestData=~TestData+1;
                 if(TestData>0x360)
                 {
                         if(TestData<0x750)                          //小于750H
                        {
                                MeasureUpCnt++;//上升次数增加
                                if(MeasureUpCnt==2)                 //如果连续上升2次,置上升标志,计1步
                                {
                                        StepUpFlag=1;
                                        StepCnt++;
                                }
                        }                                  
                        else
                        {
                                   StepUpFlag=1;           //大于750H,置上升标志,计1步
                                   StepCnt++;
                        }
                 }
        }
        else        //Bn-1>Bn的情况下,Step down
        {
                 if(TestData>0x220)
                 {
                         if(TestData<0x580)
                        {
                                MeasureDownCnt++;
                                if(MeasureDownCnt==2)
                                        StepUpFlag=0;
                                MeasureUpCnt=0;
                        }
                        else
                        {
                                MeasureUpCnt=0;
                                StepUpFlag=0;
                        }
                 }
        }
}

#endif                                                       
                                                          

#include"iostm8l152c6.h"
#include
#include "bma250.h"

unsigned char Work16Hz = 0;
unsigned char Temp = 0;

void Delay_Test(unsigned int Test_Ms)
{
    unsigned char t = 0;
    while(Test_Ms--)
      for(t = 0;t<250;t++)
        ;
}

void  tiM1_init()
{
    CLK_PCKENR2 |= 0x02;
    TIM1_IER = 0x00; //Disable timer1 interrupt
    TIM1_EGR = 0x01; //Update generation
    TIM1_PSCRH = 0x00;
    TIM1_PSCRL = 0x0F;
    TIM1_ARRH = 0xF4;     //中断62500us 即16HZ
    TIM1_ARRL = 0x24;
    TIM1_CNTRH = 0xF4;
    TIM1_CNTRL = 0x24;
    TIM1_CR1 = 0x01; //counter enable
    TIM1_IER = 0x01; //Enable timer1 interrupt
}

#pragma vector=TIM1_OVR_UIF_vector
__interrupt void TIM1_UPD_OVF_IRQHandler(void)
{
    TIM1_SR1 &= ~0x01;
     Work16Hz = 1;
//    flagcalc = 1;
}
#define  G_SDA          PC_ODR_bit.ODR0
#define  G_SDA_Read     PC_IDR_bit.IDR0
#define  G_SCL          PC_ODR_bit.ODR1

main()
{
    __disable_interrupt();
    CLK_CKDIVR = 0x00;
     TIM1_init();
    __enable_interrupt();
//   BMA_Init();
        BMAIO_Init();

                DelayB(65);
        ResetGSensor();
        nop;
        ResetGSensor();
        nop;
        SetGSensorInit();
        DelayB(30);
        Temp=1;

       Start_GSensor();
        Write_GSensor(0x30);       

        Write_GSensor(0x0f);       
        Start_GSensor();       
        Write_GSensor(0x31);
        Temp=Read_GSensor();
//        NACK();
    Stop_GSensor();
        Delay_Test(100);
    while(1) // 进入无限循环
    {
/*      Start_GSensor();
        Write_GSensor(0x30);
        Write_GSensor(0x02);       
        Start_GSensor();       
        Write_GSensor(0x31);
        XData=Read_GSensor(); ACKM();
      */
//      ReadStep();
    }
}

回帖(7)

高炎

2014-9-12 14:54:58
下一个看看 谢谢楼主 学习一下
举报

赵晓新

2014-9-13 13:55:04
哦哦哦,学习学习,谢谢
举报

anyfsy

2014-9-13 16:54:09
好~~~~~~~~~~~~~~~~~~~~~~~~~~
举报

Edtion_Len

2014-9-14 13:48:52
已经解决问题了,是STM8L开发板上PC1口的电容导致的,这个模拟I2C是可以用的
举报

戚伟业

2014-10-3 15:30:27
引用: Edtion_Len 发表于 2014-9-14 13:48
已经解决问题了,是STM8L开发板上PC1口的电容导致的,这个模拟I2C是可以用的 ...

能联系一下吗?正在做bma250、222相关的
举报

-千以南

2015-4-14 15:48:25
多谢楼主!!!
举报

袁烨

2015-12-23 10:20:00
BMA250EF现货,欢迎咨询Q:1169984850
举报

更多回帖

发帖
×
20
完善资料,
赚取积分