一、平台:hisi3516

imu模块:mpu6500   采集方式:spi 传输到pc:socket

开发板上源码:

#include <stdint.h>

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <linux/types.h>
#include <linux/spi/spidev.h>
#include <sys/wait.h>

//#define SINGLE_READ

#define SERVER_PORT    8888 
#define LENGTH_OF_LISTEN_QUEUE 20
#define BUFFER_SIZE 1024

static const char *device = "/dev/spidev0.0";
static unsigned char mode = SPI_MODE_3  ; 
static unsigned char bits = 16; 
static uint32_t speed = 12*1000*1000;/* 设置spi传输速度 */

static int g_fd = -1;

struct mpu6500_data {
   int16_t  accel_raw[3];
   int16_t  gyro_raw[3];
   int16_t  temprature;
   double   timeStampe;

unsigned int index;
};

double gettimestamp()
{
struct timeval tv;
gettimeofday(&tv, NULL);
return tv.tv_usec + tv.tv_sec*1e6;
}

int SPI_Fast_Transfer(unsigned char *tx , unsigned char *rx, unsigned int len)
{

int ret = 0;
    struct spi_ioc_transfer mesg[1];

memset(mesg, 0, sizeof(mesg));
    mesg[0].tx_buf = (__u64)tx;
    mesg[0].len    = (__u32)len;
    mesg[0].rx_buf = (__u64)rx;
    mesg[0].cs_change = 1;

ret = ioctl(g_fd, SPI_IOC_MESSAGE(1), mesg);
    if (ret  < 0) {  
        printf("SPI_IOC_MESSAGE error \n");  
        return -1;  
    }
}

int sensor_write_register(unsigned char addr, unsigned char data)
{
    int ret;
    struct spi_ioc_transfer mesg[1];
    unsigned char  tx_buf[8] = {0};
    unsigned char  rx_buf[8] = {0};
    
    tx_buf[0] = data;
    tx_buf[1] = addr & (~0x80);

memset(mesg, 0, sizeof(mesg));  
    mesg[0].tx_buf = (__u64)tx_buf;  
    mesg[0].len    = 2;  
    mesg[0].rx_buf = (__u64)rx_buf; 
    mesg[0].cs_change = 1;

ret = ioctl(g_fd, SPI_IOC_MESSAGE(1), mesg);
    if (ret < 0) {  
        printf("SPI_IOC_MESSAGE error \n");  
        return -1;  
    }
 
    return 0;
}

int sensor_read_register(unsigned char addr)
{
    int ret = 0;
    struct spi_ioc_transfer mesg[1];
    unsigned char  tx_buf[8] = {0};
    unsigned char  rx_buf[8] = {0};
    
tx_buf[0] = 0;
    tx_buf[1] = addr | 0x80;

memset(mesg, 0, sizeof(mesg));
    mesg[0].tx_buf = (__u64)tx_buf;
    mesg[0].len    = 2;
    mesg[0].rx_buf = (__u64)rx_buf;
    mesg[0].cs_change = 1;

ret = ioctl(g_fd, SPI_IOC_MESSAGE(1), mesg);
    if (ret  < 0) {  
        printf("SPI_IOC_MESSAGE error \n");  
        return -1;  
    }
    
    return rx_buf[0];
}

/**
*设置imu寄存器
**/

int set_imu_register(void)
{
sensor_write_register(0x56, 0x00);
usleep(1000);
sensor_write_register(0x1A,0x07);  //low pass filter   [2:0]
    usleep(1000);
    sensor_write_register(0x1B,0x1B);  //GYRO_CONFIG   XG_ST  YG_ST  ZG_ST  FS_SEL        Resv   FCHOICE_B   //00为启用
    usleep(1000);                  
    sensor_write_register(0x1C,0x18);  //ACCEL_CONFIG  XA_ST  YA_ST  ZA_ST  FS_SEL        Resv
    usleep(1000);                       
    sensor_write_register(0x1D,0x08);  //ACCEL_CONFIG2 Resv                        FCHOICE_B     A_DLPF_CFG
usleep(1000);
sensor_write_register(0x6B, 0x00);
usleep(1000);
    sensor_write_register(0x19,0x00);  
usleep(1000);
    
return 0;
}

/**
* 功 能:打开设备 并初始化设备
* 入口参数 :
* 出口参数:
* 返回值:0 表示已打开 
*/
int spi_sensor_open(void)
{
int fd;
int ret = 0;

fd = open(device, O_RDWR);
if (fd < 0)
printf("can't open device\n");
else
printf("SPI - Open Succeed. Start Init SPI...\n");

g_fd = fd;
/*
* spi mode
*/
ret = ioctl(fd, SPI_IOC_WR_MODE, &mode);
if (ret == -1)
printf("can't set spi mode\n");

ret = ioctl(fd, SPI_IOC_RD_MODE, &mode);
if (ret == -1)
printf("can't get spi mode\n");

/*
* bits per word
*/
ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
if (ret == -1)
printf("can't set bits per word\n");

ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits);
if (ret == -1)
printf("can't get bits per word\n");

