使用6050发现的奇怪现象
MPU6050的SDA线接在板子上时1602不能显示数据,把SDA拔下来时就能正常显示了,不是IO冲突的原因,是什么问题呢?(主控MSP430F149)不应该是硬件的问题 换了个传感器还是这个问题 大家看下代码吧:
main.c#include <msp430f149.h>
#include <intrinsics.h>
#include "MPU6050.h"
#include "LCD1602.h"
#include "I2C.h"
#define CPU_F ((double)8000000)
#define delay_ms(x) __delay_cycles((long)(CPU_F*(double)x/1000.0))
/*--------------------------------------------------------
功能: 系统时钟初始化
输入参数: 无
输出参数: 无
--------------------------------------------------------*/
static void ClockInit(void)
{
int i;
BCSCTL2 |= SELM1+SELS; //MCLK时钟源为XT2CLK,SMCLK时钟源为XT2CLK
do{
IFG1&=~OFIFG; //清除震荡标志
for(i=0;i<100;i++)
_NOP(); //延时等待
}
while((IFG1&OFIFG)!=0); //如果标志为1 ,则继续循环等待
IFG1&=~OFIFG;
}
/*--------------------------------------------------------
功能: I/O初始化
输入参数: 无
输出参数: 无
--------------------------------------------------------*/
static void GPIOInit(void)
{
P2SEL = 0x00; //设置IO口为普通I/O模式
//P1SEL = 0x00; //设置IO口为普通I/O模式
//P1DIR = 0x00; //P1作为输入
}
/*--------------------------------------------------------
功能: 定时器A初始化
输入参数: 无
输出参数: 无
--------------------------------------------------------*/
static void TimerAInit(void)
{
TACTL |= TASSEL_2+TACLR;
TACCTL0 |= CCIE;
TACTL |= ID_3+MC0;
TACCR0 = 1000; //定时1ms
}
/*--------------------------------------------------------
功能: 主函数
输入参数: 无
输出参数: 无
--------------------------------------------------------*/
void main(void)
{
WDTCTL = WDTPW + WDTHOLD;
/*各模块初始化*/
ClockInit();
GPIOInit();
TimerAInit();
LCDPort_init();
LCD_init();
LCD_clear();
InitMPU6050();
delay_ms(10);
//_EINT(); //开总中断
while(1)
{
LCD_write_str(1,1,"Welcome");
//delay_ms(3);
//Display10BitData(GetData(ACCEL_XOUT_H),2,1); //显示X轴加速度
//Display10BitData(GetData(ACCEL_YOUT_H),7,0); //显示Y轴加速度
//Display10BitData(GetData(ACCEL_ZOUT_H),12,0); //显示Z轴加速
}
}
/*--------------------------------------------------------
功能: 定时器A中断服务程序
--------------------------------------------------------*/
# pragma vector = TIMERA0_VECTOR // 提供中断函数的入口地址
__interrupt void TimerA(void)
{
//P3OUT = ~P3OUT; //控制灯闪烁
}1602.c:/*********************************************************
LCD1602驱动
*********************************************************/
#include <msp430x14x.h>
typedef unsigned int uint;
typedef unsigned char uchar;
#define CPU_F ((double)8000000)
#define delay_us(x) __delay_cycles((long)(CPU_F*(double)x/1000000.0))
#define delay_ms(x) __delay_cycles((long)(CPU_F*(double)x/1000.0))
#define P55 5
#define P56 6
#define P57 7
#define RS_CLR P5OUT &= ~(1 << P55) //RS置低
#define RS_SET P5OUT |= (1 << P55) //RS置高
#define RW_CLR P5OUT &= ~(1 << P56) //RW置低
#define RW_SET P5OUT |= (1 << P56) //RW置高
#define EN_CLR P5OUT &= ~(1 << P57) //E置低
#define EN_SET P5OUT |= (1 << P57) //E置高
#define DataPort P4OUT //P4口为数据口
/*--------------------------------------------------------
功能: 显示屏IO初始化函数
输入参数: 无
输出参数: 无
--------------------------------------------------------*/
extern void LCDPort_init(void)
{
P4SEL = 0x00;
P4DIR = 0xFF;
P5SEL = 0x00;
P5DIR|= BIT5 + BIT6 + BIT7; //控制口设置为输出模式
}
/*--------------------------------------------------------
功能: 显示屏命令写入函数
输入参数: com 要写入的命令
输出参数: 无
--------------------------------------------------------*/
static void LCD_write_com(unsigned char com)
{
RS_CLR;
RW_CLR;
EN_SET;
DataPort = com; //命令写入端口
delay_ms(5);
EN_CLR;
}
/*--------------------------------------------------------
功能: 显示屏数据写入函数
输入参数: data 要写入的数据
输出参数: 无
--------------------------------------------------------*/
static void LCD_write_data(unsigned char data)
{
RS_SET;
RW_CLR;
EN_SET;
DataPort = data; //数据写入端口
delay_ms(5);
EN_CLR;
}
/*--------------------------------------------------------
功能: 显示屏清空
输入参数: 无
输出参数: 无
--------------------------------------------------------*/
extern void LCD_clear(void)
{
LCD_write_com(0x01); //清屏幕显示
delay_ms(5);
}
/*--------------------------------------------------------
功能: 显示屏字符串写入函数
输入参数: x 横坐标
y 纵坐标(0 1)
*s 指向字符串的指针
输出参数: 无
--------------------------------------------------------*/
extern void LCD_write_str(unsigned char x,unsigned char y,unsigned char *s)
{
if (y == 0)
{
LCD_write_com(0x80 + x); //第一行显示
}
else
{
LCD_write_com(0xC0 + x); //第二行显示
}
while (*s)
{
LCD_write_data( *s);
s ++;
}
}
/*--------------------------------------------------------
功能: 显示屏单字符写入函数
输入参数: x 横坐标
y 纵坐标(0 1)
data 字符
输出参数: 无
--------------------------------------------------------*/
extern void LCD_write_char(unsigned char x,unsigned char y,unsigned char data)
{
if (y == 0)
{
LCD_write_com(0x80 + x); //第一行显示
}
else
{
LCD_write_com(0xC0 + x); //第二行显示
}
LCD_write_data( data);
}
/*--------------------------------------------------------
功能: 显示屏初始化函数
输入参数: 无
输出参数: 无
--------------------------------------------------------*/
extern void LCD_init(void)
{
LCD_write_com(0x38); //显示模式设置
delay_ms(5);
LCD_write_com(0x08); //显示关闭
delay_ms(5);
LCD_write_com(0x01); //显示清屏
delay_ms(5);
LCD_write_com(0x06); //显示光标移动设置
delay_ms(5);
LCD_write_com(0x0C); //显示开及光标设置
delay_ms(5);
}
//****************************************
//LCD1602显示字符串
//****************************************
void DisplayListChar(uchar X,uchar Y,uchar *DData,uchar L)
{
uchar ListLength=0;
Y&=0x1;
X&=0xF;
while(L--)
{
LCD_write_char(X,Y,DData);
ListLength++;
X++;
}
}MPU6050.c:/*********************************************************
MPU6050驱动
*********************************************************/
#include "MPU6050.h"
#include "LCD1602.h"
#include "I2C.h"
uchar dis; //显示数字(-511至512)的字符数组
int dis_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);
}
//**************************************
//合成数据
//**************************************
int GetData(uchar REG_Address)
{
char 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)
{
value/=64; //转换为10位数据
lcd_printf(dis, value); //转换数据显示
LCD_write_str(x,y,dis);
//DisplayListChar(x,y,dis,4); //启始列,行,显示数组,显示长度
}
/*--------------------------------------------------------------------
功能:整数转字符串(便于在1602上显示)
--------------------------------------------------------------------*/
void lcd_printf(uchar *s,int temp_data)
{
if(temp_data<0)
{
temp_data=-temp_data;
*s='-';
}
else *s=' ';
*++s =temp_data/100+0x30;
temp_data=temp_data%100; //取余运算
*++s =temp_data/10+0x30;
temp_data=temp_data%10; //取余运算
*++s =temp_data+0x30;
}
I2C.c:/*********************************************************
I2C驱动
*********************************************************/
#include"msp430x14x.h"
#include "MPU6050.h"
//#define SDA P2.1
//#define SCL P2.0
#define SDA_1 P2OUT |= BIT1 //SDA = 1
#define SDA_0 P2OUT &= ~BIT1 //SDA = 0
#define SCL_1 P2OUT |= BIT0 //SCL = 1
#define SCL_0 P2OUT &= ~BIT0 //SCL = 0
#define DIR_IN P2DIR &= ~BIT1 //I/O 口为输入
#define DIR_OUT P2DIR |= BIT1 //SDA 输出数据
#define SDA_IN ((P2IN >> 1) & 0x01)
#define TIME 5 //I2C 时序延时时间
unsigned int uiSendDataBuffer;
unsigned int uiReceiveDataBuffer;
/****************************************
*FUNCTION NAME: I2CDelay();
*CREATE DATE:2006.09.07
*CREATED BY:DreamHW
*FUNCTION:I2C 总线必要的延时程序
Y DATE:
*INPUT:n->延时时间数 相当于指令周期数
*OUTPUT:nop
*RETURN:nop
****************************************/
void I2CDelay(unsigned int n)
{
unsigned int i;
for(i = 0;i < n;i++)
{
;
}
}
/****************************************
*FUNCTION NAME: I2CStart();
*CREATE DATE:2006.09.07
*CREATED BY:DreamHW
*FUNCTION:I2C 总线启动时序
*MODIFY DATE:
*INPUT:nop
*OUTPUT:nop
*RETURN:nop
****************************************/
void I2CStart(void)
{
DIR_OUT;
SDA_1;
I2CDelay(TIME);
SCL_1;
I2CDelay(TIME);
SDA_0;
I2CDelay(TIME);
SCL_0;
}
/****************************************
*FUNCTION NAME: I2CStop();
*CREATE DATE:2006.09.07
*CREATED BY:DreamHW
*FUNCTION:I2C 总线停止时序
*MODIFY DATE:
*INPUT:nop
*OUTPUT:nop
RETURN:nop
****************************************/
void I2CStop(void)
{
DIR_OUT;
SDA_0;
I2CDelay(TIME);
SCL_1;
I2CDelay(TIME);
SDA_1;
}
/****************************************
*FUNCTION NAME: I2CReceiveACK();
CREATE DATE: 2006.09.08
*CREATED BY:DreamHW
*FUNCTION:等待接受 ACK 信号,完成一次操作
*MODIFY DATE:
*INPUT:nop
*OUTPUT:nop
*RETURN:nop
****************************************/
void I2CReceiveACK(void)
{
SCL_1;
I2CDelay(TIME);//
DIR_IN;
while(SDA_IN);
DIR_OUT;
SCL_0;
I2CDelay(TIME);
}
/****************************************
*FUNCTION NAME: I2CSendByte();
*CREATE DATE: 2006.09.08
*CREATED BY:DreamHW
*FUNCTION:I2C 送一个字节的数据
*MODIFY DATE:
*INPUT:ucWRData
*OUTPUT:nop
*RETURN:nop
****************************************/
void I2CSendByte(unsigned char ucWRData)
{
DIR_OUT;
unsigned int i;
for(i = 0;i < 8;i++)
{
SCL_0;
I2CDelay(TIME);
if((ucWRData >> 7) & 0x01) SDA_1;//最高位是否为 1,为则SDA= 1
else SDA_0; //否则 SDA=0
I2CDelay(TIME);
SCL_1;
I2CDelay(TIME);
ucWRData <<= 1 ;//数据左移一位,进入下一轮送数
}
SCL_0;//
SDA_1;//等待ack
I2CDelay(TIME);
I2CReceiveACK();
}
/****************************************
*FUNCTION NAME: I2CReceiveByte();
*CREATE DATE:2006.09.08
*CREATED BY:DreamHW
*FUNCTION:接受一个字节的数据
*MODIFY DATE:
*INPUT:nop
*OUTPUT:ucRDData
*RETURN:ucRDData
****************************************/
unsigned char I2CReceiveByte(void)
{
unsigned char i;
unsigned char ucRDData = 0;//返回值
unsigned char ucDataBit = 0;//每一个 clk 接受到的数据
SCL_0;
I2CDelay(TIME);
SDA_1;
DIR_IN;
for(i = 0;i < 8;i++)
{
SCL_1;
I2CDelay(TIME);
ucDataBit = SDA_IN;
I2CDelay(TIME);
ucRDData = ((ucRDData << 1) | ucDataBit);//将数据依次存入 ucRDData
SCL_0;
I2CDelay(TIME);
}
return(ucRDData);
}
/****************************************
*FUNCTION NAME: I2CAcknowledge();
*CREATE DATE: 2006.09.08
*CREATED BY:DreamHW
*FUNCTION:接受数据后发送一个 ACK 信号
*MODIFY DATE:
*INPUT:nop
*OUTPUT:nop
*RETURN:nop
****************************************/
void I2CAcknowledge(void)
{
SCL_0;
DIR_OUT;
SDA_0;
I2CDelay(TIME);
SCL_1;
I2CDelay(TIME);
SCL_0;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
/*--------------------------------------------------------
功能: 向I2C设备写入一个字节数据
输入参数:
输出参数: 无
--------------------------------------------------------*/
void Single_WriteI2C(uchar REG_Address,uchar REG_data)
{
I2CStart(); //起始信号
I2CSendByte(SlaveAddress); //发送设备地址+写信号
I2CSendByte(REG_Address); //内部寄存器地址,
I2CSendByte(REG_data); //内部寄存器数据,
I2CStop(); //发送停止信号
}
/*--------------------------------------------------------
功能: 从I2C设备读取一个字节数据
输入参数:
输出参数: 无
--------------------------------------------------------*/
unsigned char Single_ReadI2C(uchar REG_Address)
{
uchar REG_data;
I2CStart(); //起始信号
I2CSendByte(SlaveAddress); //发送设备地址+写信号
I2CSendByte(REG_Address); //发送存储单元地址,从0开始
I2CStart(); //起始信号
I2CSendByte(SlaveAddress+1);//发送设备地址+读信号
REG_data=I2CReceiveByte(); //读出寄存器数据
I2CAcknowledge(); //接收应答信号
I2CStop(); //停止信号
return REG_data;
}
我的也是这样楼主 解决问题没有呀 lijungei 发表于 2013-5-17 16:56 static/image/common/back.gif
我的也是这样楼主 解决问题没有呀
IIC等到握手信号没等到呗 然后程序就一直while在等待握手信号那句代码了
页:
[1]