如何旋转数组以便我始终获得最后两个元素,无论我指向哪个索引? C代码

发布于 2025-01-16 10:19:13 字数 3907 浏览 2 评论 0原文

如果我说我正在计算需要插入多少个值才能完全填充数组,如何找到数组中两个先前值之间的差异?假设我们有一个包含 5 元素的数组。如果我指定索引0,那么我需要采用index 4 - index 3,因为它们是前面的两个元素。如果我指定索引1,那么我需要采用索引0 - 索引4。如果我指定索引4,那么我需要再次获取index 4 - index 3

我已经为此编写了一个 C 代码,我的问题是......是否有更好的方法来最小化这个 C 代码?

#include <stdio.h>
#include <stdint.h>

#define LEN 10

uint16_t myArray[LEN] = {4,1,6,8,3,4,6,8,0,6};

int main()
{
    
    for(int i = LEN; i >= 0; i--){
        int i0, i1;
        int left = i;
        if(LEN == left){
            i0 = LEN - 2;
            i1 = LEN - 1;
        }else if(0 == left){
            i0 = LEN - 2;
            i1 = LEN - 1;
        }else if(1 == LEN - left){
            i0 = LEN - 1;
            i1 = 0;
        }else{
            i0 = LEN - left - 2;
            i1 = LEN - left - 1;
        }
        printf("i0 = %i, i1 = %i. Difference = %i\n", i0, i1, myArray[i1] - myArray[i0]);
    }

    return 0;
}

模拟: https://onlinegdb.com/QuIt-vRLR

输出:

i0 = 8, i1 = 9. Difference = 6
i0 = 9, i1 = 0. Difference = -2
i0 = 0, i1 = 1. Difference = -3
i0 = 1, i1 = 2. Difference = 5
i0 = 2, i1 = 3. Difference = 2
i0 = 3, i1 = 4. Difference = -5
i0 = 4, i1 = 5. Difference = 1
i0 = 5, i1 = 6. Difference = 2
i0 = 6, i1 = 7. Difference = 2
i0 = 7, i1 = 8. Difference = -8
i0 = 8, i1 = 9. Difference = 6

我问的原因是因为当我使用Input Capture时,我想在STM32DMA数组中获取差异。 DMA 数组中的前两个值包含计时器的计数器周期,我想知道它们之间的差异。

输入图片此处描述

举例说明我现在的做法。但由于索引错误,它对我来说不能完美工作。

#define LENGTH_ARRAY 5
static uint16_t input_capture0[LENGTH_ARRAY] = {0};
static uint16_t input_capture1[LENGTH_ARRAY] = {0};
static TIM_HandleTypeDef* handler_tim17;
static TIM_HandleTypeDef* handler_tim16;

void STM32_PLC_Input_Capture(TIM_HandleTypeDef* htim17, TIM_HandleTypeDef* htim16) {
    /*
     * Input capture for measuring frequency
     * For TIM17 and TIM16
     * Timer clock: 48 Mhz
     * Prescaler: 4799
     * Counter: 65535 (0xffff)
     * Update frequency: 0.1526 Hz (1/0.1526 = 6.5535 seconds)
     * Example: For every second, it will count 10000
     * Lowest frequency measurement: 1/(0xFFFF*0.0001) = 0.1526 Hz
     * Highest frequency measurement: 1/(1*0.0001) = 10000 Hz
     */
    if(HAL_TIM_IC_Start_DMA(htim16, TIM_CHANNEL_1, (uint32_t*)input_capture1, LENGTH_ARRAY) != HAL_OK)
        Error_Handler();
    if(HAL_TIM_IC_Start_DMA(htim17, TIM_CHANNEL_1, (uint32_t*)input_capture0, LENGTH_ARRAY) != HAL_OK)
        Error_Handler();

    /* Save */
    handler_tim17 = htim17;
    handler_tim16 = htim16;

}

static uint16_t compute_period(uint16_t input_capture[], uint8_t elements_left_to_write_in_array) {
    uint8_t index0, index1;
    switch(elements_left_to_write_in_array){
    case 5:
        /* When the whole array has been filled by DMA and we stand at index 0, then we need to use the 2 past indexes */
        index0 = 3;
        index1 = 4;
    case 4:
        index0 = 4;
        index1 = 0;
    case 3:
        index0 = 0;
        index1 = 1;
    case 2:
        index0 = 1;
        index1 = 2;
    case 1:
        index0 = 2;
        index1 = 3;
    default:
        index0 = 0;
        index1 = 1;
        break;
    }
    return input_capture[index1] - input_capture[index0];
}


