Hi I am creating a PWM library in c++ to use in my project. I have started working on it below is part of my code it is not complete yet. I have writing a bit by bit code and building it to find errors and I found some error so I stopped. Even though I had defined right parameters it is giving error. It should preprocess first #if and assign TCC0A with 0x80. But it skipping #if, #elif and last #else is execuing. Please help me to correct given code.
嗨,我正在用c ++创建一个PWM库,用于我的项目。我已经开始在下面开始研究它是我的代码的一部分还没有完成。我已经逐位编写代码并构建它以查找错误,我发现了一些错误,所以我停了下来。即使我已经定义了正确的参数,它也会给出错误。它应首先预处理#if并为TCC0A分配0x80。但它跳过#if,#elif和#else正在执行。请帮我纠正给定的代码。
IDE: Atmel Studio 7.0
IDE:Atmel Studio 7.0
MCU: ATmega328p
Code:
/************************************************************
PWM.h file
************************************************************/
#ifndef PWM_H_
#define PWM_H_
//PWM outputs
#define OC0A 1
#define OC0B 2
//PWM modes
#define NINV 0b10000000 //Non-inverting Mode
#define INV 0b11000000 //Inverting Mode
#include <avr/io.h>
class PWM
{
public:
void Initialize(unsigned char PWMoutputpin, unsigned char PWMmode)
{
TCCR0A = 0x00; TCCR0B = 0x00;
#if ((PWMoutputpin == OC0A) && (PWMmode == NINV))
TCCR0A |= NINV;
#elif ((PWMoutputpin == OC0A) && (PWMmode == INV))
TCCR0A |= INV;
#elif ((PWMoutputpin == OC0B) && (PWMmode == NINV))
TCCR0A |= (NINV >> 2);
#elif ((PWMoutputpin == OC0B) && (PWMmode == INV))
TCCR0A |= (INV >> 2);
#else
#error PWM::Initialize() parameters not defined properly.
#endif
}
};
#endif /* PWM_H_ */
/******************************* END **********************/
/************************************************************
main.cpp file
************************************************************/
#include <avr/io.h>
#include "PWM.h"
int main(void)
{
PWM p; //define PWM as p object
p.Initialize(OC0A,NINV); //initialize PWM with OC0A as output with non-inverting mode
return 0;
}
1 个解决方案
#1
0
As commented on already you cannot use #if
the way you are. The compiler can only make a decision once at compile time when executing the #if
statement. You are trying to use the #if
statement based on a changing parameter input, or run-time. The #if
cannot be used at run-time when your library code is being called by another function, at this point compiling has already finished.
如上所述,你不能像现在这样使用#if。编译器只能在执行#if语句时在编译时做出一次决策。您正尝试使用基于更改参数输入或运行时的#if语句。当您的库代码被另一个函数调用时,#if不能在运行时使用,此时编译已经完成。
Code Change
Your code should be changed to:
您的代码应更改为:
void Initialize(unsigned char PWMoutputpin, unsigned char PWMmode)
{
TCCR0A = 0x00; TCCR0B = 0x00;
if ((PWMoutputpin == OC0A) && (PWMmode == NINV))
TCCR0A |= NINV;
else if ((PWMoutputpin == OC0A) && (PWMmode == INV))
TCCR0A |= INV;
else if ((PWMoutputpin == OC0B) && (PWMmode == NINV))
TCCR0A |= (NINV >> 2);
else if ((PWMoutputpin == OC0B) && (PWMmode == INV))
TCCR0A |= (INV >> 2);
else
// #error PWM::Initialize() parameters not defined properly.
// Your error output message can be sent by `cout` or some
// other method like `assert()`.
}
More Code Changes
You could even simplify your code even further. Notice how if your output pin is OC0A
that the TCCR0A
value is just or
'd with the PWM mode? Same is true for OC0B
:
您甚至可以进一步简化代码。请注意,如果您的输出引脚是OC0A,TCCR0A值是否正好在PWM模式下? OC0B也是如此:
void Initialize(unsigned char PWMoutputpin, unsigned char PWMmode)
{
TCCR0A = 0x00; TCCR0B = 0x00;
if (PWMoutputpin == OC0A)
TCCR0A |= PWMmode;
else if (PWMoutputpin == OC0B)
TCCR0A |= (PWMmode >> 2);
else
// #error PWM::Initialize() parameters not defined properly.
// Your error output message can be sent by `cout` or some
// other method like `assert()`.
}
This assumes only two modes/values of NINV
and INV
will be passed in. If a user passes in another value then you'll get some weird results but you can also check for PWMmode
before the if
statements to make sure it is valid.
这假设只传入NINV和INV的两个模式/值。如果用户传入另一个值,那么你会得到一些奇怪的结果,但你也可以在if语句之前检查PWMmode以确保它是有效的。
#1
0
As commented on already you cannot use #if
the way you are. The compiler can only make a decision once at compile time when executing the #if
statement. You are trying to use the #if
statement based on a changing parameter input, or run-time. The #if
cannot be used at run-time when your library code is being called by another function, at this point compiling has already finished.
如上所述,你不能像现在这样使用#if。编译器只能在执行#if语句时在编译时做出一次决策。您正尝试使用基于更改参数输入或运行时的#if语句。当您的库代码被另一个函数调用时,#if不能在运行时使用,此时编译已经完成。
Code Change
Your code should be changed to:
您的代码应更改为:
void Initialize(unsigned char PWMoutputpin, unsigned char PWMmode)
{
TCCR0A = 0x00; TCCR0B = 0x00;
if ((PWMoutputpin == OC0A) && (PWMmode == NINV))
TCCR0A |= NINV;
else if ((PWMoutputpin == OC0A) && (PWMmode == INV))
TCCR0A |= INV;
else if ((PWMoutputpin == OC0B) && (PWMmode == NINV))
TCCR0A |= (NINV >> 2);
else if ((PWMoutputpin == OC0B) && (PWMmode == INV))
TCCR0A |= (INV >> 2);
else
// #error PWM::Initialize() parameters not defined properly.
// Your error output message can be sent by `cout` or some
// other method like `assert()`.
}
More Code Changes
You could even simplify your code even further. Notice how if your output pin is OC0A
that the TCCR0A
value is just or
'd with the PWM mode? Same is true for OC0B
:
您甚至可以进一步简化代码。请注意,如果您的输出引脚是OC0A,TCCR0A值是否正好在PWM模式下? OC0B也是如此:
void Initialize(unsigned char PWMoutputpin, unsigned char PWMmode)
{
TCCR0A = 0x00; TCCR0B = 0x00;
if (PWMoutputpin == OC0A)
TCCR0A |= PWMmode;
else if (PWMoutputpin == OC0B)
TCCR0A |= (PWMmode >> 2);
else
// #error PWM::Initialize() parameters not defined properly.
// Your error output message can be sent by `cout` or some
// other method like `assert()`.
}
This assumes only two modes/values of NINV
and INV
will be passed in. If a user passes in another value then you'll get some weird results but you can also check for PWMmode
before the if
statements to make sure it is valid.
这假设只传入NINV和INV的两个模式/值。如果用户传入另一个值,那么你会得到一些奇怪的结果,但你也可以在if语句之前检查PWMmode以确保它是有效的。