0

我不断收到错误“无法解析标识符_delay”。我使用的是 pic16f1829、MPLAB X IDE v3.26 和编译器 XC8 v1.41。

我只是想让 LCD 显示一些参数。奇怪的是,我在另一台计算机上使用了完全相同的代码,上传了它,然后它就起作用了。但是由于我改变了计算机(并且可能有一些不同的编译器版本等)它不再工作了。通常 _delay 应该是 XC8 的内置功能,所以我不知道他为什么抱怨。我也不确定这就是 LCD 不工作的原因,但这是我得到的唯一错误。

#include <stdio.h>
#include <stdlib.h>
#include <xc.h>
#include <htc.h>
#include "constants.h"
#include "LCD_code.h"
#include "ShiftRegister_code.h"
#include "ADC_code.h"
#include "Comparator_code.h"


// CONFIG1
#pragma config FOSC = HS    // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin)
#pragma config WDTE = OFF        // Watchdog Timer Enable (WDT enabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable (PWRT disabled)
#pragma config MCLRE = ON       // MCLR Pin Function Select (MCLR/VPP pin function is MCLR)
#pragma config CP = OFF         // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config CPD = OFF        // Data Memory Code Protection (Data memory code protection is disabled)
#pragma config BOREN = ON       // Brown-out Reset Enable (Brown-out Reset enabled)
#pragma config CLKOUTEN = ON   // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
#pragma config IESO = OFF       // Internal/External Switchover (Internal/External Switchover mode is disabled)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is disabled)

// CONFIG2
#pragma config WRT = OFF        // Flash Memory Self-Write Protection (Write protection off)
#pragma config PLLEN = OFF       // PLL Enable (4x PLL enabled)
#pragma config STVREN = ON      // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset)
#pragma config BORV = LO        // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LVP = OFF        // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming)


/**
 * Global variables
 */

// PI parameters
__eeprom unsigned char Igaineeprom;
__eeprom unsigned char Pgaineeprom;
unsigned int Igain=50;//initial value of 300 adaptable with potentiometer
unsigned int Pgain=300;//initial value of 300 adaptable with potentiometer
unsigned int Buttonstatus;
unsigned long Ivalue;

// Voltage
unsigned int Voltage;

// timer parameters
unsigned int timer;
signed int PeriodError;     // error on period

// Algorithm
signed long PIvalue;
signed long IvalueDelta;
signed long Pvalue;
unsigned int PIvaluePos;

// processing
unsigned int Accumulate;
unsigned char write_counter;

//Dumpload shift
unsigned char pos=0;
unsigned char LoadNprevious=0;
unsigned char LoadN=0;


// smart socket
   //unsigned char smartSocketOn;



/**
 * functions
 */
void checkNewCycle();
void PIadapation();
signed long limitRange(signed long, signed long, signed long);


void initialize()
{
    initialize_SR();
    initialize_LCD();
    initializeADC();
    initializeComparator();
}

char byte;

void interrupt ISR(void){
    GIE = 0; // Temporarily stop interrupts
    if (C1IF == 1)
    {
        C1IF = 0;
        checkNewCycle();
    }
    GIE = 1; // Reactivate interrupts
}

/*
 *
 */
int main() {
    initialize();

    LCD_clear();

    for(;;)
    {
        //GIE = 0;
        selectButton(); //Button
        Buttonstatus = readADC();
        if (Buttonstatus==1023){
        selectPot();
        int temp = readADC(); // You don't want P to be minimally 1
        if (temp < 4)
        { Pgain = 0; }
        else
        { Pgain = temp;}
        }
        else {
        selectPot();
        int temp = readADC(); // You don't want I to be minimally 1
        if (temp < 4)
        {
           Igain = 0; }
        else
        { Igain = temp;}
        }
        selectVoltage();
        Voltage = readADC();


        LCD_home();
        LCD_write_string("P: ");
        LCD_write_number_fixed_length(Pgain,4);

        LCD_goto_address(1,9);
        LCD_write_string("I: ");
        LCD_write_number_fixed_length(Igain,4);

        LCD_second_row();
        LCD_write_string("V: ");
        LCD_write_number((Voltage*5)/1000/2.8*220); //Divide by 2.55 because at 2.55V at voltage divider 220V at entry
        LCD_write_string(".");
        LCD_write_number_fixed_length_with_zero(((Voltage*5)/10)%100,2);

        /*
        LCD_goto_address(2,1);
        //LCD_write_number_neg(Ivalue);
        //LCD_write_number_neg(Pvalue);
        LCD_write_number_fixed_length(PIvaluePos,5);
        */

        LCD_goto_address(2,11);
        LCD_write_string("F:");
        long basefreq = 7812500; // Actual base frequency is 781250 Hz
        int frequency = basefreq/timer;

        LCD_write_number_fixed_length(frequency/10,2);
        LCD_write_string(".");
        LCD_write_number(frequency%10);

        for(int i = 0; i<100; i++) {
        _delay(62500); // 0.01 s
        }

        LCD_clear();
        _delay(62500);

    }
}

