Aller au contenu

Programmation sur PIC


Stude 12

Messages recommandés

Bonjour à tous, et merci de votre intérêt pour mon problème, car en langage C je suis pas terrible alors programmer un PIC ....

Voilà, je doit effectuer une conversion de voie analogique en numérique grâce au module A/N du Pic 18F4550. J'ai en tous 12 voir analogique de AN0 à AN11 ( j'utilise pas le AN12 ). Et je doit transférer vers de l'usb, le resultat.

J'aimerais traiter les 12 conversions en interruption et transmettre les 12 résultats par 1 seul envoie sur l'usb et le transmettre en ascii et pas en binaire, car convertir et envoyer juste 1 octet serait + simple à programmer mais plus long à traiter par un pc. Pour simplifier un peu j'ai prit que les 8bits de poids les + fort ( que ADRESH sur 8 bits ). Si vous pouvez m'aider un peu car perso les interruptions je maîtrise pas trop. Donc j'avoue que c'est un peu le bordel dans mon prog et pour l'instant j'essaie de faire que la voie AN0.

/** I N C L U D E S **********************************************************/

#include <p18f4550.h>

#include "typedefs.h"

#include "usb.h"

#include "io_cfg.h"

#include "usbdrv.h"

/** C O N F I G U R A T I O N ************************************************/

// Note: For a complete list of the available config pragmas and their values,

// see the compiler documentation, and/or click "Help --> Topics..." and then

// select "PIC18 Config Settings" in the Language Tools section.

#if defined(PIC18F4550_PICDEM_FS_USB) // Configuration bits for PICDEM FS USB Demo Board

#pragma config PLLDIV = 5 // (20 MHz crystal on PICDEM FS USB board)

#pragma config CPUDIV = OSC1_PLL2

#pragma config USBDIV = 2 // Clock source from 96MHz PLL/2

#pragma config FOSC = HSPLL_HS

#pragma config FCMEN = OFF

#pragma config IESO = OFF

#pragma config PWRT = OFF

#pragma config BOR = ON

#pragma config BORV = 2

#pragma config VREGEN = ON //USB Voltage Regulator

#pragma config WDT = OFF

#pragma config WDTPS = 32768

#pragma config MCLRE = ON

#pragma config LPT1OSC = OFF

#pragma config PBADEN = OFF //NOTE: modifying this value here won't have an effect

//on the application. See the top of the main() function.

//By default the RB4 I/O pin is used to detect if the

//firmware should enter the bootloader or the main application

//firmware after a reset. In order to do this, it needs to

//configure RB4 as a digital input, thereby changing it from

//the reset value according to this configuration bit.

// #pragma config CCP2MX = ON

#pragma config STVREN = ON

#pragma config LVP = OFF

// #pragma config ICPRT = OFF // Dedicated In-Circuit Debug/Programming

#pragma config XINST = OFF // Extended Instruction Set

#pragma config CP0 = OFF

#pragma config CP1 = OFF

// #pragma config CP2 = OFF

// #pragma config CP3 = OFF

#pragma config CPB = OFF

// #pragma config CPD = OFF

#pragma config WRT0 = OFF

#pragma config WRT1 = OFF

// #pragma config WRT2 = OFF

// #pragma config WRT3 = OFF

#pragma config WRTB = OFF // Boot Block Write Protection

#pragma config WRTC = OFF

// #pragma config WRTD = OFF

#pragma config EBTR0 = OFF

#pragma config EBTR1 = OFF

// #pragma config EBTR2 = OFF

// #pragma config EBTR3 = OFF

#pragma config EBTRB = OFF

#else

#error Not a supported board (yet), make sure the proper board is selected in usbcfg.h, and if so, set configuration bits in __FILE__, line __LINE__

#endif

/** V A R I A B L E S ********************************************************/

#pragma udata

/** P R I V A T E P R O T O T Y P E S ***************************************/

char *conv_char_chaine (char val); //convertie une valeur en centaine, dizaine, unité ascii

void init_timer0 (void);

void interrupt_prog_int (void);

/** D E C L A R A T I O N S **************************************************/

static volatile float input;

static volatile char res[10], asc[3], T0IF;

static volatile int i;

/******************************************************************************

* Function: void main(void)

*

* PreCondition: None

*

* Input: None

*

* Output: None

*

* Side Effects: None

*

* Overview: Main program entry point.

*

* Note: None

*****************************************************************************/

void main(void)

