IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Embarqué Discussion :

Problème de programmation PIC via mikroC [PIC]


Sujet :

Embarqué

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2018
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2018
    Messages : 54
    Points : 18
    Points
    18
    Par défaut Problème de programmation PIC via mikroC
    Bonjour,
    Je débute en électronique, j'ai plusieurs petits projet à réaliser.
    Et ici je n'arrive pas à simplifier mon chenillard, si quelqu'un sait m'aider, ma boucle ne fonctionne pas comme en C classique j'ai l'impression.
    Cordialement.

    Code sur MikroC
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    #include <stdio.h>
    // Prototypes
    void LED1() ; // Sous-programme LED1
     
    //*********************************************
     
    void main() {
     TRISA = 0b00000010; //port A en sortie sauf RA1
     PORTA = 0b11001000 ; //mettre les sorties à zéro sauf RA6, RA7,RA3
     TRISB = 0b00000001; //port B en sortie sauf RB_0
     PORTB = 0 ; //mettre les sorties à zéro
     pcon.OSCF = 1; //configure le bit 3 du registre pcon pour 4 Mhz
     CMCON = 0b00000111; //désactiver les comparateurs sur RA0
     while(1)  //boucle infinie
     {
      if (RB0_bit==0) { //si RB0 = 0 exécuter la ligne suivante
       LED1(void) ; //Sous-programme LED1
     } //fin du SI
    }
    }
     
    //*********************************************
    void LED1(){
     int tabLED[8]={RA0_bit,RB1_bit,RB2_bit,RB3_bit,RB4_bit,RB5_bit,RB6_bit,RB7_bit};
     int i=0;
     for (i = 0 ; i < 8 ; i++)
     {
      tabLED[i] = 1 ;
      delay_ms(250);
      tabLED[i] = 0 ;
     }
    }
    /*
    //sous-programme
    void LED1(){ // Début du Sous-programme LED1, on allume et éteind les leds de D4 à D11 l'une après l'autre
     RA0_bit = 1 ;    //sortie RA0 à 1
     delay_ms(250);   //delai d'1/4 sec
     RA0_bit = 0 ;    //sortie RA0 à 0
     RB1_bit = 1 ;
     delay_ms(250);
     RB1_bit = 0 ;
     RB2_bit = 1 ;
     delay_ms(250);
     RB2_bit = 0 ;
     RB3_bit = 1 ;
     delay_ms(250);
     RB3_bit = 0 ;
     RB4_bit = 1 ;
     delay_ms(250);
     RB4_bit = 0 ;
     RB5_bit = 1 ;
     delay_ms(250);
     RB5_bit = 0 ;
     RB6_bit = 1 ;
     delay_ms(250);
     RB6_bit = 0 ;
     RB7_bit = 1 ;
     delay_ms(250);
     RB7_bit = 0 ;
    } // Fin du sous-programme LED1 */

    Schéma Proteus
    Nom : schema proteus.PNG
Affichages : 932
Taille : 44,4 Ko

  2. #2
    Modérateur

    Homme Profil pro
    Ingénieur électricien
    Inscrit en
    Septembre 2008
    Messages
    1 267
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur électricien

    Informations forums :
    Inscription : Septembre 2008
    Messages : 1 267
    Points : 4 829
    Points
    4 829
    Par défaut
    Bonjour

    Le problème c'est que que le tableau stock les valeurs et non les adresses des E/S
    A la ligne 24, c'est les valeurs en cours des pins qui vont être stockées, puis dans la boucle for c'est les valeurs du tableau qui sont modifiées et c'est tout.

    Il faut passer par des pointeurs. Sur le principe, il faut stocker les pointeurs vers RXn_bit en ligne 24 et déréférencer le tableau lors de l'affectation dans la boucle for.
    Sauf que la norme C ne prévoit pas le travail sur des bits de base cette opération n'est pas possible. Ne travaillant pas sur PIC, je ne sais pas comment cela est spécifiquement implémenté dans le compilateur de cette architecture. (RA0_bit = 1 ; n'est pas conforme à la norme, car c'est une affectation sur un registre d'un seul bit, spécialité de l'embarqué chaque compilateur le traite à sa sauce.)

    A voir si un spécialiste des PIC passe par ici.

    Bonne suite

    Delias

  3. #3
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2018
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2018
    Messages : 54
    Points : 18
    Points
    18
    Par défaut
    Je comprends ce que tu veux dire, mais je ne vois pas comment le résoudre :/

  4. #4
    Modérateur

    Avatar de Vincent PETIT
    Homme Profil pro
    Consultant en Systèmes Embarqués
    Inscrit en
    Avril 2002
    Messages
    3 187
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Consultant en Systèmes Embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2002
    Messages : 3 187
    Points : 11 568
    Points
    11 568
    Par défaut
    Salut,
    int tabLED[8]={RA0_bit,RB1_bit,RB2_bit,RB3_bit,RB4_bit,RB5_bit,RB6_bit,RB7_bit}; devrait être un tableau d'adresse ou de pointeur. Là tel que que tu le fais dans ta boucle, tu écrases simplement tous les éléments de ton tableau par des 1 et de 0 alors que ce que tu veux c'est affecter 1 ou 0 à une liste de pointeurs qui se trouve dans le tableau.

    Tu peux nous dire ce qu'est RA0_bit ? Comment il est définit dans le compilateur ?
    La science ne nous apprend rien : c'est l'expérience qui nous apprend quelque chose.
    Richard Feynman

  5. #5
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2018
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2018
    Messages : 54
    Points : 18
    Points
    18
    Par défaut
    Voici mon schéma Nom : schema proteus.PNG
