我不知道我是否正确初始化了PIC24F的ADC



我使用Microchip Pic24f板从加速度计接收3个模拟输入。

我得到AN0的信号,但对于AN1和AN2有一个信号,但值不正确。

下面是我初始化ADC的代码。

void InitADC(int amask) {
AD1PCFG = 0xFFF8; // select AN0, AN1, AN2 as analog input
AD1CON1 = 0x00E0; // auto convert @ end of sampling, Integer Data in.
AD1CON2 = 0x0000; // use MUXA, AVss and AVdd used as Vref
AD1CON3 = 0x1F01; // Tad = 2xTcy = 125ns. 31*Tad for conversion time.
AD1CSSL = 0; // no scanning required
AD1CHS=0;
AD1CHS=1;
AD1CHS=2;
AD1CON1bits.ADON = 1; // Turn on the ADC
} // InitADC

In the main():

TRISBbits.TRISB0 = 1;
TRISBbits.TRISB1 = 1;
TRISBbits.TRISB2 = 1;

然后读取AD1PCFG = 0xFFFE;对于不同功能中的每个模拟输入。

输入的结果由同一函数

读入
return ADC1BUF0;

我不确定PIC24f是否需要为每个ANx模拟输入使用ADC1BUFx,或者我是否可以通过ADC1BUF0读取信号。

我也不知道我是否需要扫描,对于AD1CON2,由于使用多个模拟输入,配置需要不同。

我对PIC24f相当陌生,到处寻找帮助,我能够尝试让我获得要在LCD上读取的信号,但AN1和AN2数据不是它应该是什么。

如果有人能帮助我,将不胜感激。

这是一个示例,展示了我如何实现Microchip系列参考手册中描述您可能使用的ADC类型的内容:

