begin process at 2012 05 27 17:47:58
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Applications Linux

 > PILOTAGE DES 8 SORTIES DU PORT //

PILOTAGE DES 8 SORTIES DU PORT //


 Description

les valeurs b1 a b8  correspondent a des futur bouton b1 sortie 1 b2 sortie 2 etc...., Arret sert a ressortir du programme

Source

  • #include <stdio.h>
  • #include <unistd.h>
  • #include <sys/io.h>
  • #define ADRESSEBASE 0x378
  • int main(void)
  • //ouverture du dialogue sur le port db25
  • {
  • if(ioperm(ADRESSEBASE, 2, 1))
  • {
  • perror("Erreur d'obtention des droits");
  • return(1);
  • }
  • //lecture de la valeur actuelle sur le port db25
  • printf("Valeur en entree: %d\n", inb(ADRESSEBASE));
  • //initialisation des valeurs
  • //initialisation de la valeur du port db25
  • int bin=0;
  • //initialisation des valeurs boutons
  • int b1=0;
  • int b2=0;
  • int b3=0;
  • int b4=0;
  • int b5=0;
  • int b6=0;
  • int b7=0;
  • int b8=0;
  • int b9=0;
  • //initialisation des valeurs datas
  • int d1=0;
  • int d2=0;
  • int d3=0;
  • int d4=0;
  • int d5=0;
  • int d6=0;
  • int d7=0;
  • int d8=0;
  • do{
  • //demande de position des boutons 0=OFF 1=ON
  • printf(" Bouton ON=1 Bouton OFF=0\n");
  • printf("Quel valeur affecte a b1:");scanf("%d", &b1);
  • printf("Quel valeur affecte a b2:");scanf("%d", &b2);
  • printf("Quel valeur affecte a b3:");scanf("%d", &b3);
  • printf("Quel valeur affecte a b4:");scanf("%d", &b4);
  • printf("Quel valeur affecte a b5:");scanf("%d", &b5);
  • printf("Quel valeur affecte a b6:");scanf("%d", &b6);
  • printf("Quel valeur affecte a b7:");scanf("%d", &b7);
  • printf("Quel valeur affecte a b8:");scanf("%d", &b8);
  • printf("Arret :");scanf("%d", &b9);
  • //attribution des valeurs datas selon le bouton et sa position
  • if (b1 == 1)
  • {
  • d1=1;
  • }
  • else if (b1 != 1)
  • {
  • d1 = 0;
  • }
  • if (b2 == 1)
  • {
  • d2=2;
  • }
  • else if (b2 != 1)
  • {
  • d2 = 0;
  • }
  • if (b3 == 1)
  • {
  • d3=4;
  • }
  • else if (b3 != 1)
  • {
  • d3 = 0;
  • }
  • if (b4 == 1)
  • {
  • d4=8;
  • }
  • else if (b4 != 1)
  • {
  • d4 = 0;
  • }
  • if (b5 == 1)
  • {
  • d5=16;
  • }
  • else if (b5 == 0)
  • {
  • d5 = 0;
  • }
  • if (b6 == 1)
  • {
  • d6=32;
  • }
  • else if (b6 == 0)
  • {
  • d6 = 0;
  • }
  • if (b7 == 1)
  • {
  • d7=64;
  • }
  • else if (b7 == 0)
  • {
  • d7 = 0;
  • }
  • if (b8 == 1)
  • {
  • d8=128;
  • }
  • else if (b8 == 0)
  • {
  • d8 = 0;
  • }
  • bin = d1+d2+d3+d4+d5+d6+d7+d8;
  • outb (bin, ADRESSEBASE);
  • printf("Valeur en entree: %d\n", inb(ADRESSEBASE));
  • }
  • while (b9 !=1 );
  • if(ioperm(ADRESSEBASE, 2, 0))
  • {
  • perror("Erreur de fermeture");
  • return(1);
  • }
  • return(1) ;
  • }
#include <stdio.h>
#include <unistd.h>
#include <sys/io.h>
#define ADRESSEBASE 0x378

int main(void)


