繁体   English   中英

MPLAB X IDE v5.50 中的源代码和 Header 文件语法

[英]Source and Header file syntax in MPLAB X IDE v5.50

我正在为我的 PIC32MK1024MCM 项目开发代码。 我已经很好地测试了代码,现在我只是将所有代码模块放入最终项目中(此示例中的代码尚未完成,但功能不是这里感兴趣的轴心)。 我有生以来第一次想让它更专业一点,并为所有不同的模块 function 声明使用单独的源文件和 header 文件。 但是,我显然面临某种语法问题,因为我几乎在源文件的每一行中都遇到了错误(我想我必须在该源文件中包含一些内容,但我不确定)就像我说的那样,它是我第一次面对 header 和源文件,所以你能帮帮我吗,或者至少提示我,我这么明显地错过了什么? 我想提前谢谢你。

主要的:

#include <xc.h>
#include <configuration_bits.c>

#include <toolchain_specifics.h>
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include "stdio.h"
#include <sys/attribs.h>

#include <analog_to_digital_conversion.h>

    void main(void) {
        
       
       
            while (1){

            }
            
        return (EXIT_FAILURE);
        
    }

配置位

// DEVCFG3
#pragma config USERID = 0xFFFF // Enter Hexadecimal value (Enter Hexadecimal value)
#pragma config PWMLOCK = OFF // PWM IOxCON lock (PWM IOxCON register writes accesses are not locked or protected)
#pragma config FUSBIDIO2 = OFF // USB2 USBID Selection (USBID pin is controlled by the port function)
#pragma config FVBUSIO2 = OFF // USB2 VBUSON Selection bit (VBUSON pin is controlled by the port function)
#pragma config PGL1WAY = OFF // Permission Group Lock One Way Configuration bit (Allow multiple reconfigurations)
#pragma config PMDL1WAY = OFF // Peripheral Module Disable Configuration (Allow multiple reconfigurations)
#pragma config IOL1WAY = OFF // Peripheral Pin Select Configuration (Allow multiple reconfigurations)
#pragma config FUSBIDIO1 = OFF // USB1 USBID Selection (USBID pin is controlled by the port function)
#pragma config FVBUSIO1 = OFF // USB2 VBUSON Selection bit (VBUSON pin is controlled by the port function)

// DEVCFG2
#pragma config FPLLIDIV = DIV_1 // System PLL Input Divider (1x Divider)
#pragma config FPLLRNG = RANGE_BYPASS // System PLL Input Range (Bypass)
#pragma config FPLLICLK = PLL_POSC // System PLL Input Clock Selection (POSC is input to the System PLL)
#pragma config FPLLMULT = MUL_4 // System PLL Multiplier (PLL Multiply by 4)
#pragma config FPLLODIV = DIV_2 // System PLL Output Clock Divider (2x Divider)
#pragma config BORSEL = HIGH // Brown-out trip voltage (BOR trip voltage 2.1v (Non-OPAMP deviced operation))
#pragma config UPLLEN = OFF // USB PLL Enable (USB PLL Disabled)

// DEVCFG1
#pragma config FNOSC = POSC // Oscillator Selection Bits (Primary Osc (HS,EC))
#pragma config DMTINTV = WIN_0 // DMT Count Window Interval (Window/Interval value is zero)
#pragma config FSOSCEN = OFF // Secondary Oscillator Enable (Disable Secondary Oscillator)
#pragma config IESO = ON // Internal/External Switch Over (Enabled)
#pragma config POSCMOD = HS // Primary Oscillator Configuration (HS osc mode)
#pragma config OSCIOFNC = OFF // CLKO Output Signal Active on the OSCO Pin (Disabled)
#pragma config FCKSM = CSDCMD // Clock Switching and Monitor Selection (Clock Switch Disabled, FSCM Disabled)
#pragma config WDTPS = PS1 // Watchdog Timer Postscaler (1:1)
#pragma config WDTSPGM = STOP // Watchdog Timer Stop During Flash Programming (WDT stops during Flash programming)
#pragma config WINDIS = NORMAL // Watchdog Timer Window Mode (Watchdog Timer is in non-Window mode)
#pragma config FWDTEN = OFF // Watchdog Timer Enable (WDT Disabled)
#pragma config FWDTWINSZ = WINSZ_25 // Watchdog Timer Window Size (Window size is 25%)
#pragma config DMTCNT = DMT31 // Deadman Timer Count Selection (2^31 (2147483648))
#pragma config FDMTEN = OFF // Deadman Timer Enable (Deadman Timer is disabled)