/*
* max speed hz
*/
ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
if (ret == -1)
printf("can't set max speed hz\n");

ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);
if (ret == -1)
printf("can't get max speed hz\n");

printf("spi mode: %d\n", mode);
printf("bits per word: %d\n", bits);
printf("max speed: %d KHz (%d MHz)\n", speed / 1000, speed / 1000 / 1000);

return ret;
}

/**
* 功 能:关闭SPI模块
*/
int spi_senor_close(void)
{
int fd = g_fd;

if (fd == 0) /* SPI是否已经打开*/
return 0;
close(fd);
g_fd = 0;

return 0;
}

static unsigned int imu_index ;
int mpu6500_get_data(struct mpu6500_data *data)
{

#ifdef SINGLE_READ
data->accel_raw[0] = sensor_read_register(0x3b) << 0x08;
data->accel_raw[0] |= sensor_read_register(0x3c);

data->accel_raw[1] = sensor_read_register(0x3d) << 0x08;
data->accel_raw[1] |= sensor_read_register(0x3e);

data->accel_raw[2] = sensor_read_register(0x3f) << 0x08;
data->accel_raw[2] |= sensor_read_register(0x40);

data->temprature = sensor_read_register(0x41) << 0x08;
data->temprature |= sensor_read_register(0x42);

data->gyro_raw[0] = sensor_read_register(0x43) << 0x08;
data->gyro_raw[0] |= sensor_read_register(0x44);

data->gyro_raw[1] = sensor_read_register(0x45) << 0x08;
data->gyro_raw[1] |= sensor_read_register(0x46);

data->gyro_raw[2] = sensor_read_register(0x47) << 0x08;
data->gyro_raw[2] |= sensor_read_register(0x48);

#else

unsigned char tx_buf[14] = {0};
unsigned char rx_buf[14] = {0};
tx_buf[1] = 0x3b | 0x80;
SPI_Fast_Transfer(tx_buf , rx_buf, 14);

data->accel_raw[0] = rx_buf[0] << 0x08;
data->accel_raw[0] |= rx_buf[1];

data->accel_raw[1] = rx_buf[2] << 0x08;
data->accel_raw[1] |= rx_buf[3];

data->accel_raw[2] = rx_buf[4] << 0x08;
data->accel_raw[2] |= rx_buf[5];

data->temprature = rx_buf[6] << 0x08;
data->temprature |= rx_buf[7];

data->gyro_raw[0] = rx_buf[8] << 0x08;
data->gyro_raw[0] |= rx_buf[9];

data->gyro_raw[1] = rx_buf[10] << 0x08;
data->gyro_raw[1] |= rx_buf[11];

data->gyro_raw[2] = rx_buf[12] << 0x08;
data->gyro_raw[2] |= rx_buf[13];
#endif

data->timeStampe = gettimestamp();

imu_index ++;

data->index = imu_index;

return 0;
}

static unsigned int i ; 
static double time_last  , time_cur ;
static float error_rate;
static unsigned int lost_num;
void show_imu(struct mpu6500_data temp)
{
time_last = time_cur;
time_cur = temp.timeStampe; 
if(abs(time_cur - time_last) > 200)
{
i++;
}
lost_num = i;
error_rate = (float)i/(float)imu_index;

printf("accel_x = %d, accel_y = %d, accel_z = %d\n", temp.accel_raw[0], temp.accel_raw[1], temp.accel_raw[2]);
printf("gyro_x = %d,  gyro_y = %d,  gyro_z = %d\n", temp.gyro_raw[0], temp.gyro_raw[1], temp.gyro_raw[2]);
printf("temprature = %d, timeStampe = %f , lost_data = %d, lost_data_rate = %f, index = %d\n", temp.temprature, temp.timeStampe, i, error_rate, imu_index );
}

