宏在C语言中给出了错误的值

宏在C语言中给出了错误的值,c,embedded,microcontroller,mplab,pic18,C,Embedded,Microcontroller,Mplab,Pic18,我试图在MPLAB X IDE和XC8编译器中,以16位模式使用PIC18F4321的定时器1编写一个产生1000毫秒延迟的子程序。利用此延迟切换LED。我的问题是我无法获得所需的延迟(1000毫秒)。我试着调试程序,发现使用宏计算的“count”值不正确。它给出的值为0x4000,而不是0x0F42。 我不知道宏有什么问题: #define count (((timeDelay) * 1000) / (timerPeriod) * 256) // C-program using polled

我试图在MPLAB X IDE和XC8编译器中,以16位模式使用PIC18F4321的定时器1编写一个产生1000毫秒延迟的子程序。利用此延迟切换LED。我的问题是我无法获得所需的延迟(1000毫秒)。我试着调试程序,发现使用宏计算的“count”值不正确。它给出的值为0x4000,而不是0x0F42。 我不知道宏有什么问题:

#define count (((timeDelay) * 1000) / (timerPeriod) * 256)

// C-program using polled I/O:
#include <P18F4321.h>
#define timeDelay (1000) // 1000 ms
#define Fosc (4) // 4 MHz
#define timerPeriod (1 / ((Fosc) / 4)) // us
#define count (((timeDelay) * 1000) / (timerPeriod) * 256)
#define countInit ((0xFFFF - (count)) + 1)
#define countInitHigh ((countInit & 0xFF00) >> 8)
#define countInitLow (countInit & 0x00FF)

void T0Delay(); // A subroutine that generates a delay of 1000 ms

void main()
{
    OSCCON = 0x60; // 4MHz Internal Oscillator
    TRISC = 0x00; // Port C output
    T0CON = 0x07; // 16-bit, 1:256 prescaler, internal clock
    for(;;) // loop forever
    {
        PORTCbits.RC0 = 0; // turn LED OFF
        T0Delay(); // Wait 10 seconds
        PORTCbits.RC0 = 1; // turn LED ON
        T0Delay(); // Wait 10 seconds
    }
}

void T0Delay(void)
{
    TMR0H = countInitHigh;
    TMR0L = countInitLow;
    INTCONbits.TMR0IF = 0; // clear timer overflow flag
    T0CONbits.TMR0ON = 1; // start Timer0
    while(!INTCONbits.TMR0IF); //polling, wait until timer finishes counting
    T0CONbits.TMR0ON = 0; // Stop Timer0
}
#定义计数(((时间延迟)*1000)/(时间周期)*256)
//使用轮询I/O的C程序:
#包括
#定义时间延迟(1000)//1000毫秒
#定义Fosc(4)//4 MHz
#定义timerPeriod(1/((Fosc)/4))///us
#定义计数(((时间延迟)*1000)/(时间周期)*256)
#定义countInit((0xFFFF-(count))+1)
#定义countInitHigh((countInit&0xFF00)>>8)
#定义countInitLow(countInit&0x00FF)
void T0Delay();//产生1000毫秒延迟的子程序
void main()
{
OSCCON=0x60;//4MHz内部振荡器
TRISC=0x00;//端口C输出
T0CON=0x07;//16位,1:256预分频器,内部时钟
for(;;)//永远循环
{
PORTCbits.RC0=0;//关闭LED
T0Delay();//等待10秒
PORTCbits.RC0=1;//打开LED
T0Delay();//等待10秒
}
}
无效延迟(无效)
{
TMR0H=countInitHigh;
TMR0L=countInitLow;
INTCONbits.TMR0IF=0;//清除计时器溢出标志
T0CONbits.TMR0ON=1;//开始计时器0
当(!INTCONbits.TMR0IF);//轮询时,等待计时器完成计数
T0CONbits.TMR0ON=0;//停止计时器0
}

如果在
(timerPeriod)*256周围添加括号,将得到所需的结果:

#define count (((timeDelay) * 1000) / ((timerPeriod) * 256) /*<=parentheses here*/ )

#定义计数(((timeDelay)*1000)/((timerPeriod)*256)/*如果在
(timerPeriod)*256
周围添加括号,您将得到想要的结果:

#define count (((timeDelay) * 1000) / ((timerPeriod) * 256) /*<=parentheses here*/ )

#定义计数(((timeDelay)*1000)/((timerPeriod)*256)/*最后我可以解决这个问题,非常感谢大家。问题是在宏定义中
#定义计数((timeDelay)*1000)/((timerPeriod)*256))
分子上的结果溢出超过16位。因此,解决方案是通过将
(1000)
更改为
(1000UL)
来使用32位算术。运行的最终代码如下所示:

// C-program using polled I/O:
#include <P18F4321.h>
#define timeDelay (1000UL) // 1000 ms
#define Fosc (4) // 4 MHz
#define timerPeriod (1 / ((Fosc) / 4)) // us  
#define count (((timeDelay) * 1000UL) / ((timerPeriod) * 256))
#define countInit ((0xFFFF - (count)) + 1)
#define countInitHigh ((countInit & 0xFF00) >> 8)
#define countInitLow (countInit & 0x00FF)

void T0Delay(); // A subroutine that generates a delay of 1000 ms

void main()
{
    OSCCON = 0x60; // 4MHz Internal Oscillator
    TRISC = 0x00; // Port C output
    T0CON = 0x07; // 16-bit, 1:256 prescaler, internal clock
    for(;;) // loop forever
    {
        PORTCbits.RC0 = 0; // turn LED OFF
        T0Delay(); // Wait 10 seconds
        PORTCbits.RC0 = 1; // turn LED ON
        T0Delay(); // Wait 10 seconds
    }
}