// DEVCFG0
#pragma config DEBUG = OFF // Background Debugger Enable (Debugger is disabled)
#pragma config JTAGEN = OFF // JTAG Enable (JTAG Disabled)
#pragma config ICESEL = ICS_PGx1 // ICE/ICD Comm Channel Select (Communicate on PGEC1/PGED1)
#pragma config TRCEN = OFF // Trace Enable (Trace features in the CPU are disabled)
#pragma config BOOTISA = MIPS32 // Boot ISA Selection (Boot code and Exception code is MIPS32)
#pragma config FECCCON = ECC_DECC_DISABLE_ECCON_WRITABLE // Dynamic Flash ECC Configuration Bits (ECC and Dynamic ECC are disabled (ECCCON<1:0> bits are writable))
#pragma config FSLEEP = OFF // Flash Sleep Mode (Flash is powered down when the device is in Sleep mode)
#pragma config DBGPER = PG_ALL // Debug Mode CPU Access Permission (Allow CPU access to all permission regions)
#pragma config SMCLR = MCLR_NORM // Soft Master Clear Enable (MCLR pin generates a normal system Reset)
#pragma config SOSCGAIN = G3 // Secondary Oscillator Gain Control bits (Gain is G3)
#pragma config SOSCBOOST = ON // Secondary Oscillator Boost Kick Start Enable bit (Boost the kick start of the oscillator)
#pragma config POSCGAIN = G3 // Primary Oscillator Coarse Gain Control bits (Gain Level 3 (highest))
#pragma config POSCBOOST = ON // Primary Oscillator Boost Kick Start Enable bit (Boost the kick start of the oscillator)
#pragma config POSCFGAIN = G3 // Primary Oscillator Fine Gain Control bits (Gain is G3)
#pragma config POSCAGCDLY = AGCRNG_x_25ms // AGC Gain Search Step Settling Time Control (Settling time = 25ms x AGCRNG)
#pragma config POSCAGCRNG = ONE_X // AGC Lock Range bit (Range 1x)
#pragma config POSCAGC = Automatic // Primary Oscillator Gain Control bit (Automatic Gain Control for Oscillator)
#pragma config EJTAGBEN = NORMAL // EJTAG Boot Enable (Normal EJTAG functionality)

// DEVCP
#pragma config CP = OFF // Code Protect (Protection Disabled)

// SEQ
#pragma config TSEQ = 0xFFFF // Boot Flash True Sequence Number (Enter Hexadecimal value)
#pragma config CSEQ = 0xFFFF // Boot Flash Complement Sequence Number (Enter Hexadecimal value)   

analog_to_digital_conversion.h

//**************************************************************************
// ANALOG TO DIGITAL CONVERSION HEADER FILE
//**************************************************************************

  #include <analog_to_digital_conversion.c>

    void Anaolog_to_Digital_Conversion_Setup (void);

    void Anaolog_to_Digital_Conversion_Enable (void);

    void Anaolog_to_Digital_Conversion_Disable (void);

    uint16_t Anaolog_to_Digital_Conversion (void);

analog_to_digital_conversion.c