/*
* File:   main.c
* Author: dan1138
* Target: PIC24FJ64GA002
* IDE: MPLABX v5.45
* Compiler: XC16 v1.61
*  
* Description:
* 
*  Initialize the ADC to convert voltage levels present on AN0, AN1 and AN5
*  
*  Map UART1 with TXD on RB0 and RXD on RB1.
*  Map UART2 with TXD on RB8 and RXD on RB8.
* 
*  Initialize UART2 at 9600 baud and hook to printf.
*
* Created on March 11, 2021, 1:46 PM
* 
* See: https://stackoverflow.com/questions/66552251/i-do-not-know-if-i-am-initializing-adc-correctly-for-pic24f
*
*                            PIC24FJ64GA002
*               +-----------------:_:-----------------+
*   ICD_VPP -> :  1 MCLR                     VDD  28 : <- 3v3
*           <> :  2 RA0/RP26/AN0             VSS  27 : <- GND
*           <> :  3 RA1/RP27/AN1   AN9 /RP15/RB15 26 : <> LED4
*   ICD_PGD <> :  4 RB0/PGD1/AN2   AN10/RP14/RB14 25 : <> LED5
*   ICD_PGC <> :  5 RB1/PGC1/AN3   AN11/RP13/RB13 24 : <> LED6
*           <> :  6 RB2/RP2/AN4    AN12/RP12/RB12 23 : <> LED7
*       POT <> :  7 RB3/RP3/AN5         RP11/RB11 22 : <>
*       GND -> :  8 VSS                 RP10/RB10 21 : <>
* 7.3728MHz <> :  9 RA2/OSCI                 VCAP 20 : <- 10uF
* 7.3728MHz <> : 10 RA3/OSCO                 VSS  19 : <- GND
*           <> : 11 RB4/SOSC            RP9 /RB9  18 : <> RXD
*           <> : 12 RA4/SOSC            RP8 /RB8  17 : <> TXD
*       3v3 -> : 13 VDD           INT0/ RP7 /RB7  16 : <>
*       SW1 <> : 14 RB5/RP5             RP6 /RB6  15 : <>
*               +-------------------------------------+
*                               DIP-28
*
*/
// CONFIG2
#pragma config POSCMOD = NONE           // Primary Oscillator Select (Primary oscillator disabled)
#pragma config I2C1SEL = PRI            // I2C1 Pin Location Select (Use default SCL1/SDA1 pins)
#pragma config IOL1WAY = OFF            // IOLOCK Protection (IOLOCK may be changed via unlocking seq)
#pragma config OSCIOFNC = ON            // Primary Oscillator Output Function (OSC2/CLKO/RC15 functions as port I/O (RC15))
#pragma config FCKSM = CSDCMD           // Clock Switching and Monitor (Clock switching and Fail-Safe Clock Monitor are disabled)
#pragma config FNOSC = FRCPLL           // Oscillator Select (Fast RC Oscillator with PLL module (FRCPLL))
#pragma config SOSCSEL = SOSC           // Sec Oscillator Select (Default Secondary Oscillator (SOSC))
#pragma config WUTSEL = LEG             // Wake-up timer Select (Legacy Wake-up Timer)
#pragma config IESO = ON                // Internal External Switch Over Mode (IESO mode (Two-Speed Start-up) enabled)
// CONFIG1
#pragma config WDTPS = PS32768          // Watchdog Timer Postscaler (1:32,768)
#pragma config FWPSA = PR128            // WDT Prescaler (Prescaler ratio of 1:128)
#pragma config WINDIS = ON              // Watchdog Timer Window (Standard Watchdog Timer enabled,(Windowed-mode is disabled))
#pragma config FWDTEN = OFF             // Watchdog Timer Enable (Watchdog Timer is disabled)
#pragma config ICS = PGx1               // Comm Channel Select (Emulator EMUC1/EMUD1 pins are shared with PGC1/PGD1)
#pragma config GWRP = OFF               // General Code Segment Write Protect (Writes to program memory are allowed)
#pragma config GCP = OFF                // General Code Segment Code Protect (Code protection is disabled)
#pragma config JTAGEN = OFF             // JTAG Port Enable (JTAG port is disabled)
#define FCY (16000000ul)                // This define allows the delay macros to work
#include "xc.h"
#include <libpic30.h>
#include <stdio.h>
/* define map input pin numbers */
enum
{   
RPI0  = 0,      /* pin RB00 */ /* PGC1 */
RPI1,           /* pin RB01 */ /* PGD1 */
RPI2,           /* pin RB02 */
RPI3,           /* pin RB03 */
RPI4,           /* pin RB04 */
RPI5,           /* pin RB05 */
RPI6,           /* pin RB06 */
RPI7,           /* pin RB07 */
RPI8,           /* pin RB08 */
RPI9,           /* pin RB09 */
RPI10,          /* pin RB10 */
RPI11,          /* pin RB11 */
RPI12,          /* pin RB12 */
RPI13,          /* pin RB13 */
RPI14,          /* pin RB14 */
RPI15,          /* pin RB15 */
RPI_NONE = 0x1f  
};  

/* define map output function numbers */
enum
{   
RPO_NONE = 0,
RPO_C1OUT,      
RPO_C2OUT,      
RPO_U1TX,       
RPO_U1RTS,      
RPO_U2TX,       
RPO_U2RTS,      
RPO_SDO1,       
RPO_SCK1OUT,    
RPO_SS1OUT,     
RPO_SDO2,       
RPO_SCK2OUT,    
RPO_SS2OUT,     
RPO_OC1=18,        
RPO_OC2,        
RPO_OC3,        
RPO_OC4,        
RPO_OC5,        
};  