{

ADCON0bits.ADON = 1 ; // A/D convert ON

ADCON0bits.CHS0 = 0 ; // Choisir la voie a convertir => AN0

ADCON0bits.CHS1 = 0 ; // Choisir la voie a convertir => AN0

ADCON0bits.CHS2 = 0 ; // Choisir la voie a convertir => AN0

ADCON0bits.CHS3 = 0 ; // Choisir la voie a convertir => AN0

ADCON1bits.PCFG0 = 0 ; // Configuration des ports A/D = Tout les ports en analogique

ADCON1bits.PCFG1 = 1 ; // Configuration des ports A/D

ADCON1bits.PCFG2 = 0 ; // Configuration des ports A/D

ADCON1bits.PCFG3 = 0 ; // Configuration des ports A/D

ADCON1bits.VCFG0 = 0 ; // references de tension a utiliser par le CAN => Vref+ = Vdd

ADCON1bits.VCFG1 = 0 ; // references de tension a utiliser par le CAN => Vref- = Vss

ADCON2bits.ADCS0 = 1 ; // configurer horloge selection (pour un quartz de 20 Mhz)

ADCON2bits.ADCS1 = 0 ; // configurer horloge selection

ADCON2bits.ADCS2 = 1 ; // configurer horloge selection

ADCON2bits.ACQT0 = 0 ; // configurer un temps d'acquisition (configuration manuelle)

ADCON2bits.ACQT1 = 0 ; // configurer un temps d'acquisition

ADCON2bits.ACQT2 = 0 ; // configurer un temps d'acquisition

ADCON2bits.ADFM = 0 ; // justification à gauche

ADRESH=0x00 ; // Mise à zero du registre ADRESH

ADCON0bits.GO_DONE=1;

res[0]= 0x00; //Initialisation des buffers de résultat

i=0;

T0IF=1;

for (i=0; i<11; i++)

{

if ( T0IF )

{

ADCON0bits.GO_DONE=1;

}

if (ADCON0bits.ADON=0) // Teste bit de fin de conversion, si ADON=0 : la conversion est terminée

{

ADCON0bits.GO_DONE=0;

res=ADRESH; // On place le résultat dans un tableau

T0IF=0;

}

}

asc=conv_char_chaine(res); //Conversion binaire => ASCII

/*-----------------------------envoie des données sur le bus -----------------------------------*/

if(!mHIDTxIsBusy()) // Test si la connexion est occupée

{

HIDTxReport(asc,0); // Envoie de donnée sur l'usb fonction définie dans le hid.c

}

}//end main

/*----------------------------------------------------------------------------------------------*/

char *conv_char_chaine(char val) // Conversion binaire => ASCII

{

unsigned char uni, diz,cent,z;

char chaine[3];

if(val>=99)cent=val/100;

if(val<=99)cent=0;

z=val-cent;

if(z>=9)diz=z/10;

if(z<=9)diz=0;

diz= val-(cent*100);

uni= val-(cent*100)-(diz*10);

chaine[0]=cent|0x30;

chaine[1]=diz|0x30;

chaine[2]=uni|0x30;

return(chaine);

}

/*----------------------------------------------------------------------------------------------*/

void init_timer0 (void) // Initialisation du timer

{

T0CON.PSA =0; // Prédiviseur affecté au timer 0

T0CON.T0CS= 0; // Timer 0 utilise l'horloge interne

T0CON.PS2 = 1; // Prédivision de 256

T0CON.PS1 = 1;

T0CON.PS0= 1;

}

/*----------------------------------------------------------------------------------------------*/

void interrupt_prog_int (void)

{

if ( T0IF ) // Test sur le bit d'interruption de débordement du timer

{

T0IF = 0; // RAZ du bit de débordement

T0CON.TMR0 = 0; // RAZ du timer pour qu'il recommence à compter jusque 65536

}

}

Merci d'avance

Lien vers le commentaire
Partager sur d’autres sites

Je ne connais pas bien les PICs, mais je vois qq chose de louche dans ta boucle for

for (i=0; i<11; i++)
{

if ( T0IF )
{
ADCON0bits.GO_DONE=1;
}

if (ADCON0bits.ADON=0) // Teste bit de fin de conversion, si ADON=0 : la conversion est terminée
{
ADCON0bits.GO_DONE=0;
res[i]=ADRESH; // On place le résultat dans un tableau
T0IF=0;
}

}

Tu remplis ton tableau "res" de 11 résultats successifs de conversion sur le convertisseur 0. Déjà, ton tableau "res" est déclaré pour 10 octets et non pas 11, tu fais un dépassement.

puis

tu fais ça hors de la boucle :

asc[i]=conv_char_chaine(res[i]); //Conversion binaire => ASCII 

Non seulement tu ne recopies qu'un seul caractère, mais tu utilise en index "i" qui vaut alors 11, ça fait un dépassement pour les 2 tableaux "asc" et "res".

char *conv_char_chaine(char val) // Conversion binaire => ASCII
{
unsigned char uni, diz,cent,z;
char chaine[3];
if(val>=99)cent=val/100;
if(val<=99)cent=0;
z=val-cent;
if(z>=9)diz=z/10;
if(z<=9)diz=0;
diz= val-(cent*100);
uni= val-(cent*100)-(diz*10);
chaine[0]=cent|0x30;
chaine[1]=diz|0x30;
chaine[2]=uni|0x30;

return(chaine);
}