int main(int argc, char **argv)
{

struct sockaddr_in server_addr;
    bzero(&server_addr,sizeof(server_addr)); 
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = htons(INADDR_ANY);
    server_addr.sin_port = htons(SERVER_PORT);

//创建用于internet的流协议(TCP)socket,用server_socket代表服务器socket
    int server_socket = socket(PF_INET,SOCK_STREAM,0);
    if( server_socket < 0)
    {
        printf("Create Socket Failed!");
        exit(1);
    }
else
{
int opt =1;
setsockopt(server_socket,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
}

if( bind(server_socket,(struct sockaddr*)&server_addr,sizeof(server_addr)))
    {
        printf("Server Bind Port : %d Failed!", SERVER_PORT); 
        exit(1);
    }

if ( listen(server_socket, LENGTH_OF_LISTEN_QUEUE) )
    {
        printf("Server Listen Failed!"); 
        exit(1);
    }

/*设置imu*/
spi_sensor_open();
set_imu_register();

struct mpu6500_data data; 
    while (1) 
    {
        //定义客户端的socket地址结构client_addr
        struct sockaddr_in client_addr;
        socklen_t length = sizeof(client_addr);

int new_fd = accept(server_socket,(struct sockaddr*)&client_addr,&length);
        if ( new_fd < 0)
        {
            printf("Server Accept Failed!\n");
            break;
        }
else{
printf("server: got connection from %s\n",inet_ntoa(client_addr.sin_addr));  
}

while(1)  
        {

mpu6500_get_data(&data); 
            show_imu(data);

length = send(new_fd, &data, sizeof(struct mpu6500_data), 0);  
            if (length < 0)  
            {  
                printf("Server send Data Failed!\n");  
                break;  
            }

}     
        
    }

close(server_socket);

while(waitpid(-1,NULL,WNOHANG) > 0); 
    return 0;
}

window上源码:

#include "StdAfx.h"
#include <winsock2.h>
#include <stdio.h>
#include <windows.h>
#include <fcntl.h>
#pragma comment(lib,"ws2_32.lib")
#include <iostream>
#define FILE_PATH  "imu_data.txt"

#define PORT 8888

using namespace std;

struct mpu6500_data 
{
   __int16  accel_raw[3];
   __int16  gyro_raw[3];
   __int16  temprature;
   double   timeStampe;
   unsigned int index;
};

int main(int argc, char **args )
{

char SendBuffer[1024];
FILE *f ;
fopen_s(&f, FILE_PATH , "wb");
if(f < 0){
printf("FILE OPEN FAILED\n");
}

WSADATA wsa;
    //初始化套接字DLL
    if(WSAStartup(MAKEWORD(2,2),&wsa)!=0)
{
        printf("套接字初始化失败!");
        exit(-1);
    }
    //创建套接字
    int sock;
    if((sock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==INVALID_SOCKET)
{
        printf("创建套接字失败!");
        exit(-1);
    }

struct sockaddr_in serverAddress;
    memset(&serverAddress,0,sizeof(sockaddr_in));
    serverAddress.sin_family=AF_INET;
    serverAddress.sin_addr.S_un.S_addr = inet_addr("192.168.7.101");
    serverAddress.sin_port = htons(PORT);
    //建立和服务器的连接
    if(connect(sock,(sockaddr*)&serverAddress,sizeof(serverAddress))==SOCKET_ERROR)
{
        printf("connet failed !");
        exit(-1);
    }
else
{
printf("connect ok !\n");

}

char RecvBuffer[4096] = {0} ;
char WriteBuffer[4096] = {0};
struct mpu6500_data *data = (struct mpu6500_data * )malloc(sizeof(struct mpu6500_data));

static unsigned int lost_num;
static unsigned int last_index, cur_index;
while (1)  
    {  
  
        //recv data from server  
int Ret = recv(sock, RecvBuffer, sizeof(struct mpu6500_data), 0);  
        if ( Ret == SOCKET_ERROR )  
        {  
           printf("recv Info Error::%d\n", GetLastError());  
           break;  
        }
else
{  
data = (struct mpu6500_data *)RecvBuffer;
last_index = cur_index;
cur_index = data->index;
if(cur_index - last_index > 1)
{
lost_num ++;
}

fprintf(f, "%d  %d  %d\n", data->accel_raw[0], data->accel_raw[1], data->accel_raw[2]);
fprintf(f, "%d  %d  %d\n", data->gyro_raw[0],  data->gyro_raw[1],  data->gyro_raw[2]); 
fprintf(f, "%d  %f  %d  %d\n", data->temprature, data->timeStampe , data->index, lost_num);

fflush(f);
}
     
}

fclose(f);

WSACleanup();

return 0;
}

*************************************************************************************

主要调试时间消耗在spi通信上,由于之前对spi通信不太熟悉,mpu6500 spi通信是采用16bit通信, 采用突发模式读取数据可以实现快速读取数据。    mpu6500最快输出频率为8000hz。

hisi3516上调试mpu6500相关推荐

  1. 发条js调试工具_小工具大帮手,利用 @open-node/antman 实现 node.js 进程线上调试,无须重启...

    @open-node/antman 窥探进程内部,让 Node.js 生产环境线上调试成为可能 解决了什么问题? 日常在开发服务端代码,很多是服务类型的,比如基于http的api,或者一些任务脚本,需 ...

  2. android调试更换模拟器,在模拟器上调试 Android 磨损

    在模拟器上调试 Android 磨损Debug Android Wear on an Emulator 06/21/2018 本文内容 这些文章介绍了如何在模拟器上调试 Xamarin 应用程序应用程 ...

  3. arm linux内核调试,kgdb在ARM开发板上调试kernel成功

    大概几个注意点: 1.公版的Linux需要打kgdb补丁的,kgdb官方那边可能不支持新版本的内核(我的是2.6.18),可以在下面的网址找到,但是ARM上调试需要打哪些补丁,不是很清楚,网上的几篇中 ...

  4. android 网络时区 错误,React native 安卓机器上调试代码报错:网络请求出错TypeError: Network request failed...

    React native 安卓机器上调试代码报错:网络请求出错TypeError: Network request failed 安卓机器 usb连接调试 报错信息 TypeError: Networ ...

  5. Android 借助Stetho在Chrome上调试Android网络、数据库、Sharedpreferences

    Android 借助Stetho在Chrome上调试Android网络.数据库.Sharedpreferences 转载请标明出处:http://blog.csdn.net/zhaoyanjun6/a ...

  6. 禅道 bug状态 open_小工具大帮手,利用 @open-node/antman 实现 node.js 进程线上调试,无须重启...

    @open-node/antman 窥探进程内部,让 Node.js 生产环境线上调试成为可能 解决了什么问题? 日常在开发服务端代码,很多是服务类型的,比如基于http的api,或者一些任务脚本,需 ...

  7. Leetcode怎么调试java代码,在Clion上调试LeetCode代码

    在Clion上调试LeetCode代码 在leetcode上做题调试起来总有些不方便,所以查阅了一些资料后,按以下配置,自我感觉效率还行,分享给大家.祝大家刷题愉快.并附上自己整理的leetcode4 ...

  8. 在龙芯上调试CoreCLR

    dotnet for mips64 的 ea 版本已经发布 https://github.com/gsvm/loongson-dotnet/releases 在龙芯上调试CoreCLR 由于lldb在 ...

  9. vs生成linux服务器程序,从Visual Studio到Linux上调试C++代码

    从Visual Studio到Linux上调试C++代码 04/30/2015 5 分钟可看完 本文内容 [原文发表时间] 2015/4/29 10:00 PM 正如您可能已经听说的那样,Visual ...

最新文章

  1. 单例模式实现方式详解
  2. 二叉树后序遍历_LeetCode算法145. 二叉树的后序遍历
  3. 【BZOJ4128】Matrix,拔山盖世的矩阵乘法+随机化
  4. 【matlab】元胞数组(由元胞数组创建元胞数组)
  5. 详解:Oracle数据库介绍 、字符、类型、语言
  6. Intel Edison学习笔记(二)—— 入门环境配置
  7. php obclean函数,php函数ob_start()、ob_end_clean()、ob_get_contents()
  8. Matlab 音频信号处理
  9. 【FinE】远期、期货、互换定价
  10. 大咖面对面 | 燕雀安知Suji之志
  11. db的中英文全称_DB是什么?解读《北京遇上西雅图》中英语文化
  12. Ubuntu18.04 安装QQ、Tim、微信与win无差异
  13. vue 之url拼接 根据选择条件动态修改url地址
  14. V-token的技术革新,引领数字化支付热潮
  15. mysql limit括号_MYSQL中LIMIT使用简介
  16. Alex - 用python来写测手速游戏
  17. Android 小数点前后字体大小不一致,EditText限制小数点前后位数的实例
  18. 爬虫实战——爬取小说《从你的全世界路过》
  19. 使用matlab处理.nii图像
  20. QBC和QBE查询方法

热门文章

  1. 数学分析:隐函数定理和反函数定理
  2. Pdfium.Net SDK增强您的功能快速生成PDF
  3. 使用百度云的图像识别
  4. uniapp实现国际化多语言切换
  5. 微型计算机的外存储器 现在普遍采用什么,当前微型计算机上大部分采用的外存储器,不包含下列哪些?1.硬盘 2.光盘 3.软盘 4.磁带。...
  6. 天线方向图的形成原理及用MATLAB画出天线方向图
  7. matlab:使用四阶龙格库塔方法求解微分方程组
  8. 免费报表XDOC从入门到精通(一)简介
  9. Python官方入门手册等你领取!
  10. express学生管理系统、前后端不分离(十一)