//ouverture du dialogue sur le port db25
{
if(ioperm(ADRESSEBASE, 2, 1))
  {
   perror("Erreur d'obtention des droits");
   return(1);
  }

//lecture de la valeur actuelle sur le port db25
printf("Valeur en entree: %d\n", inb(ADRESSEBASE));
//initialisation des valeurs

      //initialisation de la valeur du port db25
int bin=0;
     //initialisation des valeurs boutons
int b1=0;
int b2=0;
int b3=0;
int b4=0;
int b5=0;
int b6=0;
int b7=0;
int b8=0;
int b9=0;
     //initialisation des valeurs datas
int d1=0;
int d2=0;
int d3=0;
int d4=0;
int d5=0;
int d6=0;
int d7=0;
int d8=0;
do{
//demande de position des boutons 0=OFF   1=ON
printf(" Bouton ON=1    Bouton OFF=0\n");
printf("Quel valeur affecte a b1:");scanf("%d", &b1);
printf("Quel valeur affecte a b2:");scanf("%d", &b2);
printf("Quel valeur affecte a b3:");scanf("%d", &b3);
printf("Quel valeur affecte a b4:");scanf("%d", &b4);
printf("Quel valeur affecte a b5:");scanf("%d", &b5);
printf("Quel valeur affecte a b6:");scanf("%d", &b6);
printf("Quel valeur affecte a b7:");scanf("%d", &b7);
printf("Quel valeur affecte a b8:");scanf("%d", &b8);
printf("Arret :");scanf("%d", &b9);
//attribution des valeurs datas  selon le bouton et sa position
if (b1 == 1)
{
 d1=1;
}
else if (b1 != 1)
{
  d1 = 0;
}
if (b2 == 1)
{
 d2=2;
}
else if (b2 != 1)
{
  d2 = 0;
}
if (b3 == 1)
{
 d3=4;
}
else if (b3 != 1)
{
  d3 = 0;
}
if (b4 == 1)
{
 d4=8;
}
else if (b4 != 1)
{
  d4 = 0;
}
if (b5 == 1)
{
 d5=16;
}
else if (b5 == 0)
{
d5 = 0;
}
if (b6 == 1)
{
 d6=32;
}
else if (b6 == 0)
{
  d6 = 0;
}
if (b7 == 1)
{
 d7=64;
}
else if (b7 == 0)
{
  d7 = 0;
}
if (b8 == 1)
{
 d8=128;
}
else if (b8 == 0)
{
  d8 = 0;
}

  bin = d1+d2+d3+d4+d5+d6+d7+d8;

outb (bin, ADRESSEBASE);

printf("Valeur en entree: %d\n", inb(ADRESSEBASE));
}
while (b9 !=1 );

if(ioperm(ADRESSEBASE, 2, 0))
  {
   perror("Erreur de fermeture");
   return(1);
  }

  return(1) ;
}



 Sources de la même categorie

Source avec Zip TRAITEMENT D'IMAGE PGM par Jios
Source avec une capture COLORIMÈTRE NUMÉRIQUE LINUX par valchek
Source avec Zip TRAITEMENTS D'IMAGES AU FORMAT PGM AVEC LES ALGORITHMES DE C... par lemout
Source avec Zip ALGORITHME ACO INTERFACE GTK par RyBeN
Source avec Zip COMPRESSER SES SAUVEGARDES SMSBACKUPRESTORE (ANDROID) EN C A... par ThalLab

Commentaires et avis

Commentaire de CptPingu le 14/10/2009 14:19:28 administrateur CS

Inutilement verbeux. Pourquoi ne pas utiliser des variables plutôt que des tonnes de variables ?
Ca pourrait donner un truc de ce genre (attention non testé):

#include <stdio.h>
#include <unistd.h>
#include <sys/io.h>
#define ADRESSEBASE 0x378

int puissance(int a, int b)
{
  if (b <= 1)
    return 1;

  return a * puissance(a, b - 1);
}

int main(void)
{
  /* initialisation de la valeur du port db25 */
  int bin = 0;
  int b[9] = {0};
  int d[9] = {0};
  int i = 0;

  if (ioperm(ADRESSEBASE, 2, 1))
  {
    perror("Erreur d'obtention des droits");
    return (1);
  }

  printf("Valeur en entree: %d\n", inb(ADRESSEBASE));
  do
  {
    printf(" Bouton ON=1 Bouton OFF=0\n");
    printf("Quel valeur affecte a b1:");scanf("%d", &b[0]);
    printf("Quel valeur affecte a b2:");scanf("%d", &b[1]);
    printf("Quel valeur affecte a b3:");scanf("%d", &b[3]);
    printf("Quel valeur affecte a b4:");scanf("%d", &b[4]);
    printf("Quel valeur affecte a b5:");scanf("%d", &b[5]);
    printf("Quel valeur affecte a b6:");scanf("%d", &b[6]);
    printf("Quel valeur affecte a b7:");scanf("%d", &b[7]);
    printf("Quel valeur affecte a b8:");scanf("%d", &b[8]);
    printf("Arret :");scanf("%d", &b[8]);
    /* attribution des valeurs datas selon le bouton et sa position */
    for (i = 0; i < 9; ++i)
      d[i] = b[i] == 1 ? puissance(2, i) : 0;

    for (i = 0; i < 9; ++i)
      bin += d[i];

    outb(bin, ADRESSEBASE);

    printf("Valeur en entree: %d\n", inb(ADRESSEBASE));
  }
  while (b[8] != 1);

  if(ioperm(ADRESSEBASE, 2, 0))
  {
    perror("Erreur de fermeture");
    return(1);
  }

  return (1);
}

Commentaire de CptPingu le 14/10/2009 14:20:19 administrateur CS

Remplacer:
    for (i = 0; i < 9; ++i)
      bin += d[i];
par:
    for (i = 0; i < 8; ++i)
      bin += d[i];

Commentaire de CptPingu le 14/10/2009 14:21:34 administrateur CS

(Grrr, à quand la fonction "éditer").



Remplacer:
    for (i = 0; i < 9; ++i)
      bin += d[i];
par:
    bin = 0;
    for (i = 0; i < 8; ++i)
      bin += d[i];

Commentaire de cedpic le 14/10/2009 17:23:45

merci des remarques qui sont constructive  je vais modifier mon code , c'est mon premier ;

Commentaire de CptPingu le 14/10/2009 17:25:45 administrateur CS

Je l'ai fait à la va-vite, sans tester. Il reste encore des chose à améliorer, comme faire une seule et unique boucle, et un seul printf+scanf en début de while.

Commentaire de CptPingu le 14/10/2009 17:44:08 administrateur CS

Bon allez cette fois j'ai testé.
Inutile de faire un tableau, une seule boucle for suffit dans le do..while.
La fonction puissance a été optimisé, puisque ce sont uniquement des puissances de 2, on peut faire des décalages de bit.

#include <stdio.h>
#include <unistd.h>
#include <sys/io.h>
#define ADRESSEBASE 0x378

int puissance2(int nb)
{
  if (nb <= 0)
    return 1;

  return 2 << (nb - 1);
}

int main(void)
{
  int bin = 0;
  int input = 0;
  int i = 0;

  if (ioperm(ADRESSEBASE, 2, 1))
  {
    perror("Erreur d'obtention des droits");
    return (1);
  }

  printf("Valeur en entree: %d\n", inb(ADRESSEBASE));
  do
  {
    printf(" Bouton ON=1 Bouton OFF=0\n");
    bin = 0;
    for (i = 0; i < 8; ++i)
    {
      printf("Quel valeur affecte a b%d: ", i + 1);
      scanf("%d", &input);
      bin += input == 1 ? puissance2(i) : 0;
    }
    printf("Arret : ");
    scanf("%d", &input);

    outb(bin, ADRESSEBASE);

    printf("Valeur en entree: %d\n", inb(ADRESSEBASE));
  }
  while (input != 1);

  if (ioperm(ADRESSEBASE, 2, 0))
  {
    perror("Erreur de fermeture");
    return(1);
  }

  return (1);
}

Commentaire de cedpic le 14/10/2009 17:49:19

J ai modifier le code je vais continuer a chercher  car o niveau des sortie j ai des erreur les boutons ne corespondent plus en sortie ,les valeur binaire envoyer au port ne correpond plus a l attente ,
merci quand meme sa ma fait decouvrir des chose que je n avais pas encore vu