void checkNewCycle() {
     /**
     * Read Time
     */
    timer = TMR1;      // read the LSB of timer
    TMR1=timer_offset;                   // reset time, heuristic adaptation for lost time

    /**
     * PI berekening
     */
    PeriodError = timer;
    PeriodError = period - PeriodError;     // time difference from wanted

    signed long PE = PeriodError;
    unsigned long PG = Pgain;
    unsigned long IG = Igain;

#   ifdef Imath //The # causes the compiler to add this code only if Imath exists, so only use integrate error if Imath exists

    // I berekening: see figure

    IvalueDelta = PE*IG;
    Ivalue += (IvalueDelta>>10) ;  // Integrate but divide by 1024, order
    Ivalue = limitRange(Ivalue,-1048575,1048575); // Limit to 21bit number
    #else
    Ivalue=0;
    #endif

    // P berekening
    Pvalue = PE*PG;
    Pvalue = limitRange(Pvalue,-1048575,1048575);

    // PI samenstelling
    PIvalue = Ivalue + Pvalue;
    PIvalue = limitRange(PIvalue,-1048575,1048575); // Limit to 21bit number
    PIvalue = PIvalue >> 6;  // Reduce to 15bit number;
    int PItemp = PIvalue;
    PIvaluePos = (PItemp+16384+1); // Let zero action be half the swing (swing goes from -16384 to 16384) (swing=range)
    // Maximum is 32767. Divided by 8 this is: 4095.875
    int NDump = PIvaluePos/4096;
    Accumulate += PIvaluePos%4096;
    if (Accumulate>4096 && NDump!=8){
        NDump+=1;
        Accumulate=0;
    }
    unsigned char LoadN = NDump;




    /**
     * Algoritme voor smartsocket
     */
//            if ((smartSocketOn==1)&&(LoadN==0))
//            {
//                smartSocketOn=0;
//                //LoadN=smartSocket/2;
//            }
//            if ((smartSocketOn==0)&&(LoadN>smartSocket))
//            {
//                smartSocketOn=1;
//                //LoadN=smartSocket/2;
//            }

    /**
     * Convert to loads
     */
/*
    int toLoads;
    switch ( LoadN ) {
        case 0:
            toLoads = 0b00000000;// | smartSocketOn;
            break;
        case 1:
            toLoads = 0b00000010;// | smartSocketOn;
            break;
        case 2:
            toLoads = 0b00000110;// | smartSocketOn;
            break;
        case 3:
            toLoads = 0b00001110;// | smartSocketOn;
            break;
        case 4:
            toLoads = 0b00011110;// | smartSocketOn;
            break;
        case 5:
            toLoads = 0b00111110;// | smartSocketOn;
            break;
        case 6:
            toLoads = 0b01111110;// | smartSocketOn;
            break;
        case 7:
            toLoads = 0b11111110;// | smartSocketOn;
            break;
        case 8:
            toLoads = 0b11111111;// | smartSocketOn;
            break;
        default:
            toLoads = 0b11111111;
            break;
    }
*/


    unsigned char toLoads1 = 0;
    unsigned char toLoads=0;
    unsigned char shift; //shift is new pos
    for(char i=0; i<LoadN; i++)
    {
        toLoads1 += (1 << i);
    }
        if (LoadNprevious>LoadN) {                         // Dumploads off
        shift=pos+(LoadNprevious-LoadN); //new pos
            if (shift>7) {                  // End position array
                shift=shift-8;
            }
            else {
                shift=shift;
            }
    }
         else  {                         // Dumploads on
            shift=pos;
        if (shift>7) {          //UNNECESARY        // End position array
    shift=shift-8;
                    }
            else {
                shift=shift;
            }
    }
    toLoads = (toLoads1 << shift) | (toLoads1 >> (8 - shift));    // Rotate bitpattern left to position


    // write shift register
    putShiftRegister(toLoads);

    //Start calculation of position
    if (LoadNprevious>LoadN) {                 // Dumploads off
        pos+=LoadNprevious-LoadN;
        if (pos>7){
            pos=pos-8;
        }
        else {
            pos=pos;
        }
    }
         else {                         // Dumploads on
    pos=pos;
    }
    //End calculation of position

    LoadNprevious=LoadN;
}



signed long limitRange(signed long number, signed long min, signed long max) {
    if(number>max){
        return max;
    }
    if(number<min) {
        return min;
    }
    return number;
}
4

1 回答 1

0

不同版本的 xc 编译器有不同的 _delay 函数。XC16 有 _delay_ms。通常你需要告诉编译器振荡器频率见下面的代码

 #define _XTAL_FREQ 20000000

#include <xc.h>
#include <p18f4550.h>
void main(void) {
   __delay_us(10);
   __delay_ms(10);
}
于 2017-04-13T17:50:53.690 回答