uint16_t STM32_PLC_Input_Capture_Get_Raw(uint8_t i){
    if(i == 0)
        return compute_period((uint16_t*)input_capture0, (uint8_t)handler_tim17->hdma[TIM_DMA_ID_CC1]->Instance->CNDTR);
    else
        return compute_period((uint16_t*)input_capture1, (uint8_t)handler_tim16->hdma[TIM_DMA_ID_CC1]->Instance->CNDTR);
}

How can I find a difference between two previous values inside an array, if I say that I'm counting how many values do I need to insert to full fill the array? Assume that we have an array with 5 elements. If I specify index 0, then I need to take index 4 - index 3 because they are the two previous elements. If I specify index 1, then I need to take index 0 - index 4. And if I specify index 4, then I need to take index 4 - index 3 again.

I have written a C code for that and my question is...if there are a better way to minimize this C code?

#include <stdio.h>
#include <stdint.h>

#define LEN 10

uint16_t myArray[LEN] = {4,1,6,8,3,4,6,8,0,6};

int main()
{
    
    for(int i = LEN; i >= 0; i--){
        int i0, i1;
        int left = i;
        if(LEN == left){
            i0 = LEN - 2;
            i1 = LEN - 1;
        }else if(0 == left){
            i0 = LEN - 2;
            i1 = LEN - 1;
        }else if(1 == LEN - left){
            i0 = LEN - 1;
            i1 = 0;
        }else{
            i0 = LEN - left - 2;
            i1 = LEN - left - 1;
        }
        printf("i0 = %i, i1 = %i. Difference = %i\n", i0, i1, myArray[i1] - myArray[i0]);
    }

    return 0;
}

Simulate: https://onlinegdb.com/QuIt-vRLR

Output:

i0 = 8, i1 = 9. Difference = 6
i0 = 9, i1 = 0. Difference = -2
i0 = 0, i1 = 1. Difference = -3
i0 = 1, i1 = 2. Difference = 5
i0 = 2, i1 = 3. Difference = 2
i0 = 3, i1 = 4. Difference = -5
i0 = 4, i1 = 5. Difference = 1
i0 = 5, i1 = 6. Difference = 2
i0 = 6, i1 = 7. Difference = 2
i0 = 7, i1 = 8. Difference = -8
i0 = 8, i1 = 9. Difference = 6

The reason why I'm asking is because I want to take the difference in a DMA array for STM32 when I'm using Input Capture. The two previous values in the DMA array contains counter periods of a timer, and I want to have the difference between them.

enter image description here

Example how I'm doing now. But it won't work perfectly for me due to wrong indexing.

#define LENGTH_ARRAY 5
static uint16_t input_capture0[LENGTH_ARRAY] = {0};
static uint16_t input_capture1[LENGTH_ARRAY] = {0};
static TIM_HandleTypeDef* handler_tim17;
static TIM_HandleTypeDef* handler_tim16;

void STM32_PLC_Input_Capture(TIM_HandleTypeDef* htim17, TIM_HandleTypeDef* htim16) {
    /*
     * Input capture for measuring frequency
     * For TIM17 and TIM16
     * Timer clock: 48 Mhz
     * Prescaler: 4799
     * Counter: 65535 (0xffff)
     * Update frequency: 0.1526 Hz (1/0.1526 = 6.5535 seconds)
     * Example: For every second, it will count 10000
     * Lowest frequency measurement: 1/(0xFFFF*0.0001) = 0.1526 Hz
     * Highest frequency measurement: 1/(1*0.0001) = 10000 Hz
     */
    if(HAL_TIM_IC_Start_DMA(htim16, TIM_CHANNEL_1, (uint32_t*)input_capture1, LENGTH_ARRAY) != HAL_OK)
        Error_Handler();
    if(HAL_TIM_IC_Start_DMA(htim17, TIM_CHANNEL_1, (uint32_t*)input_capture0, LENGTH_ARRAY) != HAL_OK)
        Error_Handler();

    /* Save */
    handler_tim17 = htim17;
    handler_tim16 = htim16;

}

