Использование 'for' l oop для присвоения значений переменным и использование имен переменных в этой функции - PullRequest
0 голосов
/ 22 января 2020

У меня есть для l oop, который получает данные от ведомого устройства i2 c. Устройство имеет 3 оси, и мне нужно прочитать старшие и младшие биты каждой оси для шести измерений, а затем объединить их в одну переменную. Я начал с создания функции для получения данных и передачи адреса ведомого и подчиненного регистра этой функции, но теперь я интегрирую второе ведомое устройство, что означает, что мне нужно будет вызвать эту функцию 12 раз, а затем в битовую комбинацию в основном или сделайте некоторый переход по ссылочному материалу в другую функцию.

Вместо этого я создал функцию, которая перебирает все регистры данных, и я хочу присвоить ее своим именам переменных в этом l oop, а затем выполнить комбинацию битов в той же функции. У меня есть массив имен переменных и указатель на эти имена, который повторяется вместе с адресом подрегистра данных.

char data_name[] = {'a', 'b', 'c', 'd', 'e', 'f'};

char *array_name_pointer[7];
array_name_pointer[i] = &data_name[i];
uint8_t sub_data_reg = 0x00;

for(i=0; i<6; i++){

    if (HAL_I2C_Mem_Read(&hi2c1, Comp_Addr , sub_data_reg, sizeof(sub_data_reg), (uint8_t*)(&array_name_pointer), sizeof(data_name[i]), HAL_MAX_DELAY) != HAL_OK){
        Error_Handler();
        printf("Could not get raw data \n\r");
    }

    printf("%c has value %d \n\r", (data_name[i]), sub_data_reg);
    sub_data_reg ++;
}

xl = a;
xh = b;
yl = c;
yh = d;
zl = e;
zh = f;

printf("xl: %d xh: %d yl: %d yh:%d \n\r", xl, xh, yl, yh);

float x_Raw = ((xh<<8)|xl);
float y_Raw = ((yh<<8)|yl);
float z_Raw = ((zh<<8)|zl);`

моя первая строка printf правильно печатает a = 0 и т. Д., Но когда я изменяю имя переменной на xl, это выдает ошибку, когда a, b, … раньше не использовалось. Я подозреваю, что это потому, что они имеют тип char, поэтому я попытался изменить их на тип int. Когда я это делал, значения xl, xh и т. Д. Всегда были 0.

Как назначить измеренные значения этим переменным? Это хорошая практика, чтобы сделать это таким образом?

Спасибо!

1 Ответ

0 голосов
/ 22 января 2020

Символьные константы 'a', 'b'. и др c. то, что вы использовали для инициализации data_name[], не имеет никакого отношения к переменным с именами a, b, et c.

Также в этом коде:

char *array_name_pointer[7];
array_name_pointer[i] = &data_name[i];

Не ясно, каково значение i на данный момент. Если i находится вне диапазона от 0 до 6, доступ к этому массиву будет вне диапазона, что приведет к неопределенному поведению .

В этом коде:

    if (HAL_I2C_Mem_Read(&hi2c1, Comp_Addr , sub_data_reg, sizeof(sub_data_reg), (uint8_t*)(&array_name_pointer), sizeof(data_name[i]), HAL_MAX_DELAY) != HAL_OK){

Массив array_name_pointer из char * используется в качестве буфера значений uint8_t. Предполагая, что указатель имеет длину 4 байта, тогда, поскольку i зацикливается от 0 до 5 включительно (завершается при i == 6), это приведет к засорению любых значений указателя, содержащихся в array_name_pointer[0] и array_name_pointer[1].

This код:

    printf("%c has value %d \n\r", (data_name[i]), sub_data_reg);
    sub_data_reg ++;

напечатает a = 0, b = 1, c = 2 и др. c. 0, 1 и 2 не являются данными, считанными из регистров I2 C. Это просто индексы считываемых регистров I2 C.

В этом коде:

xl = a;
xh = b;
yl = c;
yh = d;
zl = e;
zh = f;

Переменные a, b, et c. вероятно, никогда не были инициализированы или назначены, что приводило к предупреждениям компилятора.


Что вам, вероятно, нужно сделать, это прочитать регистры I2 C в массив uint8_t и извлечь значения из этого массив:

    uint8_t reg_vals[6];
    uint8_t sub_data_reg = 0x00;

    for (i = 0; i < 6; i++) {
        if (HAL_I2C_Mem_Read(&hi2c1, Comp_Addr , sub_data_reg, sizeof(sub_data_reg), &reg_vals[i], sizeof(reg_vals[i]), HAL_MAX_DELAY) != HAL_OK){
            Error_Handler();
            printf("Could not get raw data \n\r");
        }

        printf("%c has value %d \n\r", data_name[i], reg_vals[i]);
        sub_data_reg ++;
    }

    xl = reg_vals[0];
    xh = reg_vals[1];
    yl = reg_vals[2];
    yh = reg_vals[3];
    zl = reg_vals[4];
    zh = reg_vals[5];

Если устройство I2 C поддерживает чтение блока регистров с автоматически увеличенными адресами регистров, вы можете изменить приведенный выше код так, чтобы он вызывал HAL_I2C_Mem_Read один раз вместо 6 раз:

    uint8_t reg_vals[6];
    uint8_t sub_data_reg = 0x00;

    if (HAL_I2C_Mem_Read(&hi2c1, Comp_Addr , sub_data_reg, sizeof(sub_data_reg), &reg_vals[0], 6 * sizeof(reg_vals[0]), HAL_MAX_DELAY) != HAL_OK){
        Error_Handler();
        printf("Could not get raw data \n\r");
    }
    sub_data_reg += 6;

    for (i = 0; i < 6; i++) {
        printf("%c has value %d \n\r", data_name[i], reg_vals[i]);
    }

    xl = reg_vals[0];
    xh = reg_vals[1];
    yl = reg_vals[2];
    yh = reg_vals[3];
    zl = reg_vals[4];
    zh = reg_vals[5];
...