gpt4 book ai didi

c - C语言求模运算

转载 作者:行者123 更新时间:2023-11-30 20:59:42 26 4
gpt4 key购买 nike

我在 C 语言中的模运算方面遇到问题。我已经定义了全局变量 uint16_t Tmr_1ms ,它是每 1 毫秒递增。我想在中使用这个变量一个软件振荡器实现,在下面实现给定函数

 void OSC(uint32_t output, Osc_t *p){

float act_time;

if(p->start){

taskENTER_CRITICAL();
act_time = Tmr_1ms;
taskEXIT_CRITICAL();


if(p->init){

SetLogicSignal(output);
p->start_time = act_time;
p->delta = ((p->period)/(2*p->T));
p->init = FALSE;

}

if(((uint16_t)act_time - (uint16_t)(p->start_time)) >= ((uint16_t)(p->delta))){

NegLogicSignal(output); // my defined function for negation of a bit variable
p->start_time = act_time;

}

}else{

ClearLogicSignal(output);
p->init = TRUE;

}

}

振荡器状态存储在以下给定结构的实例中

    // oscillator state (oscillator with fixed duty cycle)
typedef struct{
float period; // period of the oscillations (ms)
float T; // function execution period (ms)
BOOL start; // oscillator start signal (start==TRUE, stop==FALSE)
BOOL init; // initiate the oscillator state
float delta; // time after which expiration the oscillator output is negated
float start_time; // captured Tmr_1ms value
}Osc_t;

这是代码

// oscillator instance init
Test_Oscillator_state.T = 20;
Test_Oscillator_state.period = 1000;
Test_Oscillator_state.init = TRUE;

// calling the function
Test_Oscillator_state.start = TRUE;
OSC(LTestBlink, &Test_Oscillator_state);

问题出在下面的代码

    if(((uint16_t)act_time - (uint16_t)(p->start_time)) >= ((uint16_t)(p->delta))){

NegLogicSignal(output);
p->start_time = act_time;

}

输出取反仅在 Tmr_1ms 溢出之前起作用。我不明白为什么。请问有人可以给我任何指导吗?提前致谢。

最佳答案

当 Action 时间结束时,从 Action 时间中减去开始时间是有问题的。您正在用较小的无符号数减去较大的无符号数,这不太可能给您想要的结果。如果这些是带符号的数字,则差异将为负;在无符号数中,您将得到与负数等价的东西,这将是一个很大的无符号数(但显然仍然小于您之前保存的起始值)。

您需要检测并处理环绕。要么有另一个寄存器类型值来指示环绕(在读取时清除,或者在读取时清除),要么有一个计算增量的函数,注意起始值比增量更接近最大值。然后计算差异的函数会计算出正确的差异。

由于您已将值放入 float 变量中,因此您不能将其转换为 unsigned int,然后在环绕后您将得到一个负数,清楚地指示环绕并允许您计算正确的区别。

看看this discussion of unsigned subtraction ,有进一步的解释和建议。

评论中建议的最佳解决方案old_timer(old_timer,如果您想将其作为答案并接受它,我会将其从我的答案中删除)。将 16 位无符号值提升为 32 位无符号值(可以使用原始代码中的 float ,但不需要或不推荐)。使用 32 位(或浮点)值进行减法。 减法之后,将位掩码回 16 位(按位与 0xFFFF 或分配给无符号 16 位变量)。然后减法就起作用了,因为算术是以 32 位(或 float )完成的,不会回绕。 “模”效应是通过屏蔽较高位来获得的。

关于c - C语言求模运算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46036680/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com