Là tu renvoies en sortant de ta fonction l'adresse d'un variable qui est locale à ta fonction. Ca ne peut pas marcher, car en dehors de cette fonction l'emplacement mémoire n'est pas réservé pour cette variable tu devrais plutôt faire un truc dans ce genre :

void conv_char_chaine(unsigned char val, char *chaine) // Conversion binaire non signe => ASCII
{
unsigned char uni, diz,cent,z;
if( val>99 )
{
 z=val/100
 chaine[0]=z|0x30;
 val=val-z*100;
}
else
 chaine[0]='0';
if( val>9 )
{
 z=val/10
 chaine[1]=z|0x30;
 val=val-z*10;
}
else
 chaine[1]='0';
chaine[2]=val|0x30;
}

et pour appeler ta fonction, cela donne :

conv_char_chaine(res[i], asc); //Conversion binaire => ASCII

Lien vers le commentaire
Partager sur d’autres sites

  • 2 semaines après...

J'ai fait ça en dernier :

/** P R I V A T E P R O T O T Y P E S ****************************** *********/

char *conv_char_chaine (char val); //convertie une valeur en centaine, dizaine, unité ascii

void init_timer0(void);

void interrupt_prog(void);

void interrupt_prog_conv(void);

void init_conv(void);

void sel_voix0(void);

/** V E C T O R R E M A P P I N G ****************************** *************/

/** D E C L A R A T I O N S ****************************** ********************/

static volatile float input;

static volatile char res[10], asc[3];

static volatile int i;

/****************************** ****************************** ******************

* Function: void main(void)

****************************** ****************************** *****************/

void main(void)

{

init_timer0();

init_conv();

ADRESH=0x00 ; // Mise à zero du registre ADRESH

res[0]= 0x00; // Initialisation des buffers de résultat

while (1) // Tâche de fond

{

sel_voix0(); // Selection de la voie 0 pour la conversion A/N

asc=conv_char_chaine(res); //Convertion binaire => ASCII

/*---------------------------| Envoie des données sur le bus |----------------------------------*/

if(!mHIDTxIsBusy()) // Test si la connexion est occupée

{

HIDTxReport(asc,0); // Envoie de donnée sur l'usb fonction définie dans le hid.c

}

} // fin du while (Tâche de fond)

}//end main

/*----------------------------------------------------------------------------------------------*/

char *conv_char_chaine(char val) // Conversion binaire => ASCII

{

unsigned char uni, diz,cent,z;

char chaine[3];

if(val>=99)cent=val/100;

if(val<=99)cent=0;

z=val-cent;

if(z>=9)diz=z/10;

if(z<=9)diz=0;

diz= val-(cent*100);

uni= val-(cent*100)-(diz*10);

chaine[0]=cent|0x30;

chaine[1]=diz|0x30;

chaine[2]=uni|0x30;

return(chaine);

}

/*----------------------------------------------------------------------------------------------*/

void init_timer0(void) // Initialisation du timer

{

T0CON.TMR0ON=1; // Validation du timer0

T0CON.PSA =0; // Prédiviseur affecté au timer 0

T0CON.T0CS= 0; // Timer 0 utilise l'horloge interne

T0CON.PS2 = 1; // Prédivision de 256

T0CON.PS1 = 1;

T0CON.PS0= 1;

T0CON.RP0 = 0 ; // retour au registeur bank0

T0CON.T0IE = 1; // autorise l'interruption timeur

T0CON.GIE = 1;

}

/*----------------------------------------------------------------------------------------------*/

void interrupt_prog(void)

{

if ( INTCON.TMR0IF ) // Test sur le bit d'interruption de déborment du timer

{

ADCON0bits.GO_DONE=1; // Lancement de la conversion

INTCON.TMR0IF = 0; // RAZ du bit de débordement

T0CON.TMR0 = 0; // RAZ du timer pour qu'il recommence à compter jusque 65536

}

}

/*----------------------------------------------------------------------------------------------*/

void interrupt_prog_conv(void)

{

if (ADIF==1) // Test bit de fin de convertion, si ADIF=1 : la conversion est terminée

{

ADCON0bits.GO_DONE=0; // EOC

res=ADRESH; // On place le résultat dans un tableau

}

}

/*----------------------------------------------------------------------------------------------*/

void init_conv(void)