//**************************************************************************
// ANALOG TO DIGITAL CONVERSION SOURCE FILE
//**************************************************************************

    void Anaolog_to_Digital_Conversion_Setup (void){
        
        //All this procedure is taken from the device`s datasheet (no ADC interrupts are desired)

        ADCANCONbits.ANEN5 = 0b0; //Analog and bias circuitry disabled (to set calibration)
        //---------------------------------------------------------------------------------------------------------------------------------------------------------------
        ADC5CFGbits.ADCCFG = DEVADC5; //Copying the factory calibration ADC module bits to the ADC configuration register
        //---------------------------------------------------------------------------------------------------------------------------------------------------------------
        ADCCON1bits.ON = 0b0; //Disabling the ADC module
        //---------------------------------------------------------------------------------------------------------------------------------------------------------------
        ADC5TIMEbits.SAMC = 0b1111111111; //Sample time is set to 1025 TAD
        ADC5TIMEbits.ADCDIV = 0b1111111; //254 * TQ = TAD (ADC clock division bits)
        //---------------------------------------------------------------------------------------------------------------------------------------------------------------
        ADCANCONbits.WKUPCLKCNT = 0xF; //ADC warm up time is set to 32768 ADC clock cycles (maximum warm up time, around 32 us @ 100 MHz SYSCLK)
        //---------------------------------------------------------------------------------------------------------------------------------------------------------------
        ADCCON3bits.ADCSEL = 0b0; //Analog-to-Digital Clock Source (TCLK) -> SYSCLK
        ADCCON3bits.CONCLKDIV = 0b000000; //TCLK = TQ
        ADCCON3bits.DIGEN5 = 0b0; //All digital bits are disabled (according to the datasheet)
        ADCCON3bits.VREFSEL = 0b000; //Vref is set to AVdd and AVss
        //---------------------------------------------------------------------------------------------------------------------------------------------------------------
        ADCIMCON1bits.DIFF11 = 0b0; //AN11 is using Single-ended mode
        ADCIMCON1bits.SIGN11 = 0b0; //AN11 is using Unsigned Data mode
        //---------------------------------------------------------------------------------------------------------------------------------------------------------------
        ADCTRGSNSbits.LVL11 = 0b0; //Analog input is sensitive to the positive edge of its trigger (this is the value after a reset)
        //---------------------------------------------------------------
        ADCTRG3bits.TRGSRC11 = 0b00001; //AN11 is software triggered
        //---------------------------------------------------------------------------------------------------------------------------------------------------------------
        ADCANCONbits.ANEN5 = 0b1; //Analog and bias circuitry enabled
        //---------------------------------------------------------------------------------------------------------------------------------------------------------------
        ADCCON1bits.ON = 0b1; //Enabling the ADC module
        //---------------------------------------------------------------
        while(!((ADCCON2bits.BGVRRDY)&&(ADCANCONbits.WKRDY5))); //Wait until device analog environment is ready
        ADCCON3bits.DIGEN5 = 0b1; //Enable digital circuitry for data processing
        //---------------------------------------------------------------------------------------------------------------------------------------------------------------
        ADCCON3bits.ADINSEL = 0b001011; //Select analog channel 11 for conversion
        //---------------------------------------------------------------------------------------------------------------------------------------------------------------
        ADCCON1bits.ON = 0b0; //Disabling the ADC module
    }
    
    void Anaolog_to_Digital_Conversion_Enable (void){

           ADCCON1bits.ON = 0b1; //Enabling the ADC module
    }

    void Anaolog_to_Digital_Conversion_Disable (void){

           ADCCON1bits.ON = 0b0; //Disabling the ADC module
    }
    
    uint16_t Anaolog_to_Digital_Conversion (void){
        
       uint16_t ADC_value = 0;
       
       ADCCON3bits.RQCNVRT = 1; //Trigger the conversion
       
           while(!ADCDSTAT1bits.ARDY11); //Waiting until ADC result is ready to be read (@ 100 MHz SYSCLK ADC conversion should take around 2ms)
           
       ADC_value = ADCDATA11 & 0x000FFFF; //Acquiring ADC result, register is 32 bits, but conversion only gives 12 bit ADC value, hence getting rid of higher 16 bits (those are all zeros)
         
       return (ADC_value);
    }

在此处输入图像描述

根据您问题中的文件,应该使用 header 文件来完成包含,因为这是常见的做法。

首先,您需要在每个使用处理器特定定义(如特殊功能寄存器和位名称)的文件中包含xc.h header。

您程序的其他依赖项可能是标准printf库中的任何内容,例如stdio.h中的 printf header 或stdint.h中的uint8_t header; 或您为应用程序编写的任何库函数等。

这里有一个技巧:如果您使用 MPLAB 编辑器编写代码,例如在键入 function 的几个字母后,您按下Ctrl + Space然后 MPLAB 编辑器将弹出可能的功能。 当您从弹出列表末尾输入 select 其中之一时,它会自动添加其 header 文件。

现在让我们回到你的案例。 除了包含 stdio.h 外,您的主文件看起来还不错。 您必须将#include "stdio.h"更改为#include <stdio.h>

您的 adc.c 文件必须包含我上面提到的一些内容。 首先,它必须包含xc.h header。并且您不必在 *.h 文件中包含 *.c 文件。 我还建议您使用 header 守卫来防止任何可能的嵌套包含,从而导致重定义错误。
analog_to_digital_conversion.h

// Header guard
#ifndef ANALOG_TO_DIGITAL_CONVERSION_H
#define ANALOG_TO_DIGITAL_CONVERSION_H

//**************************************************************************
// ANALOG TO DIGITAL CONVERSION HEADER FILE
//**************************************************************************

// #include <analog_to_digital_conversion.c> not needed here.

void Anaolog_to_Digital_Conversion_Setup (void);

void Anaolog_to_Digital_Conversion_Enable (void);

void Anaolog_to_Digital_Conversion_Disable (void);

uint16_t Anaolog_to_Digital_Conversion (void);

#endif /* ANALOG_TO_DIGITAL_CONVERSION_H */

analog_to_digital_conversion.c

//**************************************************************************
// ANALOG TO DIGITAL CONVERSION SOURCE FILE
//**************************************************************************

// include xc header for processor register and bit names
#include <xc.h>
// since you use uint16_t, you must include stdint header
#include <stdint.h>
// Finally include your own header for any further definitions
#include "analog_to_digital_conversion.h"

