|  
       #include <pic.h> //obligatoire, de base 
      //Quartz 4Mhz 
        #define PIC_CLK 4000000  
         
        //Les routines de temporisation 
        #include "delay.h"  
         
        //J'utilise un quartz, mon code n'est pas protégé 
        __CONFIG(FOSC0|PWRTE |CP);  
      /**  
        * Gestion laison RS232 à 9600 bauds 
        *  
        */ 
         
        //Fonctions de manipulation des bits en remplacement des structures unions 
        et typedef  
      #define PORTBIT(adr, bit) ((unsigned)(&adr)*8+(bit)) 
        #define getbit(data,bitno) ((data>>bitno)&0x01) 
        #define setnbit(data,bitno) (data<<bitno) 
        #define setbit(data,bitno,value) (data&(~setnbit(1,bitno))|setnbit(value,bitno)) 
        #define togglebit(data) (data^0x01) 
      //temps en microseconde pendant lequel le microcontroleur est aveugle 
        à un changement d'état sur une de ses broches d'IT 
        #define TirqLatency 60  
      /************Liaison série *******************************/ 
      //Paramètres de Reception 
        //----------------------- 
      #define Tbit_rx_RS232 104 //Reception T=1/9600=104us à 9600 bauds 
         
        #define Jump_over_RS232_rx_startbit (Tbit_rx_RS232-TirqLatency+(Tbit_rx_RS232/2)) 
        #define Nb_RS232_rx_databits 8 // 8 bits de données  
        #define Jump_over_RS232_rx_databits (Tbit_rx_RS232-15) //la boucle d'éxécution 
        prends 12us 
        #define Nb_RS232_rx_stopBits 1 //1 bit stop 
        #define Jump_over_RS232_rx_stopbits (Nb_RS232_rx_stopBits*Tbit_rx_RS232) 
      //Paramètres d'envoi 
        //------------------ 
      #define Tbit_tx_RS232 104 
        #define Duration_RS232_tx_startbit (Tbit_tx_RS232-30) 
        #define Nb_RS232_tx_databits 8 
        #define Duration_RS232_tx_databits (Tbit_tx_RS232-30) //la boucle d'xcution 
        prends 12us 
        #define Nb_RS232_tx_stopBits 1 
        #define Duration_RS232_tx_stopbits (Nb_RS232_tx_stopBits*Tbit_tx_RS232) 
       
        #define ITMask 0B10110000 
         
        //-----Attribution des broches ------------- 
      static bit RS_OUT @ PORTBIT(PORTA, 4); //Borche d'envoi  
        static bit RS_IN @ PORTBIT(PORTB, 7); //Broche de reception 
      //Pour voir le caractère envoyé sur 8 leds 
        volatile bit D1 @ PORTBIT(PORTB, 3); 
        volatile bit D2 @ PORTBIT(PORTB, 2); 
        volatile bit D3 @ PORTBIT(PORTB, 1); 
        volatile bit D4 @ PORTBIT(PORTB, 0); 
        volatile bit D5 @ PORTBIT(PORTA, 3); 
        volatile bit D6 @ PORTBIT(PORTA, 2); 
        volatile bit D7 @ PORTBIT(PORTA, 1); 
        volatile bit D8 @ PORTBIT(PORTA, 0); 
       
      //---- Variables de travail --------------------------- 
        //variable utilisée par les routines de temporisation 
        volatile unsigned int timeout; 
      //variable tampon 
        unsigned char Buff; 
         
        unsigned char TxBuff; // caractère à emettre 
        unsigned char RxBuff;// caractère reçu 
      //------ Déclaration des routines RS232 ------------------------------- 
         
        void RSsend(void); /* Send the char Buff on the serial port */ 
        void RSget(void); /* Read the serial port and save it into Buff*/ 
      //------- Déclaration des routines pour afficher sur les leds-------------- 
         
        void WriteParport(void); 
        void ReadParport(void); 
      //------ Le programme principal intialise les ports et autorise les 
        interruptions --------- 
        main()  
        {  
       
        //Indique si les broches sont des entrées ou des sorties 
          TRISB = ITMask;  
          TRISA = 0; 
        //Fixe les valeurs des ports par défaut 
          PORTA = 0; 
          PORTB = 0b10000000; //Initialize RS_IN  
          RS_OUT=1; 
        //autorise les interruptions sur le port B 
          RBIE=1; 
          GIE=1;  
         //boucle infinie qui n'attend qu'à être interrompue 
          for(;;) { 
           
          } 
       
      }  
      //-----Affiche le contenu de Buff sur le port des 8 leds 
        void WriteParport(void) { 
       
        D1=getbit(Buff,0);  
          D2=getbit(Buff,1); 
          D3=getbit(Buff,2); 
          D4=getbit(Buff,3); 
          D5=getbit(Buff,4); 
          D6=getbit(Buff,5); 
          D7=getbit(Buff,6); 
          D8=getbit(Buff,7); 
       
      } 
      //----récupère la valeur de Buff en fonction de la valeur 
        sur les leds D1-D8 
        void ReadParport(void) { 
       
        Buff=setbit(Buff,0,D1);  
          Buff=setbit(Buff,1,D2); 
          Buff=setbit(Buff,2,D3); 
          Buff=setbit(Buff,3,D4); 
          Buff=setbit(Buff,4,D5); 
          Buff=setbit(Buff,5,D6); 
          Buff=setbit(Buff,6,D7); 
          Buff=setbit(Buff,7,D8); 
       
      } 
      
      unsigned char prev_portb=0B10000000; //mémorisation de la valeur 
        du port B 
       
      // Routine d'interruption déclenchée si un signal change 
        d'état sur une des broches prévues à cet effet: 
        // RB7, RB6,RB5,RB4 et RB0 
      interrupt isr()  
        {  
       
         
          //Détermine quelle broche du port B a changé d'état 
          et a généré cette interruption 
          if (RBIF)  
          {  
          RBIF=0; //on acquite l'interruption 
         
           
            if ((prev_portb ^ (PORTB&ITMask)) == 0B10000000)  
            { 
           
             
              //C'est la Broche RB7=RS IN qui a changé, un caractère 
              est à réceptionner 
              if ((PORTB & 0B10000000) == 0) //Si c'est le front descendant 
              du bit start alors  
              {  
              //On réceptionne le caractère 
              RSget(); 
              //on l'affiche sur les leds 
              Buff=RxBuff; 
              WriteParport(); 
              //et on fait un echo en envoyant à celui qui nous l'a envoyé 
              TxBuff=RxBuff;  
              RSsend();  
              } 
           
          } 
             
            prev_portb=PORTB&ITMask; //on prépare le port b au prochain 
            changement..  
         
         }  
       
       
        }  
       
         
        // RS232 routines 
        //------------------ 
      /* Envoie sur la broche RA4 le caractère contenu dans TxBuff 
        au format RS232*/ 
      void RSsend(void) { 
        unsigned b; 
        unsigned prevbit;  
       // Bit start 
        RS_OUT=0; 
        DelayUs(Duration_RS232_tx_startbit); //durée du motif start 
         
        //pour tous les bits de données.. 
        for(b=Nb_RS232_tx_databits;b--;) {  
       prevbit=(TxBuff&0x01); 
       if(prevbit^RS_OUT) //si la valeur est différente du pécédent 
        bit  
        RS_OUT=TxBuff&0x01; //on l'envoie sinon on laisse la ligne comme est 
        l'est  
         
        if(b>0) //si ce n'est pas le premier bit de donnée, c'est qu'il 
        m'en reste encore à traiter 
        TxBuff=TxBuff>>1; //j'ai fini avec ce bit je le met à la 
        poubelle , au bit suivant 
         
        DelayUs(Duration_RS232_tx_databits);//durée d'un motif data 
         
        } 
         
        //Bit stop  
        RS_OUT=1; 
        DelayUs(Duration_RS232_tx_stopbits);//durée d'un motif stop 
         
        } 
      /* Recoit un caractère série sur RA1 et le stocke dans 
        RXBuff **/ 
      void RSget(void) { 
       
        unsigned b; 
        RxBuff='\0'; 
       
          
          //Saute par dessus le bit start et se positionne à la moitié 
          du premier bit de données 
          //RS_OUT=0; 
          DelayUs(Jump_over_RS232_rx_startbit); // la tempo qu'il faut 
          //RS_OUT=1; 
           
          //Lit consécutivement les 8 bits de données que l'on m'envoie 
          for(b=Nb_RS232_rx_databits;b--;) {  
           
          RxBuff=RxBuff | ((RS_IN&0x01)<<(Nb_RS232_rx_databits-1)); 
           
          /* Pour déboguage */ 
          //RS_OUT=0;  
           
          if(b>0) //reste il des bits à traiter? 
          RxBuff=RxBuff >> 1; //oui,alors au suivant 
           
          DelayUs(Jump_over_RS232_rx_databits); //on laisse passer la durée 
          d'un bit 
          //RS_OUT=1;  
           
          } 
         
       
       
        DelayUs(Jump_over_RS232_rx_stopbits); //facultatif car les bits stops 
        ne contiennent pas d'info 
         
        } 
      
     |