{

ADCON0bits.ADON = 1 ; // A/D convert ON

ADCON1bits.PCFG0 = 0 ; // Configuration des ports A/D = Tout les ports en analogique

ADCON1bits.PCFG1 = 1 ; // Configuration des ports A/D

ADCON1bits.PCFG2 = 0 ; // Configuration des ports A/D

ADCON1bits.PCFG3 = 0 ; // Configuration des ports A/D

ADCON1bits.VCFG0 = 0 ; // references de tension a utiliser par le CAN => Vref+ = Vdd

ADCON1bits.VCFG1 = 0 ; // references de tension a utiliser par le CAN => Vref- = Vss

ADCON2bits.ADCS0 = 1 ; // configurer horloge selection (pour un quartz de 20 Mhz)

ADCON2bits.ADCS1 = 0 ; // configurer horloge selection

ADCON2bits.ADCS2 = 1 ; // configurer horloge selection

ADCON2bits.ACQT0 = 0 ; // configurer un temps d'acquisition (configuration manuelle)

ADCON2bits.ACQT1 = 0 ; // configurer un temps d'acquisition

ADCON2bits.ACQT2 = 0 ; // configurer un temps d'acquisition

ADCON2bits.ADFM = 0 ; // justification à gauche

}

/*----------------------------------------------------------------------------------------------*/

void sel_voix0(void)

{

ADCON0bits.CHS0 = 0 ; // Choisir la voie a convertir => AN0

ADCON0bits.CHS1 = 0 ; // Choisir la voie a convertir => AN0

ADCON0bits.CHS2 = 0 ; // Choisir la voie a convertir => AN0

ADCON0bits.CHS3 = 0 ; // Choisir la voie a convertir => AN0

}

Oui j'utilise Mplab V8 et le compilateur MCC 18 ou un truc comme ça ( car je fait ça pour les études et là je suis en vac alors..... )

Lien vers le commentaire
Partager sur d’autres sites

Deja pour ton interruption timer0 je ferais ca :

#pragma code it = 0x08 // Adresse memoire des interruptions

void it(void)

{

_asm

goto sp_int // Routine d'interruption

_endasm

}

#pragma code

#pragma interrupt sp_int

void sp_int(void)

{

if(INTCONbits.TMR0IF==1) // Test si interruption de TMR0

{

INTCONbits.TMR0IF=0; // Effacement du flag TRM0

// Code a executer

}

}

je penses pas que tu aies besoin de faire un RAZ du timer il doit le faire automatiquement quand il depasse.

Tu peux utilisé les librairies MCC18 qui sont tres pratiques.

#include <usart.h>

#include <timers.h>

#include <adc.h>

et companie : http://ww1.microchip.com/downloads/en/devicedoc/51297c.pdf

Lien vers le commentaire
Partager sur d’autres sites

BON, j'ai un peu travaillé dessus, et parcontre je préfère laisser mes lignes de code pour l'init des interruptions, il y as juste la ligne retour en bank0 ui est fausse car je trouve aucune fonction dans la documentation qui le fait mais est-ce néccéssaire ? Et le raz timer bien pour l'instant je le met à zero mais après, je chargerais une valeur dedans afin d'optimiser le tout donc je préfère laissez comme je fait. Sinon le compilateur me genère des erreur sur l'envoie de donner sur l'USB, je doit pas avoir la bonne fonction ?

/** V A R I A B L E S ********************************************************/

#pragma udata

/** P R I V A T E P R O T O T Y P E S ***************************************/

void conv_char_chaine (unsigned char val, char *chaine); //convertie une valeur en centaine, dizaine, unité ascii

void init_timer0(void);

void interrupt_prog(void);

void interrupt_prog_conv(void);

void init_conv(void);

void sel_voix(int voix);

/** V E C T O R R E M A P P I N G *******************************************/

/** D E C L A R A T I O N S **************************************************/

static volatile float input;

static volatile char res[10], asc[3];

static volatile int i;

/******************************************************************************

* Function: void main(void)

*****************************************************************************/

void main(void)

{

init_timer0();

init_conv();

ADRESH=0x00 ; // Mise à zero du registre ADRESH

res[0]= 0x00; // Initialisation des buffers de résultat

while (1) // Tâche de fond

{

sel_voix(0); // Selection de la voie 0 pour la conversion A/N

conv_char_chaine(res, asc); // Convertion binaire => ASCII

sel_voix(1);

/*---------------------------| Envoie des données sur le bus |----------------------------------*/

if(!mHIDTxIsBusy()) // Test si la connexion est occupée

{

HIDTxReport(asc,0); // Envoie de donnée sur l'usb fonction définie dans le hid.c

}

} // fin du while (Tâche de fond)

}//end main

/*----------------------------------------------------------------------------------------------*/

void conv_char_chaine(unsigned char val, char *chaine) // Conversion binaire => ASCII

{

unsigned char uni, diz,cent,z;

if(val>99)

{

z=val/100;

chaine[0]=z|0x30;

val= val-(z*100);

}

else

chaine[0]= '0';

if(val>9)

{

z=val/10;

chaine[1]=z|0x30;

val= val-(z*10);

}

else

chaine[1]= '0';;

chaine[2]=val|0x30;

}

