我正在进行一个关于使用PIC16F877A MCU的有功功率和无功功率测量套件的项目。在代码中,我使用了数学库中包含的pow、sqrt和cos函数。当我执行代码时,我会得到这些错误。
CLEAN SUCCESSFUL (total time: 104ms)
make -f nbproject/Makefile-default.mk SUBPROJECTS= .build-conf
make[1]: Entering directory 'C:/Users/BATUHAN/Desktop/bitirme/bitirme.X'
make -f nbproject/Makefile-default.mk dist/default/production/bitirme.X.production.hex
make[2]: Entering directory 'C:/Users/BATUHAN/Desktop/bitirme/bitirme.X'
"D:Program FilesMicrochipxc8v2.32binxc8-cc.exe" -mcpu=16F877A -c -mdfp="D:/Program Files/Microchip/MPLABX/v5.50/packs/Microchip/PIC16Fxxx_DFP/1.2.33/xc8" -fno-short-double -fno-short-float -O0 -fasmfile -maddrqual=ignore -xassembler-with-cpp -mwarn=-3 -Wa,-a -DXPRJ_default=default -msummary=-psect,-class,+mem,-hex,-file -ginhx32 -Wl,--data-init -mno-keep-startup -mno-osccal -mno-resetbits -mno-save-resetbits -mno-download -mno-stackcall -std=c99 -gdwarf-3 -mstack=compiled:auto:auto -o build/default/production/main.p1 main.c
::: advisory: (2049) C99 compliant libraries are currently not available for baseline or mid-range devices, or for enhanced mid-range devices using a reentrant stack; using C90 libraries
main.c:72:20: warning: implicit conversion loses floating-point precision: 'double' to 'float' [-Wconversion]
pf=cos(pf_timer);
~^~~~~~~~~~~~~
main.c:77:20: warning: implicit conversion loses floating-point precision: 'double' to 'float' [-Wconversion]
pf=cos(360 - pf_timer); //guc faktoru degeri
~^~~~~~~~~~~~~~~~~~~
main.c:87:20: warning: implicit conversion loses floating-point precision: 'double' to 'float' [-Wconversion]
pf=cos(pf_timer);
~^~~~~~~~~~~~~
main.c:92:20: warning: implicit conversion loses floating-point precision: 'double' to 'float' [-Wconversion]
pf=cos(360 - pf_timer); //guc faktoru degeri
~^~~~~~~~~~~~~~~~~~~
main.c:132:25: warning: implicit conversion loses floating-point precision: 'double' to 'float' [-Wconversion]
CRMS = CRMS + pow(((ADC_Value*5/1024 - 2.5)/0.185),2); //akimin karesi alinarak toplaniyor
~ ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.c:139:25: warning: implicit conversion loses floating-point precision: 'double' to 'float' [-Wconversion]
VRMS = VRMS + pow((((ADC_Value*5/1024)-2.5)*325),2); //gerilimin karesi alinarak toplaniyor
~ ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.c:147:24: warning: implicit conversion loses floating-point precision: 'double' to 'float' [-Wconversion]
CRMS = sqrt(CRMS); //ve kare koku alinarak rms akim degeri hesaplaniyor
~ ^~~~~~~~~~
main.c:149:24: warning: implicit conversion loses floating-point precision: 'double' to 'float' [-Wconversion]
VRMS = sqrt(VRMS); //ve kare koku alinarak rms voltaj degeri hesaplaniyor
~ ^~~~~~~~~~
8 warnings generated.
"D:Program FilesMicrochipxc8v2.32binxc8-cc.exe" -mcpu=16F877A -Wl,-Map=dist/default/production/bitirme.X.production.map -DXPRJ_default=default -Wl,--defsym=__MPLAB_BUILD=1 -mdfp="D:/Program Files/Microchip/MPLABX/v5.50/packs/Microchip/PIC16Fxxx_DFP/1.2.33/xc8" -fno-short-double -fno-short-float -O0 -fasmfile -maddrqual=ignore -xassembler-with-cpp -mwarn=-3 -Wa,-a -msummary=-psect,-class,+mem,-hex,-file -ginhx32 -Wl,--data-init -mno-keep-startup -mno-osccal -mno-resetbits -mno-save-resetbits -mno-download -mno-stackcall -std=c99 -gdwarf-3 -mstack=compiled:auto:auto -Wl,--memorysummary,dist/default/production/memoryfile.xml -o dist/default/production/bitirme.X.production.elf build/default/production/main.p1
::: advisory: (2049) C99 compliant libraries are currently not available for baseline or mid-range devices, or for enhanced mid-range devices using a reentrant stack; using C90 libraries
D:Program FilesMicrochipxc8v2.32picsourcesc90commonfleq.c:4:: advisory: (1510) non-reentrant function "___fleq" appears in multiple call graphs and has been duplicated by the compiler
D:Program FilesMicrochipxc8v2.32picsourcesc90commonflge.c:4:: advisory: (1510) non-reentrant function "___flge" appears in multiple call graphs and has been duplicated by the compiler
D:Program FilesMicrochipxc8v2.32picsourcesc90commonflneg.c:15:: advisory: (1510) non-reentrant function "___flneg" appears in multiple call graphs and has been duplicated by the compiler
D:Program FilesMicrochipxc8v2.32picsourcesc90commonfltol.c:43:: advisory: (1510) non-reentrant function "___fltol" appears in multiple call graphs and has been duplicated by the compiler
D:Program FilesMicrochipxc8v2.32picsourcesc90commonsprcadd.c:10:: advisory: (1510) non-reentrant function "___fladd" appears in multiple call graphs and has been duplicated by the compiler
D:Program FilesMicrochipxc8v2.32picsourcesc90commonsprcadd.c:242:: advisory: (1510) non-reentrant function "___flsub" appears in multiple call graphs and has been duplicated by the compiler
D:Program FilesMicrochipxc8v2.32picsourcesc90commonsprcdiv.c:8:: advisory: (1510) non-reentrant function "___fldiv" appears in multiple call graphs and has been duplicated by the compiler
D:Program FilesMicrochipxc8v2.32picsourcesc90commonsprcmul.c:8:: advisory: (1510) non-reentrant function "___flmul" appears in multiple call graphs and has been duplicated by the compiler
D:Program FilesMicrochipxc8v2.32picsourcesc90commonUmul8_16.c:4:: advisory: (1510) non-reentrant function "__Umul8_16" appears in multiple call graphs and has been duplicated by the compiler
D:Program FilesMicrochipxc8v2.32picsourcesc90commonxxtofl.c:10:: advisory: (1510) non-reentrant function "___xxtofl" appears in multiple call graphs and has been duplicated by the compiler
D:Program FilesMicrochipxc8v2.32picsourcesc90commonevalpoly.c:4:: advisory: (1510) non-reentrant function "_eval_poly" appears in multiple call graphs and has been duplicated by the compiler
D:Program FilesMicrochipxc8v2.32picsourcesc90commonfloor.c:13:: advisory: (1510) non-reentrant function "_floor" appears in multiple call graphs and has been duplicated by the compiler
D:Program FilesMicrochipxc8v2.32picsourcesc90commonfrexp.c:254:: advisory: (1510) non-reentrant function "_frexp" appears in multiple call graphs and has been duplicated by the compiler
D:Program FilesMicrochipxc8v2.32picsourcesc90commonsprcdiv.c:185:: error: (1360) no space for auto/param _main$903
(908) exit status = 1
nbproject/Makefile-default.mk:138: recipe for target 'dist/default/production/bitirme.X.production.hex' failed
make[2]: Leaving directory 'C:/Users/BATUHAN/Desktop/bitirme/bitirme.X'
nbproject/Makefile-default.mk:91: recipe for target '.build-conf' failed
make[1]: Leaving directory 'C:/Users/BATUHAN/Desktop/bitirme/bitirme.X'
nbproject/Makefile-impl.mk:39: recipe for target '.build-impl' failed
make[2]: *** [dist/default/production/bitirme.X.production.hex] Error 1
make[1]: *** [.build-conf] Error 2
make: *** [.build-impl] Error 2
BUİLD FAILED (exit value 2, total time: 5s)
我无法解决这些错误
我写的代码
#pragma config FOSC = HS // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = ON // Power-up Timer Enable bit (PWRT enabled)
#pragma config BOREN = OFF // Brown-out Reset Enable bit (BOR disabled)
#pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = ON // Data EEPROM Memory Code Protection bit (Data EEPROM code-protected)
#pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = ON // Flash Program Memory Code Protection bit (All program memory code-protected)
#define _XTAL_FREQ 20000000
#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define ADC_Current RA0
#define ADC_Volt RA1
#define VZCD RB0
#define CZCD RB4
float pf_timer=0;
float pf=0;
float ADC_Value = 0;
float CRMS, VRMS, Current, Volt = 0;
int Rms_Count=0;
float Q=0, P=0;
_Bool timer_bit=0;
_Bool counter_bit=0;
_Bool pf_bit=1;
_Bool LEAD_LAG=0;
void __interrupt() KESME(void)
{
//TMR1 KESMESI
if(TMR1IF)
{
TMR1IF=0;
TMR1=15535;
timer_bit = timer_bit^1;
}
//INT (RB0) KESMESI
if(INTF)
{
INTF=0;
pf_bit=1;
pf_timer = TMR1;
}
//PORTB KESMESI
if(RBIF==1 && RB4==1 && pf_bit==1)
{
RBIF=0;
pf_bit=0;
if(TMR1 >= pf_timer)
{
pf_timer = TMR1 - pf_timer;
pf_timer = pf_timer*360/50000;
if(pf_timer <= 90)
{
pf=cos(pf_timer);
LEAD_LAG=0;
}
else if(pf_timer >= 270)
{
pf=cos(360 - pf_timer);
LEAD_LAG=1;
}
}
else if(TMR1 < pf_timer)
{
pf_timer =65535 - pf_timer + TMR1;
pf_timer = pf_timer*360/50000;
if(pf_timer <= 90)
{
pf=cos(pf_timer);
LEAD_LAG=0;
}
else if(pf_timer >= 270)
{
pf=cos(360 - pf_timer);
LEAD_LAG=1;
}
}
}
}
void main(void)
{
TRISA = 0XFF;
PORTA = 0X00;
TRISB = 0XFF;
PORTB = 0X00;
//ADC KONFIGURASYON BITLERI
ADCON0=0b01000001;
ADCON1=0b10000000;
//TIMER-1 KONFIGURASYON BITLERI
TMR1=15535;
INTCON=0b11011000;
INTEDG=1;
T1CON=0b00011110;
TMR1IE=1;
TMR1IF=0;
TMR1ON=1;
while(1)
{
//AKIM VE GERILIM OLCUMU
if(timer_bit)
{
counter_bit=0;
Rms_Count += 1;
ADCON0bits.CHS0=0;
GO_DONE = 1;
while(GO_DONE);
ADC_Value = (ADRESH*256 + ADRESL);
CRMS = CRMS + pow(((ADC_Value*5/1024 - 2.5)/0.185),2);
ADCON0bits.CHS0=1;
GO_DONE = 1;
while(GO_DONE);
ADC_Value = (ADRESH*256 + ADRESL);
VRMS = VRMS + pow((((ADC_Value*5/1024)-2.5)*325),2);
}
else if(!timer_bit)
{
if(!counter_bit)
{
CRMS = CRMS / Rms_Count;
CRMS = sqrt(CRMS);
VRMS = VRMS / Rms_Count;
VRMS = sqrt(VRMS);
Volt = VRMS;
Current = CRMS;
}
counter_bit=1;
CRMS=0;
Rms_Count=0;
VRMS=0;
}
}
return;
}
我试着换成C90单口相声,但一切都没有改变。我该如何解决这个问题。
关于XC8编译器专门为中端设备支持哪些库,似乎没有太多清晰的信息。我能在Microchip开发者帮助网站上找到的唯一简短信息是:
请确保您也在使用下图所示的C99库,但请注意,目前,C99兼容库仅适用于针对PIC18设备和针对使用编译(不可重入)堆栈模型的增强型中程设备的项目。
然而,正如咨询所述:
C99兼容库目前不适用于基线或中端设备,也不适用于使用可重入堆栈的增强型中端设备
考虑到这一建议,无论是基线还是中端或增强型中端设备,都不应用于使用C99兼容库的项目基线、中端和增强中端设备是名称分别以PIC10,PIC12*和PIC16前缀开头的任何设备。
因此,针对您的情况,选择一个高级型号的8位PIC控制器,任何名称中以PIC18前缀开头的型号都应该有效。不过,我会向您推荐相对较新的产品。例如,您可以购买比它更新的PIC18F45K50,而不是购买相对较旧的PIC18F4 550,它可能有一些增强功能。
现在让我回答你在评论中提出的其他问题:
您建议哪种PIC18F对我的项目做得足够。电路中有4-5个I/O引脚,我将添加一个2x16 LCD。
对于这种需求,像PIC18F14K50这样的型号应该为您的项目做这项工作,因为它有20个引脚。或者你可以选择25K20或25K22,它们都有28个引脚,足以满足你的要求。
如果我放上cos()和sqrt()函数的源代码并删除
#include <math.h>
,我还会有同样的架构问题吗。
我不确定,因为这里的问题是使用可重入或软件堆栈,这是一种为函数动态分配的内存类型。知道了这一点,我可以说,如果这些函数是用XC8的软件堆栈模型编译的,那么它根本不适用于PIC16F877A。事实上,我看到编译器的建议和Microchip开发者网站上引用的关于可重入堆栈模型使用的解释之间存在冲突。编译器的建议有点不清楚可重入堆栈模型是否可以与增强的中端设备一起使用,而在开发者网站上,它却表示相反。这鼓励我们在XC8编译器手册中查看编译堆栈和 软件堆栈编译堆栈(重传) 编译堆栈是为自动存储持续时间对象指定的一个或多个内存区域。编译堆栈中分配空间的对象被分配一个静态地址,该地址可以通过编译器分配的符号访问。这是访问基于堆栈的对象的最有效方法,因为它不使用堆栈指针。 软件堆栈(不可重入) 软件堆栈是内存的动态分配,用于自动存储持续时间对象,并通过堆栈指针间接访问。尽管访问软件堆栈上的对象可能较慢,但使用软件堆栈的函数是可重入的。这种形式的堆栈仅适用于增强型中程和PIC18设备。 它明确指出,可重入功能仅适用于增强型中端和PIC18设备。 最后如果您可以避免在主和中断中使用相同的函数,也许您可以使用PIC16F877A,编译器使用编译堆栈模型编译代码。因为编译器在主和中断中都使用函数时会复制这些函数,这会触发可重入函数堆栈模型的编译。
TL;DR基本上您的内存不足。编译后的代码不适合您的uCs内存。
主要问题是,您使用中断的cos()
函数被编译器复制,因为它同时出现在主代码和中断中,并且您的uC只支持不支持函数重入的编译堆栈模型。
不幸的是,它并没有就此结束。似乎cos()
调用了其他库函数,比如链式反应。这些都是浮点函数,具有较高的内存占用率。现在,这些沉重的浮点函数(很多)也被复制了,它们不适合你的uC的内存。这可能是RAM或闪存不足,也可能是两者兼而有之。
通过更改程序逻辑,尝试从ISR中删除cos()
(或任何其他浮点函数)。
警告与编译错误没有直接关系。您可以转到MPLAB中的项目属性菜单。在这里,您将看到XC8全局选项下的C库链接选项->XC8链接器->运行时。选择C90而不是C99。您也可以尝试使用浮点版本的库函数,例如使用cosf()
而不是cos()
,但这些函数可能在C90上不可用。或者,您可以手动强制转换为float以消除警告。