2013-03-03 3 views
0

Я работаю над чтением данных с гироскопа, и я получаю данные обратно в порядке, но значения не так ожидаются. Я имею в виду, что это из-за ошибки в моем кодирования после поиска вокруг решения я придумал пост HERE, который гласит:16-битное значение в комплименте 2, запутанное

Убедитесь, что вы правильно читать выходные регистры, данные 16 -битовое значение в дополнении до 2 (т.е. MSB является знаковым, то 15 бит для значения)

Это очень запутанное для меня, и я не уверен, если мое кодирования считывания значения, как его предполагается , Я использую библиотеку I2C wiringPi, чтобы преобразовать существующий код для Arduino для запуска на Малиновой Pi. У меня есть мой код ниже. Я надеюсь, кто-то скажет мне, если они видят правильную попытку прочитать 16-битное значение в комплименте 2. Внутри функции getGyroValues это единственное место, где я мог видеть это. Правильно ли мой код правильно считывает значения?

#include <stdio.h> 
#include <string.h> 
#include <errno.h> 
#include <unistd.h> 
#include <stdlib.h> 
#include <stdint.h> 
#include <time.h> 

#include <wiringPi.h> 
#include <wiringPiI2C.h> 

#define CTRL_REG1 0x20 
#define CTRL_REG2 0x21 
#define CTRL_REG3 0x22 
#define CTRL_REG4 0x23 


int fd; 
int x = 0; 
int y = 0; 
int z = 0; 
int main(){ 



    fd = wiringPiI2CSetup(0x69); // I2C address of gyro 
    wiringPiI2CWriteReg8(fd, CTRL_REG1, 0x1F); //Turn on all axes, disable power down 
    wiringPiI2CWriteReg8(fd, CTRL_REG3, 0x08); //Enable control ready signal 
    wiringPiI2CWriteReg8(fd, CTRL_REG4, 0x80); // Set scale (500 deg/sec) 
    delay(100);     // Wait to synchronize 

void getGyroValues(){ 
    int MSB, LSB; 

    LSB = wiringPiI2CReadReg16(fd, 0x28); 
    MSB = wiringPiI2CReadReg16(fd, 0x29); 
    x = ((MSB << 8) | LSB); 

    MSB = wiringPiI2CReadReg16(fd, 0x2B); 
    LSB = wiringPiI2CReadReg16(fd, 0x2A); 
    y = ((MSB << 8) | LSB); 

    MSB = wiringPiI2CReadReg16(fd, 0x2D); 
    LSB = wiringPiI2CReadReg16(fd, 0x2C); 
    z = ((MSB << 8) | LSB); 
} 

    for (int i=0;i<10;i++){ 
    getGyroValues(); 
    // In following Divinding by 114 reduces noise 
    printf("Value of X is: %d\n", x/114); 
    printf("Value of Y is: %d\n", y/114); 
    printf("Value of Z is: %d\n", z/114); 
    int t = wiringPiI2CReadReg8(fd, 0x26); 
    t = (t*1.8)+32;//convert Celcius to Fareinheit 
    int a = wiringPiI2CReadReg16(fd,0x2B); 
    int b = wiringPiI2CReadReg16(fd,0x2A); 
    printf("Y_L equals: %d\n", a); 
    printf("Y_H equals: %d\n", b); 
    int c = wiringPiI2CReadReg16(fd,0x28); 
    int d = wiringPiI2CReadReg16(fd,0x29); 
    printf("X_L equals: %d\n", c); 
    printf("X_H equals: %d\n", d); 
    int e = wiringPiI2CReadReg16(fd,0x2C); 
    int f = wiringPiI2CReadReg16(fd,0x2D); 
    printf("Z_L equals: %d\n", e); 
    printf("Z_H equals: %d\n", f); 

    printf("The temperature is: %d\n\n\n", t); 
    delay(500); 
} 
}; 
+2

В чем вопрос? –

+1

Убедитесь, что вы знаете, что такое «комплимент». –

+0

Мне интересно, правильно ли код читает значения или нет? – Yamaha32088

ответ

1

Вот как вы можете легко объединить наиболее и наименее значимые байты, представляющие половины комплемента 16-разрядного целого числа к 2-в междунар: метод

int Bytes2Short(unsigned char msb, unsigned char lsb) 
{ 
    long t = msb * 0x100L + lsb; 
    if (t >= 32768) 
    t -= 65536; 
    return (int)t; 
} 
1

Используйте Алексея Фрунзе для ясности, но вот версия без тестов (которые могут скомпилировать более быстрый встроенный код в некоторых ситуациях). Этот шаблон работает и для других размеров беззнаковых битовых шаблонов, например, для обработки 12-разрядных целых чисел, используйте 0x0800, для 17-разрядных целых чисел используйте 0x10000 и так далее.

Я связал его с небольшим водителем main, чтобы показать выходы.

#include <stdio.h> 

int comb(unsigned char msb, unsigned char lsb) { 
     long t = ((long)msb << 8) | lsb; 
     if (t >= 32768) 
       t -= 65536; 
     return t; 
} 

int comb2(unsigned char msb, unsigned char lsb) { 
     unsigned long t = ((unsigned long)msb << 8) | lsb; 
     t ^= 0x8000UL; 
     return (int)((long)t - (long)0x8000); 
} 

int main(void) { 
     printf("%6s %6s\n", "comb", "comb2"); 
     printf("%6d %6d\n", comb(0, 0), comb2(0, 0)); 
     printf("%6d %6d\n", comb(127, 255), comb2(127, 255)); 
     printf("%6d %6d\n", comb(128, 0), comb2(128, 0)); 
     printf("%6d %6d\n", comb(255, 255), comb2(255, 255)); 
     return 0; 
} 
Смежные вопросы