如何旋转数组以便我始终获得最后两个元素,无论我指向哪个索引? C代码
如果我说我正在计算需要插入多少个值才能完全填充数组,如何找到数组中两个先前值之间的差异?假设我们有一个包含 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
时,我想在STM32
的DMA
数组中获取差异。 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.
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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
myArray
是一个循环数组。您想要包装索引,这是我们可以使用%
运算符获得的行为:输出
如您所见,
i
始终先于i1
,而i1
本身又先于 <代码>i0。请注意,运行上述代码的输出与您的输出不匹配,因为您的输出没有表现出您所描述的行为。
myArray
is a cyclic array. You want wrapping indexing, which is behavior we can get using%
operator:Output
As you can see,
i
always precedesi1
which itself precedesi0
.Note that output from running the code above won't match yours, because yours doesn't exhibit the behavior you're describing.