static uint16_t compute_period(uint16_t input_capture[], uint8_t elements_left_to_write_in_array) {
    uint8_t index0, index1;
    switch(elements_left_to_write_in_array){
    case 5:
        /* When the whole array has been filled by DMA and we stand at index 0, then we need to use the 2 past indexes */
        index0 = 3;
        index1 = 4;
    case 4:
        index0 = 4;
        index1 = 0;
    case 3:
        index0 = 0;
        index1 = 1;
    case 2:
        index0 = 1;
        index1 = 2;
    case 1:
        index0 = 2;
        index1 = 3;
    default:
        index0 = 0;
        index1 = 1;
        break;
    }
    return input_capture[index1] - input_capture[index0];
}


uint16_t STM32_PLC_Input_Capture_Get_Raw(uint8_t i){
    if(i == 0)
        return compute_period((uint16_t*)input_capture0, (uint8_t)handler_tim17->hdma[TIM_DMA_ID_CC1]->Instance->CNDTR);
    else
        return compute_period((uint16_t*)input_capture1, (uint8_t)handler_tim16->hdma[TIM_DMA_ID_CC1]->Instance->CNDTR);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

一杯敬自由 2025-01-23 10:19:13

myArray 是一个循环数组。您想要包装索引,这是我们可以使用 % 运算符获得的行为:

#include <stdio.h>
#include <stdint.h>

#define LEN 10

uint16_t myArray[LEN] = {4,1,6,8,3,4,6,8,0,6};

int main()
{

    for(int i = LEN; i >= 0; i--){
        int i0 = ((i + LEN) - 2) % LEN;
        int i1 = ((i + LEN) - 1) % LEN;

        printf("i0 = %i, i1 = %i, i = %i Difference = %i\n", 
                i0, i1, i, myArray[i1] - myArray[i0]);
    }

    return 0;
}

输出

i0 = 8, i1 = 9, i = 10 Difference = 6
i0 = 7, i1 = 8, i = 9 Difference = -8
i0 = 6, i1 = 7, i = 8 Difference = 2
i0 = 5, i1 = 6, i = 7 Difference = 2
i0 = 4, i1 = 5, i = 6 Difference = 1
i0 = 3, i1 = 4, i = 5 Difference = -5
i0 = 2, i1 = 3, i = 4 Difference = 2
i0 = 1, i1 = 2, i = 3 Difference = 5
i0 = 0, i1 = 1, i = 2 Difference = -3
i0 = 9, i1 = 0, i = 1 Difference = -2
i0 = 8, i1 = 9, i = 0 Difference = 6

如您所见,i 始终先于 i1 ,而 i1 本身又先于 <代码>i0。

请注意,运行上述代码的输出与您的输出不匹配,因为您的输出没有表现出您所描述的行为。

myArray is a cyclic array. You want wrapping indexing, which is behavior we can get using % operator:

#include <stdio.h>
#include <stdint.h>

#define LEN 10

uint16_t myArray[LEN] = {4,1,6,8,3,4,6,8,0,6};

int main()
{

    for(int i = LEN; i >= 0; i--){
        int i0 = ((i + LEN) - 2) % LEN;
        int i1 = ((i + LEN) - 1) % LEN;

        printf("i0 = %i, i1 = %i, i = %i Difference = %i\n", 
                i0, i1, i, myArray[i1] - myArray[i0]);
    }

    return 0;
}

Output

i0 = 8, i1 = 9, i = 10 Difference = 6
i0 = 7, i1 = 8, i = 9 Difference = -8
i0 = 6, i1 = 7, i = 8 Difference = 2
i0 = 5, i1 = 6, i = 7 Difference = 2
i0 = 4, i1 = 5, i = 6 Difference = 1
i0 = 3, i1 = 4, i = 5 Difference = -5
i0 = 2, i1 = 3, i = 4 Difference = 2
i0 = 1, i1 = 2, i = 3 Difference = 5
i0 = 0, i1 = 1, i = 2 Difference = -3
i0 = 9, i1 = 0, i = 1 Difference = -2
i0 = 8, i1 = 9, i = 0 Difference = 6

As you can see, i always precedes i1 which itself precedes i0.

Note that output from running the code above won't match yours, because yours doesn't exhibit the behavior you're describing.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文