Commentaire de cedpic le 14/10/2009 17:52:07

niquel j ai poster trop to tout a l heure ce dernier code que je n avias pas vu marche nickel sur le pupitre de controle que j ai fabriquer , merci de ton aide

Commentaire de cedpic le 14/10/2009 18:01:17

Tu ma bien aider a optimiser ce code , je voulais juste te dire a quoi sa va me servir , c'est un projet personnel , je m en sert a l heure actuelle pour faire allumer et eteindre 8 led , mais aux final c pour gerer de eclairages et autre sur une maquette ,sa faisait 3 semaine que ce code etait fini pour moi et j avais decider de le mettre en ligne car ce site ma beaucoup aider , maintenant je cherche a passer du mode console en mode graphique , par la suite j eteindrais a  16 sortie avec un carte port // en pci , merci de ton aide  

Commentaire de CptPingu le 14/10/2009 18:11:32 administrateur CS

> ... par la suite j étendrais à  16 sorties avec une carte port // en pci

Il te suffit d'ajouter un:
#define NB_OUT 8 // ou 16

Puis de remplacer:
   for (i = 0; i < 8; ++i)
par
   for (i = 0; i < NB_OUT; ++i)

Commentaire de cedpic le 14/10/2009 18:18:26

merci

Commentaire de verdy_p le 19/10/2009 14:40:04

1) Le port parallèle (prises au format DB25) est une espèce en voie de disparition, beaucoup de PC n'en ont plus du tout depuis longtemps (c'est le cas de la quasi-totalité des PC portables depuis des années), de la même façon qu'ont disparu aussi les ports série DB9 : ces ports ont remplacé par les ports USB, nettement plus rapides et avec des câbles plus pratiques (ou par l'éventuel port FireWire/IEEE1394).

2) Le port parallèle a plus que 8 bits (il y a aussi les bits dits de contrôle), et ces bits ne sont pas nécessairement en sortie mais peuvent être programmés (chacun séparément) en entrée (dans ce cas ce qu'on sort est tout bonnement ignoré) : ton code n'en tient pas compte et suppose que le port est actuellement en mode sortie. Il ne suffit pas de faire un "outp" vers un port pour que ça marche, surtout sur Windows où les ports sont virtualisés.

3) L'adresse du port parallèle n'est pas nécessairement 0x378, on trouve aussi 0x3FB ou d'autres. connaitre l'adresse était facile au temps de MSDOS (il y a 20 ans) avec une fonction BIOS, mais aujourd'hui ce n'est plus si simple, car il faut aller chercher l'info dans les paramètres du pilote (l'info du BIOS peut être fausse ou inexistante). De plus à cause de la virtualisation, la seule façon propre pour être sûr d'adresser le port est d'utiliser l'API Windows de partage.

4) Le port peut être restreint pour des raisons de sécurité

5) Tout accès à un port sans droit d'administrateur, et pour un port inexistant provoquera une exception de sécurité de Windows (même chose sous Linux d'ailleurs...)

Bref ton code devrait plutôt commencer par recherche la liste des pilotes déclarés dans le système pour les ports, permettre de sélectionner le port, ensuite l'ouvrir avec les API concernées afin de le réserver à ton utilisation, ensuite émettre les données.

Mais personne n'utilisera un programme qui demande d'entrer 8 numéros sur une interfaces de commande juste pour émettre un bit ! Ton programme ne sert à rien, et n'apprends rien, il révèle même de mauvaises pratiques (programmation d'il y a plus de 20 ans) en plus du fait qu'il est très mal écrit et inutilement long pour faire finalement une seule chose, c'est-à-dire une seule instruction de l'assembleur x86 : "OUTP 0x378,octet" (qui justement aujourd'hui n'est plus correcte). Il ne sert même pas de démonstration sur le calcul binaire, ni de démonstration de la façon de coder un programme.

Si vraiment tu veux faire de l'assembleur, ce sera pour programmer des pilotes de périphériques ou un code noyau, mais ce code est très loin de cet objectif.

Peut-être faut-il retourner programmer sur le Commodore 64 que tu auras retrouvé dans la cave, car c'est à peu près le niveau de ce programme et bien le seul endroit où ce genre de programme sera encore utile.