Affichages : 1064
Taille : 44,4 Ko

  6. #6
    Modérateur

    Homme Profil pro
    Ingénieur électricien
    Inscrit en
    Septembre 2008
    Messages
    1 267
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur électricien

    Informations forums :
    Inscription : Septembre 2008
    Messages : 1 267
    Points : 4 829
    Points
    4 829
    Par défaut
    Bonsoir

    J'ai cherché un peu plus, et comme je le pensais RA0_bit est un alias vers PORTA.bits.0 selon une autre notation usuelle. CàD un bit d'un registre de 8 bits (dont certains sont éventuellement non existant si le port n'a pas 8 pins). C'est déclaré comme une structure d'entier à taille de 1 bit dont l'adresse est la même que le PORTx.

    Et donc il n'est pas possible de manier les RXn_bit directement avec des pointeurs.
    Il faut stocker deux éléments: les pointeurs vers les registres de 8 bits (&PORTA et &PORTB) et les masques (bit 0 c'est 1<<0 = 1; bit 1 c'est 1<<1 = 2; bit 2 c'est 1<<2 = 4; etc.) puis utiliser des opérations avec masquage du type PORTA |= masque; // mise à 1 et PORTA &= ~masque; // mise à 0. Sans garantie, il faut que la lecture de PORTA donne bien la valeur écrite dans PORTA avant.

    Source: define pointer variable to a bit in PORTx | Microchip

    Bonne suite

    Delias

  7. #7
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2018
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2018
    Messages : 54
    Points : 18
    Points
    18
    Par défaut
    J'ai vraiment du mal à comprendre comment faire. Mais le schéma m'est imposé.
    Et là je dois faire une boucle et après également un chenillard..

  8. #8
    Modérateur

    Homme Profil pro
    Ingénieur électricien
    Inscrit en
    Septembre 2008
    Messages
    1 267
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur électricien

    Informations forums :
    Inscription : Septembre 2008
    Messages : 1 267
    Points : 4 829
    Points
    4 829
    Par défaut
    Bonsoir

    La notation RXn_bit est un raccourcis vers une double information, le port X et le bit n de ce port.
    Le compilateur sait traiter cela donc on peut écrire RXn_bit = voo; ou voo = RXn_bit;, et c'est le compilateur qui fait le job (c'est adressé à la compilation). Mais on ne peut pas stocker cette double information dans un seul pointeur (ou variable) et le traiter à l’exécution.

    De manière brute, non optimisée il faut stocker ces deux informations dans une structure
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    struct portBit{
        unsigned char *port;
        unsigned char bit;
    };
    et en faire un tableau.
    L'accès se fera de la sorte.
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    *tableau[i].port |= 1 << tableau[i].bit; //pour mettre à 1
    *tableau[i].port &= ~(1 << tableau[i].bit); //pour mettre à 0
    Ecrit sans filet, je ne suis pas certain de la syntaxe du déréférencement.

    Bonne suite

    Delias

  9. #9
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2018
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2018
    Messages : 54
    Points : 18
    Points
    18
    Par défaut
    Ça ne fonctionne pas, ou je le mets mal...
    Je cherche juste à mettre ceci sous forme de boucle pour éviter la répétition


    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    //sous-programme
    void LED1(){ // Début du Sous-programme LED1, on allume et éteind les leds de D4 à D11 l'une après l'autre
     RA0_bit = 1 ;    //sortie RA0 à 1
     delay_ms(250);   //delai d'1/4 sec
     RA0_bit = 0 ;    //sortie RA0 à 0
     RB1_bit = 1 ;
     delay_ms(250);
     RB1_bit = 0 ;
     RB2_bit = 1 ;
     delay_ms(250);
     RB2_bit = 0 ;
     RB3_bit = 1 ;
     delay_ms(250);
     RB3_bit = 0 ;
     RB4_bit = 1 ;
     delay_ms(250);
     RB4_bit = 0 ;
     RB5_bit = 1 ;
     delay_ms(250);
     RB5_bit = 0 ;
     RB6_bit = 1 ;
     delay_ms(250);
     RB6_bit = 0 ;
     RB7_bit = 1 ;
     delay_ms(250);
     RB7_bit = 0 ;
    } // Fin du sous-programme LED1 */

  10. #10
    Modérateur

    Homme Profil pro
    Ingénieur électricien
    Inscrit en
    Septembre 2008
    Messages
    1 267
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur électricien

    Informations forums :
    Inscription : Septembre 2008
    Messages : 1 267
    Points : 4 829
    Points
    4 829
    Par défaut
    Bonsoir

    Du fait de sa déclaration très spéciale RXn_bit n'est utilisable que en adressage directe et n'est pas adressable en indirect (c'est à dire par pointeur).

    Explication par l'exemple
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    RA0_bit = 1; // adressage direct est valide
     
    unsigned char *pin = @RA0_bit;
    *pin = 1; // adressage indirect n'est pas valide

    Or pour passer par un tableau, il faut passer par un adressage indirect et donc il faut que le deuxième exemple de code soit valide (et il l'est pour tous les registres à 8 bits tel que PORTA). A noter que selon l'explication donnée sur le lien plus haut cette opération n'est également pas possible en assembleur, c'est le cœur du PIC qui ne sait pas le faire (et c'est le cas sur 99.99...% des architectures).

    Je ne t'ai pas donné l'entier de la réponse, juste les pistes pour y arriver.

    Bon pour finir, un code qui fonctionne sur ATTiny2313. J'avais envie d'essayer, voir comment prendre le pointeur d'un port.
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    #define F_CPU 4000000UL
     
    #include <avr/io.h>
    #include <util/delay.h>
     
     
    int main(void)
    {
        /* Replace with your application code */
    	PORTB = 0x00;
    	DDRB = 0xFF;
    	PORTD = 0x00;
    	DDRD = 0x07;
     
    	struct pin {
    		uint8_t *Port;
    		uint8_t bit;
    		};
     
    	const struct pin tableau[11] = {{&PORTB, 0}, {&PORTB, 1}, {&PORTB, 2}, {&PORTB, 3}, {&PORTB, 4}, {&PORTB, 5}, {&PORTB, 6}, {&PORTB, 7}, {&PORTD, 0}, {&PORTD, 1}, {&PORTD, 2}};
     
        while (1) 
        {
    		for (uint8_t i = 0; i<11 ; i++)
    		{
    			*tableau[i].Port |= 1 << tableau[i].bit;
    			_delay_ms(250);
    			*tableau[i].Port &= ~(1 << tableau[i].bit);
    		}
        }
    }

    A part le nom des registres, il doit fonctionner pareil sur PIC.

    Mais ce n'est pas la résolution classique de ce genre d’exercice.
    Les codes types sont plutôt de ce genre:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    void LED1()
    {
    	for (uint8_t i = 0; i<11 ; i++)
    	{
    		//calcul en fonction de i
    		PORTA = f_a(i);
    		PORTB = f_b(i);
    		delay_ms(250);
    	}
    }

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    void LED2()
    {
    	uint16_t etat = 0;
    	while (1)
    	{
    		//calcul du nouvel état depuis l'état précédent
    		etat = f_etat(etat);
    		PORTA = fa(etat);
    		PORTB = fb(etat);
    		delay_ms(250);
    	}
    }
    L'intelligence étant dans les fonctions f_a(); et f_b(); dans le premier cas ou dans f_etat(); dans le second cas. Dans le deuxième cas fa(); et fb(); ne servent qu'à découper l'état entre les deux ports (par exemple etat & 0x00FF; et etat & 0x0700 >> 8;)

    Bonne suite

    Delias

  11. #11
    Modérateur

    Avatar de Vincent PETIT
    Homme Profil pro
    Consultant en Systèmes Embarqués
    Inscrit en
    Avril 2002
    Messages
    3 187
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Consultant en Systèmes Embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2002
    Messages : 3 187
    Points : 11 568
    Points
    11 568
    Par défaut
    Salut,
    Superbe analyse Delias et c'est vrai que ça se corse à cause de la déclaration de RA0_bit, je propose donc d'aborder le problème par un autre angle.

    Au lieu d'essayer de faire défiler les broches du PIC dans un tableau, fait plutôt défiler la donnée à afficher.

    C'est à dire créait une fonction "affichage" dont chaque bit de la donnée est fixé sur les RAx_bit et intervient sur la donnée.

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    /* data sur 16 bits car le chenillard a 12 Leds 
      Exemple pour la led D0
      0000 0000 0000 0000 data
    & 0000 0000 0000 0001 masque
     */
    RA3_bit = data & 0x0001;
    RA6_bit = data & 0x0002;
    RA7_bit = data & 0x0008;
    RA0_bit = data & 0x0010;
    ...
    ...

    Et ensuite c'est data qui tourne (buffer tournant ou autre et opérateur décalage)
    La science ne nous apprend rien : c'est l'expérience qui nous apprend quelque chose.
    Richard Feynman

  12. #12
    Modérateur

    Homme Profil pro
    Ingénieur électricien
    Inscrit en
    Septembre 2008
    Messages
    1 267
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur électricien

    Informations forums :
    Inscription : Septembre 2008
    Messages : 1 267
    Points : 4 829
    Points
    4 829
    Par défaut
    Très bonne alternative de Vincent également

    Je n'ai qu'un demi-mérite, vu que pendant mes études j'ai usé et abusé des champs de bits sur des DSP TI. Bien lire la contrainte 4 en fin d'article.

    Bonne suite

    Delias

  13. #13
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2018
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2018
    Messages : 54
    Points : 18
    Points
    18
    Par défaut
    Je vais tester tout cela dans la journée. Mais je ne dois parcourir que les 8 leds (RA0 + de RB1 à RB7), les 3 autres leds serviront pour changer de mode.
    Les ports sont imposés, et je dois avoir au minimum les deux modes pas à pas et chenillard. Par la suite je peux rajouter des modes tel que rajouter le buzzer, les interruptions, un mode 3, un mode 4, mode 5 ,...

    Merci de votre aide j'ai vraiment du mal désolé, malgré les similitudes avec le C pour quelqu'un qui n'a jamais programmé en électronique je ne comprends pas tout ce dont j'ai besoin pour faire fonctionner mes codes.

  14. #14
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2018
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2018
    Messages : 54
    Points : 18
    Points
    18
    Par défaut
    Je ne comprends pas, rien ne fonctionne sur mikroC... Je n'aime pas avoir le travail tout fait mais je ne comprends pas vos déclarations,..
    Je débute vraiment en électronique, c'est mon 1er code, de base je fais simplement du code. Si vous savez m'expliquer, m'envoyer des tutos.

    Et m'aider pour faire cette boucle simple que je n'arrive pas à faire. J'ai eu comme indication : "Faire une boucle avec une condition pour la première led Ra et ensuite utiliser portb ×2 à chaque passage".

  15. #15
    Modérateur

    Avatar de Vincent PETIT
    Homme Profil pro
    Consultant en Systèmes Embarqués
    Inscrit en
    Avril 2002
    Messages
    3 187
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Consultant en Systèmes Embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2002
    Messages : 3 187
    Points : 11 568
    Points
    11 568
    Par défaut
    Citation Envoyé par sparow1 Voir le message
    Je ne comprends pas, rien ne fonctionne sur mikroC [...] de base je fais simplement du code.
    Regarde cet exemple et test le sur un compilateur PC

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    #include <stdlib.h>
    #include <stdio.h>
     
     
    void affiche (unsigned char d)
    {
     /* juste pour afficher en binaire */
     
    	printf("%d", (d & 0x80) ? 1 : 0);
    	printf("%d", (d & 0x40) ? 1 : 0);
    	printf("%d", (d & 0x20) ? 1 : 0);
    	printf("%d", (d & 0x10) ? 1 : 0);
    	printf("%d", (d & 0x08) ? 1 : 0);
    	printf("%d", (d & 0x04) ? 1 : 0);
    	printf("%d", (d & 0x02) ? 1 : 0);
    	printf("%d", (d & 0x01) ? 1 : 0);
     
    	printf("\n");
    }
     
     
    int main (void)
    {
    	unsigned char data = 0x01;
    	unsigned char i = 0x00;
     
     
    	for (i = 0; i < 8; i++)
    	{
    		affiche(data);		
    		data = data << 1;
    	}
     
     
    	return 0;
    }

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    00000001
    00000010
    00000100
    00001000
    00010000
    00100000
    01000000
    10000000
    Et tu peux remplacer les printf("%d", (d & 0x80) ? 1 : 0); par RB7_bit = (d & 0x80) ? 1 : 0;

    ps1 : quand tu codes sur un microcontrôleur, tu peux très bien coder la plus grosse partie sur PC (l'algorithme principal) et ensuite modifier que ce qui tourne autour (les périphériques, les timers et autres)

    ps2 : pour le schéma c'est ok que si tu n'alimentes qu'une LED à la fois sinon, si plusieurs LED s'allument en même temps, sache qu'on met jamais une seule résistance pour plusieurs LED en parallèle car cela suppose à tord que le courant se répartie de manière égale entre toutes les LED et absolument rien ne le garantie.
    La science ne nous apprend rien : c'est l'expérience qui nous apprend quelque chose.
    Richard Feynman

  16. #16
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2018
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2018
    Messages : 54
    Points : 18
    Points
    18
    Par défaut
    Ok je comprends dans l'ensemble. Juste 2-3 petites questions là dessus.

    On utilise des "unsigned char" pour optimiser au niveau de l'allocation, mais on peut très bien utiliser des "int" par exemple ?

    Et dans cette partie : (d & 0x80) ? 1 : 0
    "d" est une variable, unsigned char
    "&" pour assigner la valeur,
    "0x" pour dire que c'est en hexadécimal
    "80" la valeur
    C'est bien ça ?
    Mais je ne sais à quoi sert "? 1 : 0"

  17. #17
    Modérateur

    Homme Profil pro
    Ingénieur électricien
    Inscrit en
    Septembre 2008
    Messages
    1 267
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur électricien

    Informations forums :
    Inscription : Septembre 2008
    Messages : 1 267
    Points : 4 829
    Points
    4 829
    Par défaut
    Bonsoir

    Citation Envoyé par Delias Voir le message
    [...]un code qui fonctionne sur ATTiny2313.[...]
    Je n'ai pas de PIC (et je crois que personne sur le forum en a), mais des AVR qui bien que relativement différent partagent le même domaine (c'est du microcontrôleur simple 8 bits). Pour des exercices aussi simple que celui là, la partie de logique peut très bien être identique, par contre l'initialisation est différente. le DDRB et DDRD sont les équivalents de TRISA et TRISB mais avec une signification inversée (0 = entrée, 1 = sortie). La fonction délai est _delay_ms(); et non delay_ms();, les PORT s'appellent B et D, etc..

    Citation Envoyé par sparow1 Voir le message
    Mais je ne dois parcourir que les 8 leds (RA0 + de RB1 à RB7), les 3 autres leds serviront pour changer de mode.
    D'accords, dans ce cas c'est se tirer une balle dans le pied que de ne pas mettre les 8 leds sur le même port. On se complexifie le code, juste par un mauvais choix hardware, et d'ailleurs:
    Citation Envoyé par sparow1 Voir le message
    J'ai eu comme indication : "Faire une boucle avec une condition pour la première led Ra et ensuite utiliser portb ×2 à chaque passage".
    une complexification qui ne serait pas nécessaire avec un hard mieux pensé...

    La dernière information est très importante, on part sur une boucle for selon mon code type plus haut...
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    void LED1()
    {
    	for (unsigned char i = 0; i < 8 ; i++)
    	{
    		// la suite ici
    	}
    }
    Il faut faire un test pour Ra. Donc en premier c'est cela
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    		if (i == 0) // cas spécial le bit 0 est sur PORTA
    		{
    			RA0_bit = 1;
    			delay_ms(250);
    			RA0_bit = 0;
    		}
    Puis on traite les autres avec PORTB, l'important c'est de noter que le bit 0 doit être écrit à 0, si cela aurait été 1 il fallait l'ajouter au calcul.
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    		else // les autres bits sur PORT B, de 1 à 7
    		{
    			PORTB = 1 << i; // PORTB = (1 << i) + 1; si RB0_bit devait être maintenu à 1
    			delay_ms(250);
    			PORTB = 0; // PORTB = 1; si RB0_bit devait être maintenu à 1
    		}

    L'important de noter c'est la fonction de décalage << l'opérande à gauche (1 ou 0b00000001) est décalé à gauche de l'opérande de droite. De ce fait le byte au final c'est un seul 1 à une position qui varie en fonction de i.

    Pour ton dernier message.
    Le microcontrôleur est un 8 bits, donc il ne traite que des nombres de 8 bits, au dela il doit faire le travail en plusieurs passes. C'est pour cela que l'on limite la taille des entiers à ce qui est vraiment nécessaire, 8 bits, 16 bits ou 32 bits.
    d c'est la variable
    & c'est l'opérateur ET bit à bit, cela signifie qu'il effectue un ET entre les deux nombres et cela bit à bit. Le bit n du résultat est le bit n du premier opérande ET le bit n du le deuxième opérande, cela pour n = 0 à 7.
    0 ET quelque chose c'est 0
    1 ET quelque chose c'est ce quelque chose.
    Le deuxième opérande est 0x80 (oui c'est de l'hexa) soit 0b10000000 en binaire. Donc le résultat du ET sera 0 si le bit 7 de d est à 0 et 0x80 si le bit 7 de d est à 1. Tout les autres bits de d sont mis à 0 par le & 0x80
    ... ? ... : ... est l'opérateur ternaire, c'est un test. Ce qui est avant le ? c'est la condition, si vrai (≠ 0) c'est la valeur entre ? et : qui est retournée si faux (= 0) c'est la valeur après le : qui est retournée.

    Bonne suite

    Delias

  18. #18
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2018
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2018
    Messages : 54
    Points : 18
    Points
    18
    Par défaut Problème de programmation PIC via mikroC
    Bonjour,

    Je débute en électronique, merci d'employer les termes basiques je n'ai que peu de notions sur le sujet.
    J'ai plusieurs petits projets à réaliser.

    Pour commencer, je souhaiterais simplifier mon chenillard, si quelqu'un sait m'aider. J'avais essayé de faire une boucle comme en C classique mais je n'ai pas eu le même résultat.
    Le schéma m'est imposé.

    Cordialement.

    Code sur MikroC

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    #include <stdio.h>
    // Prototypes
    void LED1() ; // Sous-programme LED1
     
    //*********************************************
     
    void main() {
     TRISA = 0b00000010; //port A en sortie sauf RA1
     PORTA = 0b11001000 ; //mettre les sorties à zéro sauf RA6, RA7,RA3
     TRISB = 0b00000001; //port B en sortie sauf RB_0
     PORTB = 0 ; //mettre les sorties à zéro
     pcon.OSCF = 1; //configure le bit 3 du registre pcon pour 4 Mhz
     CMCON = 0b00000111; //désactiver les comparateurs sur RA0
     while(1)  //boucle infinie
     {
      if (RB0_bit==0) { //si RB0 = 0 exécuter la ligne suivante
       LED1(void) ; //Sous-programme LED1
     } //fin du SI
    }
    }
     
    //*********************************************
     
    //sous-programme
    void LED1(){ // Début du Sous-programme LED1, on allume et éteind les leds de D4 à D11 l'une après l'autre
     RA0_bit = 1 ;    //sortie RA0 à 1
     delay_ms(250);   //delai d'1/4 sec
     RA0_bit = 0 ;    //sortie RA0 à 0
     RB1_bit = 1 ;
     delay_ms(250);
     RB1_bit = 0 ;
     RB2_bit = 1 ;
     delay_ms(250);
     RB2_bit = 0 ;
     RB3_bit = 1 ;
     delay_ms(250);
     RB3_bit = 0 ;
     RB4_bit = 1 ;
     delay_ms(250);
     RB4_bit = 0 ;
     RB5_bit = 1 ;
     delay_ms(250);
     RB5_bit = 0 ;
     RB6_bit = 1 ;
     delay_ms(250);
     RB6_bit = 0 ;
     RB7_bit = 1 ;
     delay_ms(250);
     RB7_bit = 0 ;
    } // Fin du sous-programme LED1 */

    Schéma Proteus
    Nom : schema proteus.PNG
Affichages : 855
Taille : 44,4 Ko

    P.S.: Je me suis permis de remettre ce poste car je ne comprends pas et je préfère redémarrer sur de bonnes bases.

  19. #19
    Modérateur

    Avatar de Vincent PETIT
    Homme Profil pro
    Consultant en Systèmes Embarqués
    Inscrit en
    Avril 2002
    Messages
    3 187
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Consultant en Systèmes Embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2002
    Messages : 3 187
    Points : 11 568
    Points
    11 568
    Par défaut
    Salut !
    J'ai fusionné les discussions afin que tout le monde puisse voir ce qui a déjà été dit et pas compris, ça arrive et il n'y a pas de problème.

    Je repasse ce soir pour expliquer différemment (très différemment)

    A+
    La science ne nous apprend rien : c'est l'expérience qui nous apprend quelque chose.
    Richard Feynman

  20. #20
    Modérateur

    Avatar de Vincent PETIT
    Homme Profil pro
    Consultant en Systèmes Embarqués
    Inscrit en
    Avril 2002
    Messages
    3 187
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Consultant en Systèmes Embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2002
    Messages : 3 187
    Points : 11 568
    Points
    11 568
    Par défaut
    Bon reprenons depuis le début.
    Un chenillard c'est une donnée qui se balade en avançant.

    En langage C pour faire avancer une donnée, dans une variable on fait appel à l'opérateur de décalage.
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    unsigned char ma_variable_8bits = 1; // ma_variable_8bits vaut 1 soit 0b00000001
     
    ma_variable_8bits = ma_variable_8bits << 1; // ma_variable_8bits vaut 2 soit 0b00000010
    ma_variable_8bits = ma_variable_8bits << 1; // ma_variable_8bits vaut 4 soit 0b00000100
    Si tu fais une boucle tu peux faire balader le 1 binaire de droite à gauche jusqu'à ce qu'il disparaisse. Maintenant on va aller un peu plus loin avec le même principe mais en l'améliorant. Voici ce que je te demande de t'imaginer ; une variable sur 16 bits ma_variable_16bits, les 8 bits de poids faibles serviront à charger une donnée ma_variable_8bits. Une fois que c'est fait on lance une boucle de décalage 8 fois dans un premier temps.

    Nom : text26514.png
Affichages : 782
Taille : 15,3 Ko

    Je vais devoir te faire participer sinon c'est sur et certain que tu ne comprendras pas ce que je vais faire même si tu vois probablement tout ce qui va se passer.

    Je te demande de faire juste un petit programme qui crée une variable 16bits qui s'appellera ma_variable_16bits et que tu charges dans l'octet de poids faible ma_variable_8bits. La variable ma_variable_8bits contiendra au préalable 0b10101010. Une fois chargé, tu fais un décalage à gauche de 1 de ma_variable_16bits mais 8 fois.

    Après le chargement de ma_variable_8bits (qui vaut 0b10101010) dans l'octet de poids faible de ma_variable_16bits, tu peux te représenter les choses comme ça :

    Nom : text26515.png
Affichages : 774
Taille : 16,8 Ko

    Pour le seconde partie, voici un exemple de ce que ça donnerait lorsque dans une boucle tu feras des décalages à gauche (ici dans l'image ci dessous, 7 décalages à gauche)

    Nom : text26516.png
Affichages : 779
Taille : 18,4 Ko

    A toi de faire le programme mais pour 8 décalages.
    La science ne nous apprend rien : c'est l'expérience qui nous apprend quelque chose.
    Richard Feynman

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 5 12345 DernièreDernière

Discussions similaires

  1. Problème de communication PIC-PC via RS232
    Par jiji94 dans le forum C++
    Réponses: 0
    Dernier message: 04/04/2008, 19h26
  2. problème finalisation programme
    Par depelek dans le forum Installation, Déploiement et Sécurité
    Réponses: 9
    Dernier message: 02/05/2006, 16h17
  3. Problème de récup image via http://
    Par TK5EP dans le forum Langage
    Réponses: 3
    Dernier message: 26/12/2005, 19h59
  4. Réponses: 1
    Dernier message: 26/09/2005, 19h29
  5. Communication RS232 avec un PIC via delphi
    Par JeanPh dans le forum API, COM et SDKs
    Réponses: 22
    Dernier message: 09/08/2004, 22h56

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo