我不断收到错误"无法解析标识符_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;
}
不同版本的xc编译器具有不同的_delay函数。XC16 具有_delay_ms。 通常你需要告诉编译器振荡器频率见下面的代码
#define _XTAL_FREQ 20000000
#include <xc.h>
#include <p18f4550.h>
void main(void) {
__delay_us(10);
__delay_ms(10);
}