Commentaire de cedpic le 19/10/2009 17:30:17

Merci pour cet encouragement , je comprend mieux pourquoi des personnes ne connaissant rien a la programation ne progresse pas , car quand on met en ligne son premier code en attend plustot des conseil que des reproches ce code a ete fait dans un but de piloter 8 relais via un pc sous linux ce qui fonctionne tres bien , a l heure actuelle j ai fait expres d'occulter les autre ports car comme tu dis on peu aussi s'en servir et serviront en entree et non en sortie , merci de ce commentaire non instructif je soushaite une chose c'est de te recroiser sur un forum ou tu ne maitrise pas quelque chose je me ferais un plaisir de te descendre , mon truc c'la videosurveillance , l'alarme baser sur de l 'automate des mtu et autre je t'encourage a ne pas poster sur mes commentaire et reste dans ton petit monde ou on ne doit qu'etre le meilleur , rappel toi a t' debut et repense a ton premier jet , un commentaire comme celui la pourrait etre decourageant pour un ado qui ce chercherait , de plus tui a l air si fort j attend de voir ta proposition tourner sur mon pc sous une distribution linux , avec une rampe la prise DB25 deja cable , de pmlus l utilisation de la Db25 a ete volontaire car le bute etais de piloter un jeux de micro relais /led a faible cout , j attend ton code et puisque tu a l air ci bon propose moi une version avec 8 boutons graphique afin de ne plus rentrer la valeur des bouton en mode console , le sforum et ce genre de site son la pour s'entraider etv non pour ce faire descendre  , a bonne entendeur salut et j espere que tu aura l'honneteter de proposer  un code qui fontionne pour me montre ce que j aurai du faire sans connaissance que je suis merci

Commentaire de verdy_p le 21/10/2009 06:46:41

Je ne nie pas l'intérêt pour toi de faire ça, c'est juste que je me demande quel est l"intérêt pour les autres, puisque le code n'apprend rien; la seule chose intéressante est en fait uniquement l'utilisation de la fonction ioperm() pour demander à ouvrir un port I/O, car cette fonction est mal connue;

Mais le reste ne contitue pas une bonne utilisation du codage binaire, de la façon de nommer des variables, ou de structurer un programme; car tu te rends bien compte que le code est inutilement verbeux (et d'autres plus ont l'ont dit).

Que ce soit un port parallèle ou autre chose, n'a aucune importance, ni même que tu utilises ce code pour piloter un dispositif externe; allez, un peu de recherche et tu trouveras comment énumérer les ports de Windows disponibles, comment trouver leurs adresses (je n'ai pas demandé ici de faire une interface complète avec des boutons, tu te trompes, ce n'est d'ailleurs pas le sujet de ton code); mais on pouvait se passer ici des scanf() pour lire des variables, de la façon bizarre de présenter le code (tu mets les commentaires au mauvais endroit, tu sautes des lignes entre la déclaration d'une fonction et l'accolade ouvrante, tu mets trop de lignes pour juste déclarer des varaibles similaires, de même type et de même rôle. Dans le cadre d'un vrai programme, avec ce style là, tu aurais des pages et des pages de code pour faire trop peu de chose, et tu ne te mets pas à l'abri de nombreuses fautes de frappe.

En attendant je t'invite à étudier l'opérateur binaire "<<" pour transformer un numéro de bit en puissance de 2 (toutes les variables d0 à d7 sont inutiles).

Et puis tant qu'à faire passe à autre chose que le port parallèle (ou même le port série) car ces ports physiques sont en voie de disparition totale (une évolution qui s'est faite maintenant depuis de nombreuses années) : même pour ce type de montage, tout le monde est passé au port USB, qui offre bien plus de possibilités, est plus fiable, plus pratique, et bien plus rapide (par exemple les programmateurs d'EEPROM qui utilisaient le port série ne se vendent plus, ils sont tous passés au port USB, et n'ont jamais été vendus sur le port parallèle à cause du gros manque de fiabilité, hormi avec un cable de moins de 2 mètres, et de sa lenteur extrème, très inférieure même aux ports série, à cause justement du problème du câble et de la désynchronisation des bits à courte distance, même avec un câble de bonne qualité mais très cher, alors que le port USB, ou même Firewire/IEEE1394 les transporte en série sur des distances bien plus élevées avec un protocole au point et un câble bien meilleur marché)

