18F4550 - acquisition analogique

Dans ce projet, nous allons introduire la notion d’acquisition numérique. Je vous propose, dans un premier temps de lire la documentation (21.0 Analog-To-Digital Converter, p.259).

Le principe du programme que nous allons créer, est d’afficher sur le port D, la tension appliquée sur le port A0 (pin2).

Les sources

Créez un nouveau projet et insérez deux fichiers:

  • config.h
  • main.c

config.h

#ifndef CONFIG_H_INCLUDED
#define CONFIG_H_INCLUDED

#include <pic18f4550.h>

// Set the __CONFIG words:
__code      __at (__CONFIG1L) _conf0   = _PLLDIV_DIVIDE_BY_5__20MHZ_INPUT__1L  & _CPUDIV__OSC1_OSC2_SRC___1__96MHZ_PLL_SRC___2__1L & _USBPLL_CLOCK_SRC_FROM_96MHZ_PLL_2_1L;  
__code      __at (__CONFIG1L) _conf1   = _OSC_HS__HS_PLL__USB_HS_1H;  
__code      __at (__CONFIG1L) _conf2   = _VREGEN_ON_2L;  
__code      __at (__CONFIG1L) _conf3   = _WDT_DISABLED_CONTROLLED_2H;  
__code      __at (__CONFIG1L) _conf4   = _PBADEN_PORTB_4_0__CONFIGURED_AS_DIGITAL_I_O_ON_RESET_3H;  
__code      __at (__CONFIG1L) _conf5   = _ENHCPU_OFF_4L & _LVP_OFF_4L ;  
__code      __at (__CONFIG1L) _conf6   = _CP_0_OFF_5L ;  
//code     char at __CONFIG5H _conf7   =
//code     char at __CONFIG6L _conf8   =
//code     char at __CONFIG6H _conf9   =
//code     char at __CONFIG7L _conf10  =
//code     char at __CONFIG7H _conf11  =

#endif // CONFIG_H_INCLUDED

main.c

/* Directive for ADC library */
#define __SDCC_PIC18F4550

#include <pic18f4550.h>
#include <adc.h>
#include "config.h"

/*

Designed for a 20MHz cristal  
Prog clock = 48MHz

*/

int getAnalogData(unsigned char channel) {  
    int result;
    /* Configure ADC module */
    adc_open(
        channel,                           /* channel : Reg ADCON0*/
        ADC_ACQT_0  | ADC_FOSC_64,         /* Manually launched,  FOSC/64  for 48MHz (table 21_1) : Reg ADCON2*/
        ADC_CFG_3A,                        /* 3 AN inputs : Reg ADCON1*/
        ADC_VCFG_VDD_VSS | ADC_FRM_RJUST   /* voltage ref = VSS and VDD, Right justified */
    );
    adc_conv ();            /* Launch conversion */
    while (adc_busy ());    /* Wait for the end of the conversion */
    result = adc_read ();    /* Get the result */
    /* stop the module */
    adc_close ();
    return result;
}

void main() {  
    // set port D as output
    TRISD=0;
    // Main loop
    while(1) {
        LATD = getAnalogData(0);
    }
}

Explication du programme

On commence par définir la constante __SDCC_PIC18F4550 afin que lors de l’inclusion de adc.h les constantes adaptées à notre microcontrolleur soient correctement initialisées.

On définit, ensuite, une fonction qui lira un canal. On entend par canal, un numéro de port. Par exemple, le canal 0 correspont au port A0, soit la broche 2 du composant. Dans cette fonction, on fait un appel à adc_open(). Cela permet de configurer le canal sur lequel nous allons effectuer l’acquisition. Ce canal devient le canal par défaut. Vient, ensuite, adc_conv() qui lance la conversion sur le canal par défaut (celui sélectionné avec adc_open()). La conversion n’est pas instantanée et n’est pas terminée lorsque la main est rendu (= lorsque l’on sort de la function adc_conv()). C’est pour ça que l’on trouve la ligne:

while (adc_busy ());    /* Wait for the end of the conversion */  

Cette ligne sert à attendre que la conversion soit terminée. Une fois la conversion faite, nous pouvons lire le résultat avec la fonction adc_read()

N’oubliez pas de faire un appel à adc_close() pour restaurer l’état du microcontrolleur.

Téléchargement

Les sources sont disponibles ici : analogic.tar.gz