void T0Delay(void)
{
    TMR0H = countInitHigh;
    TMR0L = countInitLow;
    INTCONbits.TMR0IF = 0; // clear timer overflow flag
    T0CONbits.TMR0ON = 1; // start Timer0
    while(!INTCONbits.TMR0IF); //polling, wait until timer finishes counting
    T0CONbits.TMR0ON = 0; // Stop Timer0
}
//使用轮询I/O的C程序:
#包括
#定义时间延迟(1000UL)//1000ms
#定义Fosc(4)//4 MHz
#定义timerPeriod(1/((Fosc)/4))///us
#定义计数(((时间延迟)*1000UL)/((时间周期)*256))
#定义countInit((0xFFFF-(count))+1)
#定义countInitHigh((countInit&0xFF00)>>8)
#定义countInitLow(countInit&0x00FF)
void T0Delay();//生成1000毫秒延迟的子例程
void main()
{
OSCCON=0x60;//4MHz内部振荡器
TRISC=0x00;//端口C输出
T0CON=0x07;//16位,1:256预分频器,内部时钟
for(;;)//永远循环
{
PORTCbits.RC0=0;//关闭LED
T0Delay();//等待10秒
PORTCbits.RC0=1;//打开LED
T0Delay();//等待10秒
}
}
无效延迟(无效)
{
TMR0H=countInitHigh;
TMR0L=countInitLow;
INTCONbits.TMR0IF=0;//清除计时器溢出标志
T0CONbits.TMR0ON=1;//开始计时器0
当(!INTCONbits.TMR0IF);//轮询时,等待计时器完成计数
T0CONbits.TMR0ON=0;//停止计时器0
}

最后我可以解决这个问题了,非常感谢各位。问题是在宏定义中,定义计数(((timeDelay)*1000)/((timerPeriod)*256))
分子的结果溢出超过了16位。所以解决方法是使用32位算法,将
(1000)
更改为
(1000UL)
。运行的最终代码将按如下方式更正它:

// C-program using polled I/O:
#include <P18F4321.h>
#define timeDelay (1000UL) // 1000 ms
#define Fosc (4) // 4 MHz
#define timerPeriod (1 / ((Fosc) / 4)) // us  
#define count (((timeDelay) * 1000UL) / ((timerPeriod) * 256))
#define countInit ((0xFFFF - (count)) + 1)
#define countInitHigh ((countInit & 0xFF00) >> 8)
#define countInitLow (countInit & 0x00FF)

void T0Delay(); // A subroutine that generates a delay of 1000 ms

void main()
{
    OSCCON = 0x60; // 4MHz Internal Oscillator
    TRISC = 0x00; // Port C output
    T0CON = 0x07; // 16-bit, 1:256 prescaler, internal clock
    for(;;) // loop forever
    {
        PORTCbits.RC0 = 0; // turn LED OFF
        T0Delay(); // Wait 10 seconds
        PORTCbits.RC0 = 1; // turn LED ON
        T0Delay(); // Wait 10 seconds
    }
}

void T0Delay(void)
{
    TMR0H = countInitHigh;
    TMR0L = countInitLow;
    INTCONbits.TMR0IF = 0; // clear timer overflow flag
    T0CONbits.TMR0ON = 1; // start Timer0
    while(!INTCONbits.TMR0IF); //polling, wait until timer finishes counting
    T0CONbits.TMR0ON = 0; // Stop Timer0
}
//使用轮询I/O的C程序:
#包括
#定义时间延迟(1000UL)//1000ms
#定义Fosc(4)//4 MHz
#定义timerPeriod(1/((Fosc)/4))///us
#定义计数(((时间延迟)*1000UL)/((时间周期)*256))
#定义countInit((0xFFFF-(count))+1)
#定义countInitHigh((countInit&0xFF00)>>8)
#定义countInitLow(countInit&0x00FF)
void T0Delay();//生成1000毫秒延迟的子例程
void main()
{
OSCCON=0x60;//4MHz内部振荡器
TRISC=0x00;//端口C输出
T0CON=0x07;//16位,1:256预分频器,内部时钟
for(;;)//永远循环
{
PORTCbits.RC0=0;//关闭LED
T0Delay();//等待10秒
PORTCbits.RC0=1;//打开LED
T0Delay();//等待10秒
}
}
无效延迟(无效)
{
TMR0H=countInitHigh;
TMR0L=countInitLow;
INTCONbits.TMR0IF=0;//清除计时器溢出标志
T0CONbits.TMR0ON=1;//开始计时器0
当(!INTCONbits.TMR0IF);//轮询时,等待计时器完成计数
T0CONbits.TMR0ON=0;//停止计时器0
}

时间周期
真的应该扩展到
(1/((4))/4))
,即1?@zwol是的,这是正确的如果您在16位整数系统上,
时间延迟*1000
导致未定义behaviour@M.M是的,我使用的是16位系统。但我如何解决这个问题???一种方法是使用32位算术(将
1000
更改为
UINT32_C(1000)
1000UL
)是
timeperiod
真的应该扩展到
(1/((4))/4))
,即1?@zwol是正确的如果您使用的是16位整数系统,
timeDelay*1000
导致未定义behaviour@M.M是的,我使用的是16位系统。但是如何解决这个问题呢???一种方法是使用32位算术(将
1000
更改为
UINT32_C(1000)
1000UL
)我刚刚尝试了你的建议,但仍然给出了错误的值!@ SAMILFASSAK在重新定义后的值是0xF42。这里的证据是:是的,我在在线编译器上尝试了它给出了正确的值(0x0f42)。它也给出了Visual C++ 2008的正确值。但是当我尝试COD时