/*----------------------------------------------------------------------------------------------*/

void init_timer0(void) // Initialisation du timer

{

T0CONbits.TMR0ON=1; // Validation du timer0

T0CONbits.PSA =0; // Prédiviseur affecté au timer 0

T0CONbits.T0CS= 0; // Timer 0 utilise l'horloge interne

T0CONbits.T0PS2 = 1; // Prédivision de 256

T0CONbits.T0PS1 = 1;

T0CONbits.T0PS0= 1;

INTCONbits.RP0 = 0 ; // retour au registre bank0

INTCONbits.INT0IE = 1; // autorise l'interruption timeur

INTCONbits.GIE = 1;

}

/*----------------------------------------------------------------------------------------------*/

void interrupt_prog(void)

{

if ( INTCONbits.TMR0IF ) // Test sur le bit d'interruption de déborment du timer

{

ADCON0bits.GO_DONE=1; // Lancement de la conversion

INTCONbits.TMR0IF = 0; // RAZ du bit de débordement

TMR0L = 0x00;

TMR0H = 0x00;// RAZ du timer pour qu'il recommence à compter jusque 65536

}

}

/*----------------------------------------------------------------------------------------------*/

void interrupt_prog_conv(void)

{

if (PIR1bits.ADIF) // Test bit de fin de convertion, si ADIF=1 : la conversion est terminée

{

ADCON0bits.GO_DONE=0; // EOC

res=ADRESH; // On place le résultat dans un tableau

}

}

/*----------------------------------------------------------------------------------------------*/

void init_conv(void)

{

ADCON0bits.ADON = 1 ; // A/D convert ON

ADCON1bits.PCFG0 = 0 ; // Configuration des ports A/D = Tout les ports en analogique

ADCON1bits.PCFG1 = 1 ; // Configuration des ports A/D

ADCON1bits.PCFG2 = 0 ; // Configuration des ports A/D

ADCON1bits.PCFG3 = 0 ; // Configuration des ports A/D

ADCON1bits.VCFG0 = 0 ; // references de tension a utiliser par le CAN => Vref+ = Vdd

ADCON1bits.VCFG1 = 0 ; // references de tension a utiliser par le CAN => Vref- = Vss

ADCON2bits.ADCS0 = 1 ; // configurer horloge selection (pour un quartz de 20 Mhz)

ADCON2bits.ADCS1 = 0 ; // configurer horloge selection

ADCON2bits.ADCS2 = 1 ; // configurer horloge selection

ADCON2bits.ACQT0 = 0 ; // configurer un temps d'acquisition (configuration manuelle)

ADCON2bits.ACQT1 = 0 ; // configurer un temps d'acquisition

ADCON2bits.ACQT2 = 0 ; // configurer un temps d'acquisition

ADCON2bits.ADFM = 0 ; // justification à gauche

}

/*----------------------------------------------------------------------------------------------*/

void sel_voix(int voix)

{

switch(voix){

case 0:ADCON0bits.CHS0 = 0 ; // Choisir la voie a convertir => AN0

ADCON0bits.CHS1 = 0 ; // Choisir la voie a convertir => AN0

ADCON0bits.CHS2 = 0 ; // Choisir la voie a convertir => AN0

ADCON0bits.CHS3 = 0 ; /* Choisir la voie a convertir => AN0*/ ;break;

case 1:ADCON0bits.CHS0 = 1 ; // Choisir la voie a convertir => AN0

ADCON0bits.CHS1 = 0 ; // Choisir la voie a convertir => AN0

ADCON0bits.CHS2 = 0 ; // Choisir la voie a convertir => AN0

ADCON0bits.CHS3 = 0 ; /* Choisir la voie a convertir => AN0*/ ;break;

case 2:ADCON0bits.CHS0 = 0 ; // Choisir la voie a convertir => AN0

ADCON0bits.CHS1 = 1 ; // Choisir la voie a convertir => AN0

ADCON0bits.CHS2 = 0 ; // Choisir la voie a convertir => AN0

ADCON0bits.CHS3 = 0 ; /* Choisir la voie a convertir => AN0*/ ;break;

case 3:ADCON0bits.CHS0 = 1 ; // Choisir la voie a convertir => AN0

ADCON0bits.CHS1 = 1 ; // Choisir la voie a convertir => AN0

ADCON0bits.CHS2 = 0 ; // Choisir la voie a convertir => AN0

ADCON0bits.CHS3 = 0 ; /* Choisir la voie a convertir => AN0*/ ;break;

case 4:ADCON0bits.CHS0 = 0 ; // Choisir la voie a convertir => AN0

ADCON0bits.CHS1 = 0 ; // Choisir la voie a convertir => AN0

ADCON0bits.CHS2 = 1 ; // Choisir la voie a convertir => AN0

ADCON0bits.CHS3 = 0 ; /* Choisir la voie a convertir => AN0*/ ;break;

case 5:ADCON0bits.CHS0 = 1 ; // Choisir la voie a convertir => AN0

ADCON0bits.CHS1 = 0 ; // Choisir la voie a convertir => AN0

ADCON0bits.CHS2 = 1 ; // Choisir la voie a convertir => AN0

ADCON0bits.CHS3 = 0 ; /* Choisir la voie a convertir => AN0*/ ;break;

case 6:ADCON0bits.CHS0 = 0 ; // Choisir la voie a convertir => AN0

ADCON0bits.CHS1 = 1 ; // Choisir la voie a convertir => AN0

ADCON0bits.CHS2 = 1 ; // Choisir la voie a convertir => AN0

ADCON0bits.CHS3 = 0 ; /* Choisir la voie a convertir => AN0*/ ;break;

case 7:ADCON0bits.CHS0 = 1 ; // Choisir la voie a convertir => AN0

ADCON0bits.CHS1 = 1 ; // Choisir la voie a convertir => AN0

ADCON0bits.CHS2 = 1 ; // Choisir la voie a convertir => AN0

ADCON0bits.CHS3 = 0 ; /* Choisir la voie a convertir => AN0*/ ;break;

case 8:ADCON0bits.CHS0 = 0 ; // Choisir la voie a convertir => AN0

ADCON0bits.CHS1 = 0 ; // Choisir la voie a convertir => AN0

ADCON0bits.CHS2 = 0 ; // Choisir la voie a convertir => AN0

ADCON0bits.CHS3 = 1 ; /* Choisir la voie a convertir => AN0*/ ;break;

case 9:ADCON0bits.CHS0 = 1 ; // Choisir la voie a convertir => AN0

ADCON0bits.CHS1 = 0 ; // Choisir la voie a convertir => AN0

ADCON0bits.CHS2 = 0 ; // Choisir la voie a convertir => AN0

ADCON0bits.CHS3 = 1 ; /* Choisir la voie a convertir => AN0*/ ;break;

case 10:ADCON0bits.CHS0 = 0 ; // Choisir la voie a convertir => AN0

ADCON0bits.CHS1 = 1 ; // Choisir la voie a convertir => AN0

ADCON0bits.CHS2 = 0 ; // Choisir la voie a convertir => AN0

ADCON0bits.CHS3 = 1 ; /* Choisir la voie a convertir => AN0*/ ;break;

case 11:ADCON0bits.CHS0 = 1 ; // Choisir la voie a convertir => AN0

ADCON0bits.CHS1 = 1 ; // Choisir la voie a convertir => AN0

ADCON0bits.CHS2 = 0 ; // Choisir la voie a convertir => AN0

ADCON0bits.CHS3 = 1 ; /* Choisir la voie a convertir => AN0*/ ;break;

case 12:ADCON0bits.CHS0 = 0 ; // Choisir la voie a convertir => AN0

ADCON0bits.CHS1 = 0 ; // Choisir la voie a convertir => AN0

ADCON0bits.CHS2 = 1 ; // Choisir la voie a convertir => AN0

ADCON0bits.CHS3 = 1 ; /* Choisir la voie a convertir => AN0*/ ;break;

}

}

IL me reste donc à bien récuperer les informations de chaque, les mettres en ascii et envoyer tout en 1 seul fois, car là dans mon main il me manque des trucs.

Lien vers le commentaire
Partager sur d’autres sites

J ai pas vu ou tu utilisais les pragma dans ton code. Faut faire comme j ai mis plus haut sinon il trouvera pas le code a exectuer quand t aura une interruption.

Pour l USB je peux pas t aider car je l avais pas utiliser. Regarde dans les bibliotheque MCC18 comme je t ai mis plus haut doit y avoir des fonctions tout faites.

Lien vers le commentaire
Partager sur d’autres sites

  • 1 mois après...
Bonjour à tous, et merci de votre intérêt pour mon problème, car en langage C je suis pas terrible alors programmer un PIC ....

Voilà, je doit effectuer une conversion de voie analogique en numérique grâce au module A/N du Pic 18F4550. J'ai en tous 12 voir analogique de AN0 à AN11 ( j'utilise pas le AN12 ). Et je doit transférer vers de l'usb, le resultat.

J'aimerais traiter les 12 conversions en interruption et transmettre les 12 résultats par 1 seul envoie sur l'usb et le transmettre en ascii et pas en binaire, car convertir et envoyer juste 1 octet serait + simple à programmer mais plus long à traiter par un pc. Pour simplifier un peu j'ai prit que les 8bits de poids les + fort ( que ADRESH sur 8 bits ). Si vous pouvez m'aider un peu car perso les interruptions je maîtrise pas trop. Donc j'avoue que c'est un peu le bordel dans mon prog et pour l'instant j'essaie de faire que la voie AN0.

/** I N C L U D E S **********************************************************/

#include <p18f4550.h>

#include "typedefs.h"

#include "usb.h"

#include "io_cfg.h"

#include "usbdrv.h"

/** C O N F I G U R A T I O N ************************************************/

// Note: For a complete list of the available config pragmas and their values,

// see the compiler documentation, and/or click "Help --> Topics..." and then

// select "PIC18 Config Settings" in the Language Tools section.

#if defined(PIC18F4550_PICDEM_FS_USB) // Configuration bits for PICDEM FS USB Demo Board

#pragma config PLLDIV = 5 // (20 MHz crystal on PICDEM FS USB board)

#pragma config CPUDIV = OSC1_PLL2

#pragma config USBDIV = 2 // Clock source from 96MHz PLL/2

#pragma config FOSC = HSPLL_HS

#pragma config FCMEN = OFF

#pragma config IESO = OFF

#pragma config PWRT = OFF

#pragma config BOR = ON

#pragma config BORV = 2

#pragma config VREGEN = ON //USB Voltage Regulator

#pragma config WDT = OFF

#pragma config WDTPS = 32768

#pragma config MCLRE = ON

#pragma config LPT1OSC = OFF

#pragma config PBADEN = OFF //NOTE: modifying this value here won't have an effect

//on the application. See the top of the main() function.

//By default the RB4 I/O pin is used to detect if the

//firmware should enter the bootloader or the main application

//firmware after a reset. In order to do this, it needs to

//configure RB4 as a digital input, thereby changing it from

//the reset value according to this configuration bit.

// #pragma config CCP2MX = ON

#pragma config STVREN = ON

#pragma config LVP = OFF

// #pragma config ICPRT = OFF // Dedicated In-Circuit Debug/Programming

#pragma config XINST = OFF // Extended Instruction Set

#pragma config CP0 = OFF

#pragma config CP1 = OFF

// #pragma config CP2 = OFF

// #pragma config CP3 = OFF

#pragma config CPB = OFF

// #pragma config CPD = OFF

#pragma config WRT0 = OFF

#pragma config WRT1 = OFF

// #pragma config WRT2 = OFF

// #pragma config WRT3 = OFF

#pragma config WRTB = OFF // Boot Block Write Protection

#pragma config WRTC = OFF

// #pragma config WRTD = OFF

#pragma config EBTR0 = OFF

#pragma config EBTR1 = OFF

// #pragma config EBTR2 = OFF

// #pragma config EBTR3 = OFF

#pragma config EBTRB = OFF

#else

#error Not a supported board (yet), make sure the proper board is selected in usbcfg.h, and if so, set configuration bits in __FILE__, line __LINE__

#endif

/** V A R I A B L E S ********************************************************/

#pragma udata

/** P R I V A T E P R O T O T Y P E S ***************************************/

char *conv_char_chaine (char val); //convertie une valeur en centaine, dizaine, unité ascii

void init_timer0 (void);

void interrupt_prog_int (void);

/** D E C L A R A T I O N S **************************************************/

static volatile float input;

static volatile char res[10], asc[3], T0IF;

static volatile int i;

/******************************************************************************

* Function: void main(void)

*

* PreCondition: None

*

* Input: None

*

* Output: None

*

* Side Effects: None

*

* Overview: Main program entry point.

*

* Note: None

*****************************************************************************/

void main(void)

{

ADCON0bits.ADON = 1 ; // A/D convert ON

ADCON0bits.CHS0 = 0 ; // Choisir la voie a convertir => AN0

ADCON0bits.CHS1 = 0 ; // Choisir la voie a convertir => AN0

ADCON0bits.CHS2 = 0 ; // Choisir la voie a convertir => AN0

ADCON0bits.CHS3 = 0 ; // Choisir la voie a convertir => AN0

ADCON1bits.PCFG0 = 0 ; // Configuration des ports A/D = Tout les ports en analogique

ADCON1bits.PCFG1 = 1 ; // Configuration des ports A/D

ADCON1bits.PCFG2 = 0 ; // Configuration des ports A/D

ADCON1bits.PCFG3 = 0 ; // Configuration des ports A/D

ADCON1bits.VCFG0 = 0 ; // references de tension a utiliser par le CAN => Vref+ = Vdd

ADCON1bits.VCFG1 = 0 ; // references de tension a utiliser par le CAN => Vref- = Vss

ADCON2bits.ADCS0 = 1 ; // configurer horloge selection (pour un quartz de 20 Mhz)

ADCON2bits.ADCS1 = 0 ; // configurer horloge selection

ADCON2bits.ADCS2 = 1 ; // configurer horloge selection

ADCON2bits.ACQT0 = 0 ; // configurer un temps d'acquisition (configuration manuelle)

ADCON2bits.ACQT1 = 0 ; // configurer un temps d'acquisition

ADCON2bits.ACQT2 = 0 ; // configurer un temps d'acquisition

ADCON2bits.ADFM = 0 ; // justification à gauche

ADRESH=0x00 ; // Mise à zero du registre ADRESH

ADCON0bits.GO_DONE=1;

res[0]= 0x00; //Initialisation des buffers de résultat

i=0;

T0IF=1;

for (i=0; i<11; i++)

{

if ( T0IF )

{

ADCON0bits.GO_DONE=1;

}

if (ADCON0bits.ADON=0) // Teste bit de fin de conversion, si ADON=0 : la conversion est terminée

{

ADCON0bits.GO_DONE=0;

res=ADRESH; // On place le résultat dans un tableau

T0IF=0;

}

}

asc=conv_char_chaine(res); //Conversion binaire => ASCII

/*-----------------------------envoie des données sur le bus -----------------------------------*/

if(!mHIDTxIsBusy()) // Test si la connexion est occupée

{

HIDTxReport(asc,0); // Envoie de donnée sur l'usb fonction définie dans le hid.c

}

}//end main