/* Initialize this PIC */
void
PIC_Init(
void
)
{   
/* 
** Disable all interrupt sources
*/ 
__builtin_disi(0x3FFF); /* disable interrupts for 16383 cycles */
IEC0 = 0;
IEC1 = 0;
IEC2 = 0;
IEC3 = 0;
IEC4 = 0;
__builtin_disi(0x0000); /* enable interrupts */
CLKDIV =  0x0000; /* set for default clock operations */
AD1PCFG = 0xffff; /* Set for digital I/O */
#ifdef AD1PCFGH
AD1PCFGH = 0xffff;
#endif
CMCON   = 0x0000;
_NSTDIS = 1;    /* disable interrupt nesting */

TRISA   = 0xFFFF;
TRISB   = 0xFFFF;

/* Unlock Registers */
__builtin_write_OSCCONL(OSCCON & ~_OSCCON_IOLOCK_MASK);

/* map inputs */

_INT1R  = RPI_NONE; /* External Interrupt 1    */
_INT2R  = RPI_NONE; /* External Interrupt 2    */
_T2CKR  = RPI_NONE; /* Timer2 External Clock   */
_T3CKR  = RPI_NONE; /* Timer3 External Clock   */
_T4CKR  = RPI_NONE; /* Timer4 External Clock   */
_T5CKR  = RPI_NONE; /* Timer5 External Clock   */
_IC1R   = RPI_NONE; /* Input Capture 1         */
_IC2R   = RPI_NONE; /* Input Capture 2         */
_IC3R   = RPI_NONE; /* Input Capture 3         */
_IC4R   = RPI_NONE; /* Input Capture 4         */
_IC5R   = RPI_NONE; /* Input Capture 5         */
_OCFAR  = RPI_NONE; /* Output Compare Fault A  */
_OCFBR  = RPI_NONE; /* Output Compare Fault B  */
_U1RXR  = RPI1;     /* UART1 Receive           */
_U1CTSR = RPI_NONE; /* UART1 Clear To Send     */
_U2RXR  = RPI9;     /* UART2 Receive           */
_U2CTSR = RPI_NONE; /* UART2 Clear To Send     */
_SDI1R  = RPI_NONE; /* SPI1 Data Input         */
_SCK1R  = RPI_NONE; /* SPI1 Clock Input        */
_SS1R   = RPI_NONE; /* SPI1 Slave Select Input */
_SDI2R  = RPI_NONE; /* SPI2 Data Input         */
_SCK2R  = RPI_NONE; /* SPI2 Clock Input        */
_SS2R   = RPI_NONE; /* SPI2 Slave Select Input */

/* map outputs */
_RP0R   = RPO_U1TX;  /* U1 TXD */               /* pin RB00 */ /* PGC1 */
_RP1R   = RPO_NONE;  /* U1 RXD */               /* pin RB01 */ /* PGD1 */
_RP2R   = RPO_NONE;                             /* pin RB02 */
_RP3R   = RPO_NONE;                             /* pin RB03 */
_RP4R   = RPO_NONE;                             /* pin RB04 */
_RP5R   = RPO_NONE;                             /* pin RB05 */
_RP6R   = RPO_NONE;                             /* pin RB06 */
_RP7R   = RPO_NONE;                             /* pin RB07 */
_RP8R   = RPO_U2TX; /* U2 TXD */                /* pin RB08 */
_RP9R   = RPO_NONE; /* U2 RXD */                /* pin RB09 */
_RP10R  = RPO_NONE;                             /* pin RB10 */
_RP11R  = RPO_NONE;                             /* pin RB11 */
_RP12R  = RPO_NONE;                             /* pin RB12 */
_RP13R  = RPO_NONE;                             /* pin RB13 */
_RP14R  = RPO_NONE;                             /* pin RB14 */
_RP15R  = RPO_NONE;                             /* pin RB15 */

/* Lock Registers */
__builtin_write_OSCCONL(OSCCON | _OSCCON_IOLOCK_MASK);
}
/*
* Initialize the ADC
*/
static const uint8_t Selector[] = {0x00,0x01,0x05};
void ADC_Init(void)
{
AD1PCFGbits.PCFG0 = 0;  /* AN0/RA0 */
AD1PCFGbits.PCFG1 = 0;  /* AN1/RA1 */
AD1PCFGbits.PCFG5 = 0;  /* AN5/RB3 */
TRISAbits.TRISA0 = 1;
TRISAbits.TRISA1 = 1;
TRISBbits.TRISB3 = 1;

AD1CON1 = 0x0000;       // SAMP bit = 0 ends sampling and starts converting
AD1CHS  = 0x0000;       // default to channel 0       
AD1CSSL = 0;
AD1CON3 = 0x0102;       // Manual Sample, TAD = 3 TCY, Auto-Sample Time 1 TAD
AD1CON2 = 0;
AD1CON1bits.ADON = 1;   // turn ADC ON
}
/*
* ADC Read channel
*/
uint16_t ADC_ReadChannel(uint16_t Index)
{
if(Index < sizeof(Selector))
{
AD1CHSbits.CH0SA = Selector[Index];
}
AD1CON1bits.SAMP = 1;   // start sampling...
__delay_us(5);          // Ensure the correct sampling time has elapsed before starting conversion.
AD1CON1bits.SAMP = 0;   // start converting
for(;;)
{
if(AD1CON1bits.DONE) break; // conversion done?
}

return ADC1BUF0;  // yes then get ADC value
}
/*
* Initialize UART2
*/
#define U2_BAUD 9600L
#define U2_BRGH_VALUE 0
#if U2_BRGH_VALUE
#define U2_BRGH_SCALE 4L
#else
#define U2_BRGH_SCALE 16L
#endif
#define U2_BRGREG (FCY/(U2_BRGH_SCALE * U2_BAUD)-1L)
#if U2_BRGREG > 65535
#error Cannot set up UART2 for the FCY and BAUDRATE. Correct values in init.h and uart.h files.
#endif
/*
** Check if baud error greater than 2.5 percent
*/
#define REAL_BAUDRATE ( FCY / ( U2_BRGH_SCALE * ( U2_BRGREG + 1L) ) )
#if (REAL_BAUDRATE > (U2_BAUD + (U2_BAUD * 25L) / 1000L)) || (REAL_BAUDRATE < (U2_BAUD - (U2_BAUD * 25L) / 1000L))
#error UART baudrate error greater than 2.5 percent for the FCY and U2_BAUD. Correct values in uart.c file.
#endif
#undef REAL_BAUDRATE
void UART2_Init(void)
{
_U2TXIE = 0;
_U2RXIE = 0;
_U2ERIE = 0;
_U2RXIP = 0b100;
_U2TXIP = 0b100;
_U2ERIP = 0b100;
U2MODE = 0;
U2STA = 0;
U2BRG = U2_BRGREG;
U2MODEbits.BRGH = U2_BRGH_VALUE;
U2MODEbits.UARTEN = 1;
U2STAbits.UTXEN  = 1;
}
void UART2_Write(uint8_t txData)
{
while(U2STAbits.TRMT != 1);
U2TXREG = txData;    // Write the data byte to the USART.
}
/*
* hook for printf
*/
int __attribute__((__section__(".libc.write"))) write(int handle, void *buffer, unsigned int len) 
{
unsigned int i;
for (i = len; i; --i)
{
UART2_Write(*(char*)buffer++);
}
return(len);
}
/*
* Main Application
*/
int main(void) 
{
uint16_t ADC_results[sizeof(Selector)];
uint16_t ADC_value;
uint16_t NewResults;
uint16_t Index;

PIC_Init();
ADC_Init();
UART2_Init();

printf("rnPIC24FJ64GA002 start, built on %s at %srn", __DATE__, __TIME__);
/*
* Application loop
*/
NewResults = 1;
for(;;)
{
for(Index = 0; Index < sizeof(Selector); Index++)
{
ADC_value = ADC_ReadChannel(Index);
if (ADC_value != ADC_results[Index])
{
NewResults |= 1;
}
ADC_results[Index] = ADC_value;
}
if(NewResults)
{
NewResults = 0;
printf("Values");
for(Index = 0; Index < (sizeof(ADC_results)/sizeof(*ADC_results) ); Index++)
{
printf(" AN%1u = %5u", Selector[Index], ADC_results[Index]);
}
printf("rn");
}

}
return 0;
}

你在文章中没有提供足够的信息来知道你可能实际使用的是55个控制器中的哪一个。

我使用了PIC24FJ64GA002控制器,我现在可以找到它具有您可以使用的ADC硬件。

最新更新