void Anaolog_to_Digital_Conversion_Setup (void){
    
    //All this procedure is taken from the device`s datasheet (no ADC interrupts are desired)
    
    ADCANCONbits.ANEN5 = 0b0; //Analog and bias circuitry disabled (to set calibration)
    //---------------------------------------------------------------------------------------------------------------------------------------------------------------
    ADC5CFGbits.ADCCFG = DEVADC5; //Copying the factory calibration ADC module bits to the ADC configuration register
    //---------------------------------------------------------------------------------------------------------------------------------------------------------------
    ADCCON1bits.ON = 0b0; //Disabling the ADC module
    //---------------------------------------------------------------------------------------------------------------------------------------------------------------
    ADC5TIMEbits.SAMC = 0b1111111111; //Sample time is set to 1025 TAD
    ADC5TIMEbits.ADCDIV = 0b1111111; //254 * TQ = TAD (ADC clock division bits)
    //---------------------------------------------------------------------------------------------------------------------------------------------------------------
    ADCANCONbits.WKUPCLKCNT = 0xF; //ADC warm up time is set to 32768 ADC clock cycles (maximum warm up time, around 32 us @ 100 MHz SYSCLK)
    //---------------------------------------------------------------------------------------------------------------------------------------------------------------
    ADCCON3bits.ADCSEL = 0b0; //Analog-to-Digital Clock Source (TCLK) -> SYSCLK
    ADCCON3bits.CONCLKDIV = 0b000000; //TCLK = TQ
    ADCCON3bits.DIGEN5 = 0b0; //All digital bits are disabled (according to the datasheet)
    ADCCON3bits.VREFSEL = 0b000; //Vref is set to AVdd and AVss
    //---------------------------------------------------------------------------------------------------------------------------------------------------------------
    ADCIMCON1bits.DIFF11 = 0b0; //AN11 is using Single-ended mode
    ADCIMCON1bits.SIGN11 = 0b0; //AN11 is using Unsigned Data mode
    //---------------------------------------------------------------------------------------------------------------------------------------------------------------
    ADCTRGSNSbits.LVL11 = 0b0; //Analog input is sensitive to the positive edge of its trigger (this is the value after a reset)
    //---------------------------------------------------------------
    ADCTRG3bits.TRGSRC11 = 0b00001; //AN11 is software triggered
    //---------------------------------------------------------------------------------------------------------------------------------------------------------------
    ADCANCONbits.ANEN5 = 0b1; //Analog and bias circuitry enabled
    //---------------------------------------------------------------------------------------------------------------------------------------------------------------
    ADCCON1bits.ON = 0b1; //Enabling the ADC module
    //---------------------------------------------------------------
    while(!((ADCCON2bits.BGVRRDY)&&(ADCANCONbits.WKRDY5))); //Wait until device analog environment is ready
    ADCCON3bits.DIGEN5 = 0b1; //Enable digital circuitry for data processing
    //---------------------------------------------------------------------------------------------------------------------------------------------------------------
    ADCCON3bits.ADINSEL = 0b001011; //Select analog channel 11 for conversion
    //---------------------------------------------------------------------------------------------------------------------------------------------------------------
    ADCCON1bits.ON = 0b0; //Disabling the ADC module
}

void Anaolog_to_Digital_Conversion_Enable (void){
    
    ADCCON1bits.ON = 0b1; //Enabling the ADC module
}

void Anaolog_to_Digital_Conversion_Disable (void){
    
    ADCCON1bits.ON = 0b0; //Disabling the ADC module
}

uint16_t Anaolog_to_Digital_Conversion (void){
    
    uint16_t ADC_value = 0;
    
    ADCCON3bits.RQCNVRT = 1; //Trigger the conversion
    
    while(!ADCDSTAT1bits.ARDY11); //Waiting until ADC result is ready to be read (@ 100 MHz SYSCLK ADC conversion should take around 2ms)
    
    ADC_value = ADCDATA11 & 0x000FFFF; //Acquiring ADC result, register is 32 bits, but conversion only gives 12 bit ADC value, hence getting rid of higher 16 bits (those are all zeros)
    
    return (ADC_value);
}

您必须对添加到项目中的每个 *.c & *.h 文件对使用相同的包含逻辑。

单独编译需要外部符号的可见性。 例如,在引用 ADCANCONbits 的ADCANCONbits中,编译器至少需要查看ADCANCONbits声明,以便它知道该符号存在及其类型。 当 linker 将来自每个单独编译的翻译单元的object代码脉冲在一起时,就会发生对定义的实际链接和解析。

您可以通过提供声明来解决未声明的标识符错误。 在这种情况下,该声明存在于 header 文件中,您必须在引用它的每个翻译单元中#include 我对PIC32开发不熟悉,但可以想象header是xc.h

Yoiu 还有许多其他问题,例如 analog_to_digital_conversion.h 引用了uint16_t但不包括定义该类型的 <stdint.h>。 由于包含在其他模块中,您可能会侥幸逃脱,但您不应该依赖它。

此外,所有 header 文件都需要警卫,以避免在同一翻译单元中多次包含多次声明 - 例如,当您嵌套包含时,这很容易发生。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM