首先下载相关文件eMPL.zip,解压缩得到eMPL文件夹,将整个eMPL文件夹复制到要移植的工程下的project/code/目录下,包括以下文件:在这里插入图片描述
打开keil mdk项目,点击魔法棒配置目录,添加…\code\eMPL与…\code\eMPL\include这两个环境目录,点OK。在这里插入图片描述
添加项目文件夹及文件在这里插入图片描述
选中这6个文件点击add,再点close,然后ok
在这里插入图片描述
可以看到6个文件已经被添加到项目里了
在这里插入图片描述
打开zf_driver_soft_iic.c,在最后添加以下内容:

//-------------------------------------------------------------------------------------------------------------------
//  @brief      GPIO方向设置
//  @param      pin         选择的引脚 (可选择范围由 common.h 内PIN_enum枚举值确定)
//  @param      dir         引脚的方向   输出:GPO   输入:GPI
//  @return     void        
//  Sample usage:           gpio_dir(D0,GPO);//设置D0为输出模式
//-------------------------------------------------------------------------------------------------------------------
void gpio_dir(gpio_pin_enum pin, gpio_dir_enum dir)
{
    if (GPI == dir) PORTPTR[pin>>5]->GDIR &= ~(1U << (pin&0x1f));
    else            PORTPTR[pin>>5]->GDIR |= (1U << (pin&0x1f));
}
#define SEEKFREE_SCL    C23                           //定义SCL引脚  可任意更改为其他IO
#define SEEKFREE_SDA    C22                           //定义SDA引脚  可任意更改为其他IO
#define SDA             gpio_get_level (SEEKFREE_SDA)
#define SDA0()          gpio_low (SEEKFREE_SDA)		//IO口输出低电平
#define SDA1()          gpio_high (SEEKFREE_SDA)		//IO口输出高电平  
#define SCL0()          gpio_low (SEEKFREE_SCL)		//IO口输出低电平
#define SCL1()          gpio_high (SEEKFREE_SCL)		//IO口输出高电平
#define DIR_OUT()       gpio_dir (SEEKFREE_SDA, GPO)    //输出方向
#define DIR_IN()        gpio_dir (SEEKFREE_SDA, GPI)    //输入方向
//-------------------------------------------------------------------------------------------------------------------
//  @brief      模拟IIC延时
//  @return     void						
//  @since      v1.0
//  Sample usage:				如果IIC通讯失败可以尝试增加simiic_delay_time的值
//-------------------------------------------------------------------------------------------------------------------
static uint16 simiic_delay_time=100;   //ICM等传感器应设置为100
void simiic_delay(void)
{
	uint16 delay_time;
    delay_time = simiic_delay_time;
	while(delay_time--);
}
//内部使用,用户无需调用
void simiic_start(void)
{
	SDA1();
	SCL1();
	simiic_delay();
	SDA0();
	simiic_delay();
	SCL0();
}


//字节发送程序
//发送c(可以是数据也可是地址),送完后接收从应答
//不考虑从应答位
//内部使用,用户无需调用
static int sccb_waitack(void)
{
    SCL0();
	DIR_IN();
	simiic_delay();
	
	SCL1();
    simiic_delay();
	
    if(SDA)           //应答为高电平,异常,通信失败
    {
        DIR_OUT();
        SCL0();
        return 0;
    }
    DIR_OUT();
    SCL0();
	simiic_delay();
    return 1;
}
void send_ch(uint8 c)
{
	uint8 i = 8;
    while(i--)
    {
        if(c & 0x80)	SDA1();//SDA 输出数据
        else			SDA0();
        c <<= 1;
        simiic_delay();
        SCL1();                //SCL 拉高,采集信号
        simiic_delay();
        SCL0();                //SCL 时钟线拉低
    }
	sccb_waitack();
}
//主应答(包含ack:SDA=0和no_ack:SDA=0)
//内部使用,用户无需调用
void simiic_sendack(unsigned char ack_dat)
{
    SCL0();
	simiic_delay();
	if(ack_dat) SDA0();
    else    	SDA1();

    SCL1();
    simiic_delay();
    SCL0();
    simiic_delay();
}

//字节接收程序
//接收器件传来的数据,此程序应配合|主应答函数|使用
//内部使用,用户无需调用
uint8 read_ch(uint8 ack_x)
{
    uint8 i;
    uint8 c;
    c=0;
    SCL0();
    simiic_delay();
    SDA1();             
    DIR_IN();           //置数据线为输入方式
    for(i=0;i<8;i++)
    {
        simiic_delay();
        SCL0();         //置时钟线为低,准备接收数据位
        simiic_delay();
        SCL1();         //置时钟线为高,使数据线上数据有效
        simiic_delay();
        c<<=1;
        if(SDA) 
        {
            c+=1;   //读数据位,将接收的数据存c
        }
    }
    DIR_OUT();
	SCL0();
	simiic_delay();
	simiic_sendack(ack_x);
	
    return c;
}


//内部使用,用户无需调用
void simiic_stop(void)
{
	SDA0();
	SCL0();
	simiic_delay();
	SCL1();
	simiic_delay();
	SDA1();
	simiic_delay();
}
//IIC连续写
//addr:器件地址 
//reg:寄存器地址
//len:写入长度
//buf:数据区
//返回值:0,正常
//    其他,错误代码
uint8_t MPU_Write_Len(uint8_t addr,uint8_t reg,uint8_t len,uint8_t *buf)
{
	uint8_t i; 
    simiic_start();
	send_ch((addr<<1)|0);//发送器件地址+写命令	
    send_ch(reg);	//写寄存器地址
	for(i=0;i<len;i++)
	{
		send_ch(buf[i]);	//发送数据		
	}    
    simiic_stop();	 
	return 0;	
} 
//IIC连续读
//addr:器件地址
//reg:要读取的寄存器地址
//len:要读取的长度
//buf:读取到的数据存储区
//返回值:0,正常
//    其他,错误代码
uint8_t MPU_Read_Len(uint8_t addr,uint8_t reg,uint8_t len,uint8_t *buf)
{ 
 	simiic_start();
	send_ch((addr<<1)|0);//发送器件地址+写命令	
    send_ch(reg);	//写寄存器地址
	
    simiic_start();
	send_ch((addr<<1)|1);//发送器件地址+读命令	
	
	while(len)
	{
		if(len==1)*buf=read_ch(0);	//读数据,发送nACK 
		else *buf=read_ch(1);		//读数据,发送ACK  
		len--;
		buf++; 
	}    
    simiic_stop();	//产生一个停止条件 
	return 0;	
}

打开zf_driver_soft_iic.h,在#endif前添加以下内容:

uint8_t MPU_Read_Len(uint8_t addr,uint8_t reg,uint8_t len,uint8_t *buf);
uint8_t MPU_Write_Len(uint8_t addr,uint8_t reg,uint8_t len,uint8_t *buf);

打开main.c,编写代码如下:

#include "zf_common_headfile.h"
#include "inv_mpu.h"
// 打开新的工程或者工程移动了位置务必执行以下操作
// 第一步 关闭上面所有打开的文件
// 第二步 project->clean  等待下方进度条走完
// 本例程是开源库移植用空工程
int main(void)
{
    clock_init(SYSTEM_CLOCK_600M);  // 不可删除
    debug_init();                   // 调试端口初始化

    // 此处编写用户代码 例如外设初始化代码等
    float pitch=0,roll=0,yaw=0; 		//欧拉角
	mpu6050_init();
	ips114_init();
	while(mpu_dmp_init()!=0)
	{ 
		ips114_show_string(0,0,"dmp-error");
	}
	ips114_show_string(0,0,"dmp-init-ok");
    while (1)
    {
        //此处编写需要循环执行的代码
		
		mpu_dmp_get_data(&pitch,&roll,&yaw);
		ips114_show_float(0,20,pitch,3,2);
		ips114_show_float(0,40,roll,3,2);
		ips114_show_float(0,60,yaw,3,2);
		system_delay_ms(5);
    }
}

最后编译烧录即可。
在这里插入图片描述

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