c - C语言中一个宏给出了错误的值

标签 c embedded microcontroller mplab pic18

我正在尝试在带有 XC8 编译器的 MPLAB X IDE 中以 16 位模式使用 PIC18F4321 的 Timer1 编写一个产生 1000 毫秒延迟的子程序。此延迟被用来切换 LED。我的问题是我无法获得所需的延迟(1000 毫秒)。我试图调试我观察到使用宏计算的“计数”值不正确的程序。它给出的值为 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
}

最佳答案

终于解决了这个问题,非常感谢你们。问题是在宏定义 #define count (((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
}

关于c - C语言中一个宏给出了错误的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50090403/

相关文章:

c - 在什么情况下 C 需要指向指针的指针?

c - glUseProgramObjectARB 无效操作错误

c - Linux驱动模块编译问题

c - 将指针写入 GPIO 输出引脚的地址

将整数转换为无符号长整型

c - 基本的 Makefile 和头文件依赖

c++ - 宏在 C 中编译,但在 C++ 中不编译(MSP432 BSL 调用)

math - `atan` 函数在定点的逼近

c - PIC单片机如何添加两个超声波传感器

c - 如何用c语言调用pic18F4550中的方法(编译器)