/*----------------------------------------------------------------------------------------------*/

char *conv_char_chaine(char val) // Conversion binaire => ASCII

{

unsigned char uni, diz,cent,z;

char chaine[3];

if(val>=99)cent=val/100;

if(val<=99)cent=0;

z=val-cent;

if(z>=9)diz=z/10;

if(z<=9)diz=0;

diz= val-(cent*100);

uni= val-(cent*100)-(diz*10);

chaine[0]=cent|0x30;

chaine[1]=diz|0x30;

chaine[2]=uni|0x30;

return(chaine);

}

/*----------------------------------------------------------------------------------------------*/

void init_timer0 (void) // Initialisation du timer

{

T0CON.PSA =0; // Prédiviseur affecté au timer 0

T0CON.T0CS= 0; // Timer 0 utilise l'horloge interne

T0CON.PS2 = 1; // Prédivision de 256

T0CON.PS1 = 1;

T0CON.PS0= 1;

}

/*----------------------------------------------------------------------------------------------*/

void interrupt_prog_int (void)

{

if ( T0IF ) // Test sur le bit d'interruption de débordement du timer

{

T0IF = 0; // RAZ du bit de débordement

T0CON.TMR0 = 0; // RAZ du timer pour qu'il recommence à compter jusque 65536

}

}

Merci d'avance

j'ai fait la compilation de ton code j'ai eu ca :)

C:\Documents and Settings\oussama\Bureau\projet3\projet3.c:86:Warni ng [2066] type qualifier mismatch in assignment

C:\Documents and Settings\oussama\Bureau\projet3\projet3.c:114:Erro r [1151] struct or union object designator expected

C:\Documents and Settings\oussama\Bureau\projet3\projet3.c:115:Erro r [1151] struct or union object designator expected

C:\Documents and Settings\oussama\Bureau\projet3\projet3.c:116:Erro r [1151] struct or union object designator expected

C:\Documents and Settings\oussama\Bureau\projet3\projet3.c:117:Erro r [1151] struct or union object designator expected

C:\Documents and Settings\oussama\Bureau\projet3\projet3.c:118:Erro r [1151] struct or union object designator expected

C:\Documents and Settings\oussama\Bureau\projet3\projet3.c:119:Erro r [1151] struct or union object designator expected

C:\Documents and Settings\oussama\Bureau\projet3\projet3.c:120:Erro r [1151] struct or union object designator expected

C:\Documents and Settings\oussama\Bureau\projet3\projet3.c:121:Erro r [1151] struct or union object designator expected

C:\Documents and Settings\oussama\Bureau\projet3\projet3.c:122:Erro r [1151] struct or union object designator expected

C:\Documents and Settings\oussama\Bureau\projet3\projet3.c:129:Erro r [1151] struct or union object designator expected

C:\Documents and Settings\oussama\Bureau\projet3\projet3.c:132:Erro r [1151] struct or union object designator expected

C:\Documents and Settings\oussama\Bureau\projet3\projet3.c:133:Erro r [1151] struct or union object designator expected

C:\Documents and Settings\oussama\Bureau\projet3\projet3.c:141:Erro r [1105] symbol 'ADIF' has not been defined

Halting build on first failure as requested.

BUILD FAILED: Fri Apr 03 18:47:45 2009

void init_timer0(void)

{

T0CON.TMR0ON=1;

T0CON.PSA =0;

T0CON.T0CS= 0;

T0CON.PS2 = 1;

T0CON.PS1 = 1;

T0CON.PS0= 1;

T0CON.RP0 = 0 ;

T0CON.T0IE = 1;

T0CON.GIE = 1;

Lien vers le commentaire
Partager sur d’autres sites

Archivé

Ce sujet est désormais archivé et ne peut plus recevoir de nouvelles réponses.

×
×
  • Créer...