CC2540直接读MPU6050,前天运行OK,今天运行不行了?
//**************************************** // GY-52 MPU3050 IIC测试程序 // 使用单片机STC89C51 // 晶振:11.0592M // 显示:LCD1602 // 编译环境 Keil uVision2 // 参考宏晶网站24c04通信程序 // 时间:2011年9月1日 // QQ:531389319 //第X作者Btz23,QQ357074909 日期:20140525 2030 //****************************************
#include <math.h> //Keil library #include <stdio.h> //Keil library #include <ioCC2540.h> #include "hal_types.h"
#define MPU6050_DMP_UPDATES_SIZE 47
//**************************************** //定义CC2540端口 //**************************************** #define DataPort P0 #define SDA P1_3 // #define SCL P1_4 //
//sbit LCM_RS=P2^0; // //sbit LCM_RW=P2^1; // //sbit LCM_EN=P2^2; //
//**************************************** //定义类型及变量 //**************************************** char dis[6]; //显示数字(-511至512)的字符数组 int dis_data; //变量 int Temperature,Temp_h,Temp_l; //温度及高低位数据
//**************************************** //函数声明 //**************************************** void delay(unsigned int k); //延时 //void Print_Dec_Char(uchar *s,float temp_data);
//void lcd_printf(uchar *s,int temp_data);
//MPU6050操作函数
//**************************************** //整数转字符串 //****************************************
/*void Print_Dec_Char(char *s,float temp_data) { if(temp_data<0) { temp_data=-temp_data; *s='-'; } else *s=' '; int temp5=temp_data*1000;
*++s =temp5/1000000+0x30; temp5=temp5%1000000; //取余运算 *++s =temp5/100000+0x30; temp5=temp5%100000; //取余运算 *++s =temp5/10000+0x30; temp5=temp5%10000; //取余运算
*++s =temp5/1000+0x30; temp5=temp5%1000; //取余运算
*++s='.'; *++s =temp5/100+0x30; temp5=temp5%100; //取余运算 *++s =temp5/10+0x30; temp5=temp5%10; //取余运算 *++s =temp5+0x30; }
//**************************************** void lcd_printf(char *s,int temp_data) { //double Temp2; if(temp_data<0) { temp_data=-temp_data; *s='-'; } else *s=' '; //temp_data=temp_data*1000;
*++s =temp_data/10000+0x30; temp_data=temp_data%10000; //取余运算
*++s =temp_data/1000+0x30; temp_data=temp_data%1000; //取余运算
*++s =temp_data/100+0x30; temp_data=temp_data%100; //取余运算 *++s =temp_data/10+0x30; temp_data=temp_data%10; //取余运算 *++s =temp_data+0x30; }*/
void SeriPushSend(uchar send_data) { U0DBUF=send_data; while(UTX0IF == 0); UTX0IF = 0; } //**************************************** //延时 //**************************************** void delay(unsigned int k) { unsigned int i,j; for(i=0;i<k;i++) { for(j=0;j<121;j++); } }
//************************************** //延时5微秒(STC90C52RC@12M) //不同的工作环境,需要调整此函数 //当改用1T的MCU时,请调整此延时函数 //************************************** void Delay5us(int microSecs) //对应一个指令是多少时间,在规格书中难找,在HAO_LCD中找到下面的延时程序,更改之,修改201405252039 { while(microSecs--) { /* 32 NOPs == 1 usecs */ asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); } } //************************************** //I2C起始信号 //************************************** void I2C_Start() { SDA = 1; //拉高数据线 SCL = 1; //拉高时钟线 Delay5us(5); //延时 SDA = 0; //产生下降沿 Delay5us(5); //延时 SCL = 0; //拉低时钟线 } //************************************** //I2C停止信号 //************************************** void I2C_Stop() { SDA = 0; //拉低数据线 SCL = 1; //拉高时钟线 Delay5us(5); //延时 SDA = 1; //产生上升沿 Delay5us(5); //延时 } //************************************** //I2C发送应答信号 //入口参数:ack (0:ACK 1:NAK) //************************************** void I2C_SendACK(int ack) { SDA = ack; //写应答信号 SCL = 1; //拉高时钟线 Delay5us(5); //延时 SCL = 0; //拉低时钟线 Delay5us(5); //延时 } //************************************** //I2C接收应答信号 //************************************** int I2C_RecvACK() { SCL = 1; //拉高时钟线 P1DIR=0x05; //设定为输入 btz Delay5us(5); //延时 int CY = SDA; //读应答信号 SCL = 0; //拉低时钟线 P1DIR=0xFF; //这里在单步执行时,没将输入变为输出,接下来的数据就写不进,更改之,修改201405252039 Delay5us(5); //延时 return CY; } //************************************** //向I2C总线发送一个字节数据 //************************************** void I2C_SendByte(uint8_t dat) { uchar i; for (i=0; i<8; i++) //8位计数器 { if(dat&0x80) SDA = 1; //送数据口 开如用CY,今天单步执行就不行了? else if(dat&0x80) //原来是没有这句语名,当SDA为1时赋值后,转而按续执行,SDA又赋0值了,更改之,修改201405252039 SDA=0; SCL = 1; //拉高时钟线 Delay5us(5); //延时 SCL = 0; //拉低时钟线 Delay5us(5); //延时 dat <<= 1; //移出数据的最高位 } I2C_RecvACK(); } //************************************** //从I2C总线接收一个字节数据 //************************************** uchar I2C_RecvByte() { uchar i; uchar dat = 0; P1DIR &= ~0X05; //设SDA脚为输入 btz; //P0INP=0x02; //SDA = 1; //使能内部上拉,准备读取数据, for (i=0; i<8; i++) //8位计数器 { dat <<= 1; SCL = 1; //拉高时钟线 Delay5us(5); //延时 dat |= SDA; //读数据 SCL = 0; //拉低时钟线 Delay5us(5); //延时 } P1DIR |= 0xFF; //重新设定为输输 btz; return dat; } //************************************** //向I2C设备写入一个字节数据 //************************************** void Single_WriteI2C(uchar REG_Address,uint8_t REG_data) { I2C_Start(); //起始信号 I2C_SendByte(SlaveAddress); //发送设备地址+写信号 I2C_SendByte(REG_Address); //内部寄存器地址, I2C_SendByte(REG_data); //内部寄存器数据, I2C_Stop(); //发送停止信号 } //************************************** //从I2C设备读取一个字节数据 //**************************************
uint8 Single_ReadI2C_B(uchar REG_Address)//注意数据类型 { uint8 REG_data_b; I2C_Start(); //起始信号 I2C_SendByte(SlaveAddress); //发送设备地址+写信号 I2C_SendByte(REG_Address); //发送存储单元地址,从0开始 I2C_Start(); //起始信号 I2C_SendByte(SlaveAddress+1); //发送设备地址+读信号 REG_data_b=I2C_RecvByte(); //读出寄存器数据 I2C_SendACK(1); //接收应答信号 I2C_Stop(); //停止信号 return REG_data_b; }
uchar Single_ReadI2C(uchar REG_Address) { uchar REG_data; I2C_Start(); //起始信号 I2C_SendByte(SlaveAddress); //发送设备地址+写信号 I2C_SendByte(REG_Address); //发送存储单元地址,从0开始 I2C_Start(); //起始信号 I2C_SendByte(SlaveAddress+1); //发送设备地址+读信号 REG_data=I2C_RecvByte(); //读出寄存器数据 I2C_SendACK(1); //接收应答信号 I2C_Stop(); //停止信号 return REG_data; } //************************************** //初始化MPU6050 //************************************** void InitMPU6050() { Single_WriteI2C(PWR_MGMT_1, 0x00); //解除休眠状态 Single_WriteI2C(SMPLRT_div, 0x07);// Single_WriteI2C(CONFIG, 0x06);// Single_WriteI2C(GYRO_CONFIG, 0x18);// Single_WriteI2C(ACCEL_CONFIG, 0x01);// } //************************************** //合成数据 //************************************** uchar GetData(uchar REG_Address) { uchar H,L; H=Single_ReadI2C(REG_Address); L=Single_ReadI2C(REG_Address+1); return (H<<8)+L; //合成数据 } //************************************** //在1602上显示10位数据 //************************************** void Display10BitData(int value,uchar x,uchar y) { uchar i; // value/=64; //转换为10位数据 lcd_printf(dis, value); //转换数据显示 for(i=0;i<6;i++) { SeriPushSend(dis[i]); }
// DisplayListChar(x,y,dis,4); //启始列,行,显示数组,显示长度 } //************************************** //显示温度 //************************************** //void display_temp() //{ // Temp_h=Single_ReadI2C(TEMP_OUT_H); //读取温度 // Temp_l=Single_ReadI2C(TEMP_OUT_L); //读取温度 // Temperature=Temp_h<<8|Temp_l; //合成温度 // Temperature = 35+ ((double) (Temperature + 13200)) / 280; // 计算出温度 // lcd_printf(dis,Temperature); //转换数据显示 // DisplayListChar(11,1,dis,4); //启始列,行,显示数组,显示位数 //}
void InitUART(void) { PERCFG = 0x00; //位置 1 P0 口 P0SEL = 0x0c; //P0_2,P0_3 用作串口(外部设备功能) P2DIR &= ~0XC0; //P0 优先作为 UART0 U0CSR |= 0x80; //设置为 UART 方式 U0GCR |= 11; U0BAUD |= 216; //波特率设为 115200 UTX0IF = 0; //UART0 TX 中断标志初始置位 0 }
void UartSend_String(uchar *Data,int len) {
int j; for(j=0;j<len;j++) { U0DBUF = *Data++; while(UTX0IF == 0); UTX0IF = 0; } }
void Printf_float(float tempdata1) { int temp3; temp3=tempdata1*1000; lcd_printf(dis,temp3); }
void System_CC2540_init() { P0SEL = 0x07; P1DIR =0xFF; //重设定为输出 btz //P1INP &=~0X01; //打开上拉 }
/******
****/
#define LED1 P1_0
//InitLcd(); //液晶初始化
void main() { float temp1; int tempx[47]; int k;
delay(500); //上电延时 System_CC2540_init(); InitMPU6050(); //初始化MPU6050 Single_WriteI2C(MPU6050_RA_PWR_MGMT_1,0x59); char gyro_b=Single_ReadI2C(GYRO_CONFIG); // 测试MPU6050读写是否正常 while(1) { SeriPushSend(0x0d); SeriPushSend(0x0a); //换行,回车 delay(100); } }
tz,
这,这代码看得亚历山大啊。。。
能描述地详细点吗?
谢谢Yan,也表示抱歉!拷上去,网站排版出来就是这个样子啦,再贴
//****************************************
// GY-52 MPU3050 IIC测试程序 // 使用单片机STC89C51
// 晶振:11.0592M // 显示:LCD1602
// 编译环境 Keil uVision2 // 参考宏晶网站24c04通信程序
// 时间:2011年9月1日 // QQ:531389319
//第X作者Btz23,QQ357074909 日期:20140525 2030 //****************************************
#include <math.h> //Keil library
#include <stdio.h> //Keil library
#include <ioCC2540.h> #include "hal_types.h"
#define MPU6050_DMP_UPDATES_SIZE 47
//**************************************** //定义CC2540端口 //****************************************
#define DataPort P0
#define SDA P1_3
// #define SCL P1_4
//****************************************
//定义类型及变量
//****************************************
char dis[6]; //显示数字(-511至512)的字符数组
int dis_data; //变量
int Temperature,Temp_h,Temp_l; //温度及高低位数据
//**************************************** //函数声明 //****************************************
void delay(unsigned int k); //延时
//void Print_Dec_Char(uchar *s,float temp_data);
//void lcd_printf(uchar *s,int temp_data);
//MPU6050操作函数
void SeriPushSend(uchar send_data)
{
U0DBUF=send_data;
while(UTX0IF == 0);
UTX0IF = 0; }
//**************************************** //延时 //****************************************
void delay(unsigned int k)
{ unsigned int i,j;
for(i=0;i<k;i++)
{
for(j=0;j<121;j++);
}
}
//************************************** //延时5微秒(STC90C52RC@12M)
//不同的工作环境,需要调整此函数
//当改用1T的MCU时,请调整此延时函数
//**************************************
void Delay5us(int microSecs) //对应一个指令是多少时间,在规格书中难找,在HAO_LCD中找到下面的延时程序,更改之,修改201405252039
{ while(microSecs--)
{ /* 32 NOPs == 1 usecs */
asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); }
}
//************************************** //I2C起始信号 //**************************************
void I2C_Start()
{
SDA = 1; //拉高数据线
SCL = 1; //拉高时钟线
Delay5us(5); //延时
SDA = 0; //产生下降沿
Delay5us(5); //延时
SCL = 0; //拉低时钟线 }
//************************************** //I2C停止信号 //**************************************
void I2C_Stop()
{
SDA = 0; //拉低数据线
SCL = 1; //拉高时钟线
Delay5us(5); //延时
SDA = 1; //产生上升沿
Delay5us(5); //延时
}
//**************************************
//I2C发送应答信号
//入口参数:ack (0:ACK 1:NAK)
//**************************************
void I2C_SendACK(int ack)
{
SDA = ack; //写应答信号
SCL = 1; //拉高时钟线
Delay5us(5); //延时
SCL = 0; //拉低时钟线
Delay5us(5); //延时
}
//************************************** //I2C接收应答信号 //**************************************
int I2C_RecvACK()
{
SCL = 1; //拉高时钟线
P1DIR=0x05; //设定为输入 btz
Delay5us(5); //延时
int CY = SDA; //读应答信号
SCL = 0; //拉低时钟线
P1DIR=0xFF; //这里在单步执行时,没将输入变为输出,接下来的数据就写不进,更改之,修改201405252039
Delay5us(5); //延时
return CY;
}
//************************************** //向I2C总线发送一个字节数据 //**************************************
void I2C_SendByte(uint8_t dat)
{
uchar i;
for (i=0; i<8; i++) //8位计数器
{
if(dat&0x80)
SDA = 1; //送数据口 开如用CY,今天单步执行就不行了?
else if(dat&0x80) //原来是没有这句语名,当SDA为1时赋值后,转而按续执行,SDA又赋0值了,更改之,修改201405252039
SDA=0;
SCL = 1; //拉高时钟线
Delay5us(5); //延时
SCL = 0; //拉低时钟线
Delay5us(5); //延时
dat <<= 1; //移出数据的最高位
}
I2C_RecvACK();
}
//************************************** //从I2C总线接收一个字节数据 //**************************************
uchar I2C_RecvByte()
{
uchar i;
uchar dat = 0;
P1DIR &= ~0X05; //设SDA脚为输入 btz;
//P0INP=0x02;
//SDA = 1; //使能内部上拉,准备读取数据,
for (i=0; i<8; i++) //8位计数器
{
dat <<= 1;
SCL = 1; //拉高时钟线
Delay5us(5); //延时
dat |= SDA; //读数据
SCL = 0; //拉低时钟线
Delay5us(5); //延时
}
P1DIR |= 0xFF; //重新设定为输输 btz;
return dat;
}
//************************************** //向I2C设备写入一个字节数据 //**************************************
void Single_WriteI2C(uchar REG_Address,uint8_t REG_data)
{
I2C_Start(); //起始信号
I2C_SendByte(SlaveAddress); //发送设备地址+写信号
I2C_SendByte(REG_Address); //内部寄存器地址,
I2C_SendByte(REG_data); //内部寄存器数据,
I2C_Stop(); //发送停止信号
}
//************************************** //从I2C设备读取一个字节数据 //**************************************
uint8 Single_ReadI2C_B(uchar REG_Address)//注意数据类型
{
uint8 REG_data_b; I2C_Start(); //起始信号
I2C_SendByte(SlaveAddress); //发送设备地址+写信号
I2C_SendByte(REG_Address); //发送存储单元地址,从0开始
I2C_Start(); //起始信号
I2C_SendByte(SlaveAddress+1); //发送设备地址+读信号
REG_data_b=I2C_RecvByte(); //读出寄存器数据
I2C_SendACK(1); //接收应答信号
I2C_Stop(); //停止信号
return REG_data_b;
}
uchar Single_ReadI2C(uchar REG_Address)
{ uchar REG_data;
I2C_Start(); //起始信号
I2C_SendByte(SlaveAddress); //发送设备地址+写信号
I2C_SendByte(REG_Address); //发送存储单元地址,从0开始
I2C_Start(); //起始信号
I2C_SendByte(SlaveAddress+1); //发送设备地址+读信号
REG_data=I2C_RecvByte(); //读出寄存器数据
I2C_SendACK(1); //接收应答信号
I2C_Stop(); //停止信号
return REG_data; }
//************************************** //初始化MPU6050 //**************************************
void InitMPU6050()
{
Single_WriteI2C(PWR_MGMT_1, 0x00); //解除休眠状态
Single_WriteI2C(SMPLRT_div, 0x07);//
Single_WriteI2C(CONFIG, 0x06);//
Single_WriteI2C(GYRO_CONFIG, 0x18);//
Single_WriteI2C(ACCEL_CONFIG, 0x01);//
}
//************************************** //合成数据 //**************************************
uchar GetData(uchar REG_Address)
{
uchar H,L;
H=Single_ReadI2C(REG_Address);
L=Single_ReadI2C(REG_Address+1);
return (H<<8)+L; //合成数据
}
//************************************** //显示温度 //************************************** //
void InitUART(void)
{ PERCFG = 0x00; //位置 1 P0 口
P0SEL = 0x0c; //P0_2,P0_3 用作串口(外部设备功能)
P2DIR &= ~0XC0; //P0 优先作为
UART0 U0CSR |= 0x80; //设置为
UART 方式 U0GCR |= 11;
U0BAUD |= 216; //波特率设为 115200
UTX0IF = 0; //UART0 TX 中断标志初始置位 0 }
void UartSend_String(uchar *Data,int len)
{
int j; for(j=0;j<len;j++)
{ U0DBUF = *Data++; while(UTX0IF == 0); UTX0IF = 0; } }
#define LED1 P1_0
void main()
{
float temp1;
int tempx[47]; int k;
delay(500); //上电延时
System_CC2540_init();
InitMPU6050(); //初始化MPU6050
Single_WriteI2C(MPU6050_RA_PWR_MGMT_1,0x59);
char gyro_b=Single_ReadI2C(GYRO_CONFIG); // 测试MPU6050读写是否正常
while(1)
{
SeriPushSend(0x0d);
SeriPushSend(0x0a); //换行,回车
delay(100);
}
}
自已解决了,今天又遇到一回!
不过这次,按一下“restart debugger”就OK了,有时就是大脑短路了,
程序是OK,板子是OK,就不会想一下调试器是否OK,是否要复位一下!
