stm8l152c6的模拟I2C问题?
时间:10-02
整理:3721RD
点击:
[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<<BitCnt)&0x80)
{
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 <intrinsics.h>
#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();
}
}
#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<<BitCnt)&0x80)
{
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 <intrinsics.h>
#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();
}
}
下一个看看 谢谢小编 学习一下
哦哦哦,学习学习,谢谢
好~~~~~~~~~~~~~~~~~~~~~~~~~~
已经解决问题了,是STM8L开发板上PC1口的电容导致的,这个模拟I2C是可以用的
能联系一下吗?正在做bma250、222相关的
多谢小编!
BMA250EF现货,欢迎咨询Q:1169984850