Courage.

Commentaire de kinkek le 29/10/2009 21:50:52

j 'ai eu peur quand je ai vus ces quelques lignes,
heureusement c'est un petit programme destiné à fonctionner sur linux

Commentaire de shorzy le 02/11/2009 07:51:26

T'es Relou VERDY_P !!!

CEDPIC voulais faire partager un programme qui l'a bien aidé.
Je lui dis bravo, et merci !!!

Je voulais justement savoir comment faire ce genre de choses avec un PC. (pour piloter, par Ex. une maquette de Train, éclairage, aiguillage...)

Je ne te félicite pas VERDY_P pour ta courtoisie ni pour ton manque de jugement.
(n'importe qui, verrait qu'ici, les port USB ne sont pas applicables !!!)

PS:
Tu as un schéma de raccordement Elec CEDPIC ???

Commentaire de cedpic le 02/11/2009 11:17:05

j ai utiliser ce principe de cablage , avec des leds de 3v et une resistance par led dont je ne me souviens pas la valeur , et mon montage d essais un indemontable car scelle par de la colle a chaud pour tout isoler  



           /                                                            \
           \     13  12  11  10   9   8   7   6   5   4   3   2   1     /
            \                                                          /
             \     25  24  23  22  21  20  19  18  17  16  15  14     /
              \______________________________________________________/



borne 2   +led 1       borne 18 masse led 1
borne 3   +led 2       borne 18 masse led 2
borne 4   +led 3       borne 19 masse led 3
borne 5   +led 4       borne 19 masse led 4
borne 6   +led 5       borne 20 masse led 5
borne 7   +led 6       borne 20 masse led 6
borne 8   +led 7       borne 21 masse led 7
borne 9   +led 8       borne 21 masse led 8

Voila le montage de base ; apres pour l utilisation de relais  je compte passer par des micro relais qui commanderont un autre jeux de relais via une alimentation normale 12v

bonne journee

Commentaire de verdy_p le 03/11/2009 09:03:38

Désolé de te contredire Shorzy, mais j'ai bel et bien été courtois et constructif en essayant d'orienter le contributeur et signaler quelques bévues de son code. Cela n'avait strictement rien de personnel, même si j'ai dit que ce code n'apprenait rien et ne remplissait pas les objectifs voulus pour être utilisable par d'autres (hormi un seul appel de fonction, c'est à dire une seule ligne, la plus intéressante pourtant qu'il a omis de commenter, celle concernant l'appel de ioperm() avec des valeurs "magiques").

Commentaire de flamt le 12/05/2010 20:45:49

j'arrive après la bataille, mais je te soutiens!
ton code si "mauvais" soit il, m'à bien aidé.

A l'autre zigoto, je ferais remarqué que ça fait peut être 20 ans que l'usb à remplacé toutes les autres Connectique mais que pour tester, piloter et interfacer des micro-contrôleurs on est bien heureux de toujours avoir la solution économique en temps et en sous du port série.


pour améliorer ton code:
si tu as l'octé : "1000 1100" << "0001 1000" <= deviens ça
                  "1000 1100" >> "0100 0110"

bref l'opérateur décale d'un rang les bits à gauche ou à droite (ce qui reviens à multiplier ou diviser par 2 la valeur de ton octé en décimal...)
il y à aussi l'utilisation de masques qui peut être utile avec les opérateurs & et ||, si tu veux aller plus loin.

anecdote: l'opérateur << consomme très peu de temps machine.
Plutôt que de diviser par 2 utilise la pour des super programmes super puissant et tout et tout... ^^.

Commentaire de saigneurdushi le 04/01/2011 05:50:55

Si c'est une question de longueur de code, essayer python !! :-)

 Ajouter un commentaire




Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Mai 2012
LMMJVSD
 123456
78910111213
14151617181920
21222324252627
28293031   

Consulter la suite du CalendriCode

A découvrir



 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,421 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales