我正在尝试使用Arduino MEGA 2560和硬件中断读取PWM信号的占空比。我很清楚在定义为类成员函数的ISR中使用attachInterrupt函数会出现的问题,但我找到了解决问题的方法。我的代码部分正常工作,但有两个问题:
我的问题是:在我的“面向对象”实现和常规的“功能性”实现之间,有什么隐藏的差异是我看不到的?我在下面发布了两个实现的代码。
代码一:“功能性”实现
#define PWM_CHANNEL 2
volatile int pwmDutyCycle_throttle = 0;
void setup() {
Serial.begin(115200); // Serial to PC
attachInterrupt(digitalPinToInterrupt(PWM_CHANNEL), decodePwm_1, CHANGE);
}
void loop() {
int localValue;
noInterrupts();
localValue = pwmDutyCycle_throttle;
interrupts();
Serial.println(pwmDutyCycle_throttle);
}
void decodePwm_1() {
static unsigned long riseTime = micros(); // initialize riseTime
if (digitalRead(PWM_CHANNEL_1) == 1) { // the signal has risen
riseTime = micros(); // save the rise time
}
else { // the signal has fallen
pwmDutyCycle_throttle = micros() - riseTime; // compute the duration of the high pulse
}
}
代码2:“面向对象”实现:
#define PWM_CHANNEL 2
typedef byte pin_t;
typedef uint16_t pulse_t;
class pwm_reader_attachable_t {
uint8_t pin; /**< physical pin on the board */
volatile uint16_t pulse; /**< duration of the high edge (the pwm reading) */
uint16_t pulse_real; /**< a stabilized version of the reading (for fast varying signals) */
uint16_t edge_time; /**< timing of the last high edge */
uint8_t counter; /**< counter (actually used for the encoder) */
uint8_t read; /**< Last reading of the pin, for triggering pulse width evaluation */
public:
void setup(pin_t pin, void (*ISR_callback)(void), int value);
void handleInterrupt(void);
inline pulse_t get_pulse() {
pulse_t x;
noInterrupts();
x = pulse;
interrupts();
return x;
};
pwm_reader_attachable_t(void) {
counter = 0;
pulse = 0;
pulse_real = 0;
edge_time = 0;
read = 0;
}
private:
void(*ISR_callback)();
};
void pwm_reader_attachable_t::setup(pin_t pin, void (*ISR_callback)(void), int value)
{
//pinMode(pin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(pin), ISR_callback, value);
interrupts();
}
inline void pwm_reader_attachable_t::handleInterrupt(void)
{
static unsigned long riseTime = micros(); // initialize riseTime
if (digitalRead(pin) == 1) { // the signal has risen
riseTime = micros(); // save the rise time
}
else { // the signal has fallen
pulse = micros() - riseTime; // compute the duration of the high pulse
}
}
pwm_reader_attachable_t* motor;
pulse_t DC = 0;
void setup()
{
Serial.begin(115200);
motor = new pwm_reader_attachable_t();
motor->setup(PWM_CHANNEL, [] {motor->handleInterrupt();}, CHANGE);
//motor->setup(PWM_CHANNEL, motor->handleInterrupt, CHANGE);
}
void loop()
{
DC = motor->get_pulse();
Serial.println(DC);
}
谢谢!
在函数实现中,调用AttachInterrupt()
时,将函数DecodePWM_1()
的地址作为函数指针传递。这是有意义的,并暗示在需要时将调用该函数。
在面向对象的版本中,您调用attachInterrupt()
,传递一个未初始化的变量,即私有变量ISR_Callback
。您可能希望该变量指向处理程序函数handleinterrupt()
。初始化它的最佳位置是pwm_reader_attachable_t
的构造函数。
你好想问一下,刚刚接触react,之前写的js在html上可以使用,但是换到这里显示document is not defined,如果在document.getElementById不能用的情况下还有什么办法能够通过id获取到元素?或者应该怎么修改才能正常获取呢?写的屎山如下,请大佬指教qaq 1
我有两个文件,一个是'a.js'在压缩文件夹中,另一个是b.js在压缩文件夹中的一个文件夹b中,我正在使用Express的路由。我是一个初学者,不知道如何解决这个错误,它意味着什么。我想在a.js中使用b文件。A.JS 这是B.JS 这是错误 This.Stack.Push(层);^ TypeError:无法读取function.route(C:\users\palwasha\downloads\
我面临这个问题,当我假设通过n并找到从范围[0,2次方n-1]中选择x的方法的数目时,使得x^(x+1)=(x+2)^(x+3)其中^表示异或运算符。由于有效x的数目可能很大,因此输出它的模为10^9+7。
在基类中,我有一个函数,它接受一个字符串文件名,构造一个功能集,并将其工作延迟到一个纯虚拟函数。 在子类中,我实现了这个虚拟函数。 在中,我有一个子类的实例,并使用一个文件名调用。我以为这将调用基类的非虚拟函数,该函数接受字符串参数,但这并不能编译。错误是: 掠夺。cpp:在函数“int main()”中: 掠夺。cpp:33:48:错误:调用“SubClass::GetDetections(co
在我的Android Studio项目中,我在gradle中定义了代理设置。与Git repo同步的属性文件。只要在那里定义了代理密码,我就需要将其移动到本地。属性文件。我想实现这样的smth: 在gradle.properties: 在当地。特性: 我该怎么做?
我面临这个问题,当我假设通过n并找到从范围[0,2次方n-1]中选择x的方法的数目时,使得x^(x+1)=(x+2)^(x+3)其中^表示异或运算符。由于有效x的数目可能很大,因此输出它的模为10^9+7。