Bienvenue aux nouveaux arrivants sur FantasPic !

- Pensez à lire les règles durant votre visite, il n'y en a pas beaucoup, mais encore faut-il les respecter .
- N’hésitez pas à faire des remarques et/ou suggestions sur le Forum, dans le but de l'améliorer et de rendre vos prochaines visites plus agréables.
- Vous pouvez regarder votre "panneau de l'utilisateur" afin de configurer vos préférences.
- Un passage par "l'utilisation du forum" est recommandé pour connaître les fonctionnalités du forum.

--- L’équipe FantasPic ---
Forum général sur le langage C !

Modérateur : Jérémy

Dupliquer un UART pour espionner dialogue
Jérémy
Administrateur du site
Administrateur du site
Messages : 2723
Âge : 45
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#1 Message par Jérémy » mer. 13 juil. 2016 14:18

Bonjour à tous,

Toujours sur mon Bluetooth, j'avance petit à petit ....... . J'ai fini une version stable, mais très peu optimisée. détection de perte de com, plus recuperation automatique de celle ci quand on rentre dans le rayon etc ;...

Je souhaiterais pour cela améliorer ma compréhension dans divers point.

Pour ce faire j'ai besoin de voir exactement le dialogue entre mon module Bluetooth et mon PIC .

J'ai modifier mon programme tournant sur un PIC16F1847 pour tourner sur un PIC18F46K22 possédant deux UARTs !!!!

Le but étant de brancher sur la brcoheTX2 mon cable USB/UART . ainsi je pourrais voir ce qui ce trame et les cailloux dans ma chaussure :lol: .

D’après mes premiers tests, ce n'est pas si simple vu l'architecture de mon programme "source" .
En effet la gestion du dialogue est tiré d'une source qui n'est pas de moi, et je vois mal comment je pourrais m'en servir .

Pour la partie TX1 à la limite j'ai juste à rajouter un TX2 a la suite avec les mêmes valeurs à envoyer . ( reloud mais ça devrait fonctionner).

Par contre pour la partie RX1 qui doit etre envoyer en TX2 je vois pas trop Auriez vous des pistes ?

Voici le programme avec mes quelques premières modifications ( les plus faciles) :

Code : Tout sélectionner

/*##################################################################################
- Version du "13-07-2016"
- MikroC version 6.6.3
- PIC 18F46K22 ,  FOSC INTERNE à 1MHZ PLL Disable
- Data-Shit du PIC : http://ww1.microchip.com/downloads/en/DeviceDoc/41412F.pdf
#################################################################################*/

#include "BT_Routines.h"

// Constantes pour analyser les réponses
const BT_CMD  = 1;
const BT_AOK  = 2;
const BT_CONN = 3;
const BT_END  = 4;

//#######################     DEFINE     #########################
#define Led_rouge PORTB.B4
#define Led_verte PORTA.B0
#define status PORTB.B0

//#######################     Déclaration des Variables    #########################
char txt[255]={0};
char Convert[1]={0};

unsigned int Index_Buffer, tmp, DataReady, Flag_seconde, i, compteur=;
unsigned int Var_Heure, Var_Minute, Var_Seconde, Lancement;
char CMD_mode, BT_state, response_rcvd, responseID, response = 0 ;

//###########################     Interruption    ##################################
void interrupt(){

  if (TMR1IF_bit)            // Interruption sur Timer1 toutes les 100 ms
     {
       TMR1IF_bit = 0;       // RAZ du flag
       TMR1H = 0x9E;
       TMR1L = 0x58;
       compteur++ ;          // On signale que 100ms se sont écoulées
     }

  if (RC1IF_bit == 1) {       // Interruption sur reception UART
     tmp = UART1_Read();      // On enregistre notre byte

     if (CMD_mode){           // Si CMD_mode est égale à 1, l'initialisation n'est pas encore terminée
                             // Tout ce qui arrive sur le buffer est une commande
        switch (BT_state) {
            case  0: {
                      response = 0;                   // Clear response
                      if (tmp == 'C')                 // We have 'C', it could be CMD<cr><lf>  or CONN
                        BT_state = 1;                 // Expecting 'M' or 'N'
                      if (tmp == 'A')                 // We have 'A', it could be AOK<cr><lf>
                        BT_state = 11;                // expecting 'O'
                      if (tmp == 'E')                 // We have 'E', it could be END<cr><lf>
                        BT_state = 31;                // expecting 'N'
                      break;                          // ...
            }
            case  1: {
                      if (tmp == 'M')
                        BT_state = 2;
                      else if (tmp == 'O')
                        BT_state = 22;
                      else
                        BT_state 
= 0;
                      break;
            }
            case  2: {
                      if (tmp == 'D') {
                        response = BT_CMD;           // CMD
                        BT_state = 40;
                      }
                      else
                        BT_state 
= 0;
                      break;
            }
            case 11: {
                      if (tmp == 'O')
                        BT_state = 12;
                      else
                        BT_state 
= 0;
                      break;
            }
            case 12: {
                      if (tmp == 'K'){
                        response = BT_AOK;            // AOK
                        BT_state = 40;
                      }
                      else
                        BT_state 
= 0;
                      break;
            }
            case 22: {
                      if (tmp == 'N')
                        BT_state = 23;
                      else
                        BT_state 
= 0;
                      break;
            }
            case 23: {
                      if (tmp == 'N') {
                        response = BT_CONN;           // SlaveCONNECTmikroE
                        response_rcvd = 1;
                        responseID = response;
                      }
                      BT_state = 0;
                      break;
            }
            case 31: {
                      if (tmp == 'N')
                        BT_state = 32;
                      else
                        BT_state 
= 0;
                      break;
            }
            case 32: {
                      if (tmp == 'D') {
                        response = BT_END;           // END
                        BT_state = 40;
                      }
                      else
                        BT_state 
= 0;
                      break;
            }
            case 40: {
                      if (tmp == 13)
                        BT_state = 41;
                      else
                        BT_state 
= 0;
                      break;
            }
            case 41: {
                      if (tmp == 10){
                        response_rcvd = 1;
                        responseID = response;
                      }
                      BT_state = 0;
                      break;
            }

            default: {
                      BT_state = 0;
                      break;
            }
        }
     }
    else                                   // Une fois l'initialisation finie on remplit notre buffer
      {
        if (tmp == 13)                     // Si on recoit un "CR" fin d'une chaine de caractere
           {
              txt[Index_Buffer] = 0;       // Terminateur de string , on rajoute un 0 pour dire "Fin de la chaine"
              DataReady = 1;               // Une donnée à été recue et est prête , on léve le drapeau
           }
        else                               // Sin on a pas recu de "CR"
           {
              txt[Index_Buffer] = tmp;     // On place la donnée recue dans le tableau txt[] à l'endroit de l'index
              Index_Buffer++;              // Incremente l'index du tableau pour placer la lettre suivante
           }
      }
      RCIF_bit = 0;                       // Ré-arme le flag
  }
}

// -----------------------------------------------------------------------------
char BT_Get_Response() {   // renvoie l'identifiant de la réponse
  if (response_rcvd) {
    response_rcvd = 0;
    return responseID;
  }
  else
    return 0
;
}

//##############################################################################
//#####################     PROGRAMME PRINCIPAL     ############################
//##############################################################################

void main() {
  // Configuration des PORTs
  ANSELA = 0;   // PORT en numérique
  ANSELB = 0;   // PORT en numérique
  ANSELC = 0;   // PORT en numérique
  ANSELD = 0;   // PORT en numérique
  ANSELE = 0;
  
  TRISA 
= 0;             // En sortie
  TRISB = 0;
  TRISC = 0b10000000;    // RC7 En entrée pour reception UART 1
  TRISD = 0b10000000;     // RD7 En entrée pour reception UART 2
  TRISE = 0;
  
//--------------------------------------------------------------------
  UART1_init(9600);    // Initialise l'UART1 à 9600 Bauds
  delay_ms(100);
  UART2_init(9600);
  delay_ms(100);

// Initialisation des variables
  CMD_mode = 1;
  BT_state = 0;
  response_rcvd = 0;
  responseID = 0;
  response = 0;
  tmp = 0;
  DataReady = 0;     // RAZ du flag
  Index_Buffer = 0;  // RAZ dde l'index
  Flag_seconde = 0;  // RAZ du flag seconde
  Lancement = 0;     // RAZ du flag Lancement
  
//-------------     Interruption sur reception UART     ------------------------
  PIR1.RC1IF = 0;     // RAZ Drapeau d'interrutpion
  PIE1.RC1IE = 1;     // Autorise l'INT sur reception Rx de l'UART
  RC2IF_bit = 0;
  RC2IE_bit = 1;

//-------------     reglages timer1 et INT TIMER 1      ------------------------
  T1CON = 0x01;
  TMR1H = 0x9E;
  TMR1L = 0x58;
  TMR1IF_bit = 0;
  TMR1IE_bit = 1 ;
  INTCON = 0xC0;    // Configuration de l'INT GIE et Peripherique

//-------------     Configure le module BlueTooth-Click
  BT_Configure();  // Envoi la configuration au BT au démarrage via le fichier BT_Routines.h

//-------------  Attente de connexion
  while (BT_Get_Response() != BT_CONN);    // Tant que le BT n'est pas connecté on reste ici

  CMD_mode = 0;    // On arrete le mode de commande car le BT est configuré et Connecté

//-------   Indication de connexion
  for (i=0;i<3;i++){
     Led_verte = 1;
     delay_ms(100);
     Led_verte = 0;
     delay_ms(100);
 }

//###################################################################################
 while (1) {

    if (DataReady)              // Si une donnée est recue
       {
         GIE_bit  = 0;          // Interdit les Interutpions le temps du traitement
         DataReady = 0;         // Réarme le flag
         Index_Buffer = 0;      // Raz l'index du buffer

         //---------------  Reception des valeurs du chrono  ---------------------------
         if ( txt[0] == 'c' & txt[1] == 'h') // on verifie le mot de commande "ch" correspondant à chrono
            {
               Var_Heure = txt[3];    // On enregistre les valeurs du chrono recues dans les variables
               Var_Minute = txt[5];
               Var_Seconde = txt[7];

               Lancement = 1;   // On met le flag à 1 pour signaler le Lancement du chrono

            }

         //---------------  Reception de l'arret du chrono  ---------------------------
         else if ( txt[0] == 's' & txt[1] == 't')  // on verifie le mot de commande "st" correspondant à stop
            {
               Lancement = 0;   // On met le flag à 0 pour signaler l'arret du chrono
               Var_Heure = Var_Minute = Var_Seconde = 0;
               Led_rouge = 0;
            }

         GIE_bit = 1;            // On ré-active les INT
       }

//----------------------------------------------------------------------------------
    if ( compteur >= 10)        // Toute les secondes ont envoie les infos pour tenir le fil de vie
          {
           compteur = 0;    // RAZ le compteur de seconde
           
            if 
( Lancement == 1 )  // Si le Lancement à été effetué
               {                   // On effectue le décompte des secondes et on envoie les valeurs par BT
                  Var_Seconde--;   // On décremente une seconde
                  Led_rouge = !Led_rouge ;

                  if (Var_Seconde > 59 )   // Quand la seconde passe de 0 à 255
                     {
                        Var_Seconde = 59;
                        Var_Minute--;      // On décremente une minute
                        if (Var_Minute> 59 )
                           {
                              Var_Minute = 59;
                              Var_Heure--;

                              if (Var_Heure > 59 )  // Si le Compte à rebours arrive à zéro
                                 {
                                   Lancement = 0;   // On arrete le chrono
                                   Led_rouge = 0;
                                   Var_Heure = Var_Minute = Var_Seconde = 0;  // On RAZ les valeurs
                                   delay_ms(2000);

                                 }
                            }
                      }
               }

             if (status)
                {
                   UART1_Write_text("#");   // Mot de reconnaisance pour la tablette
                   UART1_Write(Lancement);  // On indique que le chrono tourne ou non
                   UART1_Write(Var_Heure);
                   UART1_Write(Var_Minute);
                   UART1_Write(Var_Seconde);
                   UART2_Write_text("#");   // Mot de reconnaisance pour la tablette
                   IntToStr(Lancement, convert);
                   UART2_Write_text(Convert);  // On indique que le chrono tourne ou non
                   IntToStr(Var_Heure, convert);
                   UART2_Write_text(Convert);
                   IntToStr(Var_Minute, convert);
                   UART2_Write_text(Convert);
                   IntToStr(Var_Seconde, convert);
                   UART2_Write_text(Convert);
                   UART2_Write(13);
                   UART2_Write(10);
                }
          }

     }
}


Et le Header :

Code : Tout sélectionner

//  Configure le module BlueTooth-Click

// Vous trouverez les configurations du module à cette adresse
// http://ww1.microchip.com/downloads/en/DeviceDoc/bluetooth_cr_UG-v1.0r.pdf


// réponses à analyser et attendues
extern const BT_CMD;
extern const BT_AOK;
extern const BT_CONN;
extern const BT_END;
extern char BT_Get_Response();


//-----------------------   CONFIGURATION DU MODULE   ------------------------------
void  BT_Configure() {

  do {
     UART1_Write_Text("$$$");                  // On rentre dans la configuration
     Delay_ms(100);
  } while (BT_Get_Response() != BT_CMD);       // On reste ICI tant qu'on à pas la réponse du module BT

  do {
    UART1_Write_Text("SN,EasyPic_18F");       // Selection du Nom de notre module qui apparaitra lors de la recherche 20 caractéres max
    UART1_Write(13);
    UART1_Write(10);
    Delay_ms(100);
  } while (BT_Get_Response() != BT_AOK);      // On reste ICI tant qu'on à pas la réponse du module BT

   do {
    UART1_Write_Text("SO,Master");            // Extended status string , pas compris !
    UART1_Write(13);
    UART1_Write(10);
    Delay_ms(100);
  } while (BT_Get_Response() != BT_AOK);     // On reste ICI tant qu'on à pas la réponse du module BT

  do {
    UART1_Write_Text("SM,1");                // selection du mode (0 = esclave, 1 = master, 2 = trigger, 3 = auto-connect, 4 = DTR, 5 = ANY)
    UART1_Write(13);
    UART1_Write(10);
    Delay_ms(100);
  } while (BT_Get_Response() != BT_AOK);     // On reste ICI tant qu'on à pas la réponse du module BT

  do {
    UART1_Write_Text("SJ,00A0");            // Le module est "Connectable"  pendant 100ms
    UART1_Write(13);
    UART1_Write(10);
    Delay_ms(100);
  } while (BT_Get_Response() != BT_AOK);     // On reste ICI tant qu'on à pas la réponse du module BT

  do {
    UART1_Write_Text("SI,0000");            // Le module est non "decouvrable"
    UART1_Write(13);
    UART1_Write(10);
    Delay_ms(100);
  } while (BT_Get_Response() != BT_AOK);     // On reste ICI tant qu'on à pas la réponse du module BT

   do {
    UART1_Write_Text("S|,0303");            // mode "OFF" pendant 3 secondes, mode "ON" pendant 3 secondes
    UART1_Write(13);
    UART1_Write(10);
    Delay_ms(100);
  } while (BT_Get_Response() != BT_AOK);     // On reste ICI tant qu'on à pas la réponse du module BT

   do {
    UART1_Write_Text("SW,0000");            //  Désactivation du mode Low-Power sniff mode
    UART1_Write(13);
    UART1_Write(10);
    Delay_ms(100);
  } while (BT_Get_Response() != BT_AOK);     // On reste ICI tant qu'on à pas la réponse du module BT

  do {
    UART1_Write_Text("SA,0");                // Selection Authentication (0 désactivé , 1 activé) il me semble que ca concerne que l'appairage
    UART1_Write(13);
    UART1_Write(10);
    Delay_ms(100);
  } while (BT_Get_Response() != BT_AOK);     // On reste ICI tant qu'on à pas la réponse du module BT

  do {
    UART1_Write_Text("SP,1");                // Code de sécurité ( SP =Security Pin), à l'origine "SP,1234"
    UART1_Write(13);
    UART1_Write(10);
    Delay_ms(100);
  } while (BT_Get_Response() != BT_AOK);     // On reste ICI tant qu'on à pas la réponse du module BT

  do {
    UART1_Write_Text("---");                 // Indique la fin ! On sort du mode de commande
    UART1_Write(13);
    UART1_Write(10);
    Delay_ms(100);
  } while (BT_Get_Response() != BT_END);    // On reste ICI tant qu'on à pas la réponse du module BT

   // ICI METTRE UNE VISUALISATION POUR VERIFIER QUE LA CONFIGURATION S'EST BIEN PASSEE
}


Peut être existe-t-il une façon élégante d'obtenir le résultat souhaité

Bonne journée
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Dupliquer un UART pour espionner dialogue
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2597
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#2 Message par paulfjujo » mer. 13 juil. 2016 14:57

bonjour,


dedoubler tous les envois UART1 vers UART2 ...

il y a suffisamment de delay entre chaque envoi de char pour eviter de rajouter sun test si le
buffer de transmission est vide.


ci dessous en mode texte ,car on ne peut pas surligner entre balises code .


Capture de ce qui est reçu

if (RC1IF_bit == 1) { // Interruption sur reception UART
tmp = UART1_Read(); // On enregistre notre byte
TXREG2=tmp;
if (CMD_mode){ // Si CMD_mode est égale à 1, l'initialisation n'est pas encore terminée
// Tout ce qui arrive sur le buffer est une commande
switch (BT_state) {
..etc ..


capture de ce qui est envoyé ...

//----------------------- CONFIGURATION DU MODULE ------------------------------
void BT_Configure() {

do {
UART1_Write_Text("$$$"); // On rentre dans la configuration
UART2_Write_Text("$$$\r\n");
Delay_ms(100);
} while (BT_Get_Response() != BT_CMD); // On reste ICI tant qu'on à pas la réponse du module BT

do {
UART1_Write_Text("SN,EasyPic_18F"); // Selection du Nom de notre module qui apparaitra lors de la recherche 20 caractéres max
UART1_Write(13);
UART1_Write(10);
UART2_Write_Text("SN,EasyPic_18F\r\n");
Delay_ms(100);
} while (BT_Get_Response() != BT_AOK); // On reste ICI tant qu'on à pas la réponse du module BT
do {
UART1_Write_Text("SO,Master"); // Extended status string , pas compris !
UART1_Write(13);
UART1_Write(10);
UART2_Write_Text("SO,Master\r\n"); // Extended status string , pas compris !
Delay_ms(100);
} while (BT_Get_Response() != BT_AOK); // On reste ICI tant qu'on à pas la réponse du module BT
Aide toi, le ciel ou FantasPic t'aidera

Dupliquer un UART pour espionner dialogue
Jérémy
Administrateur du site
Administrateur du site
Messages : 2723
Âge : 45
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#3 Message par Jérémy » mer. 13 juil. 2016 15:10

Hello Paul,

Déjà un gros merci pour la petite astuce du \r\n remplaçant leUART1_Write(13);
UART1_Write(10);
. c'est quand même vachement plus agréable à lire.

Ok donc pour la capture de ce qui est envoyé , c'est bien ce que je craignais faut tout recopier sur l'UART2.

PAr contre pour la reception de la partie "initialisation" , je pense pas que ca fonctionne car les lettres sont interprétée une à une . et non en tant que chaine de caractère.
Il faudrait que j'arrive à afficher chaque lettre une à une aussi, mais ce n'est pas possible il faudrait se placer entre deux INT .
Je ne peux pas lancer un UART2_Write_Text(TXREG2); dans l'INT ( je viens d'essayer lol).
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Dupliquer un UART pour espionner dialogue
Jérémy
Administrateur du site
Administrateur du site
Messages : 2723
Âge : 45
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#4 Message par Jérémy » mer. 13 juil. 2016 15:46

Me revoila !

Je ne comprends pas le TXREG2 .

Au départ je pensais que c’était un tableau de caractères , afin de les stockés. Mais en fait pas du tout , il s'agit du registre du buffer TX2.

Mais comment cela fonctionne-t-il ? Je ne comprends pas .

A chaque reception de caractères, on remplit donc notre buffer TXREG2 avec le caractère reçu. pour effet également de RAZ le flag TX2IF.

Comment-il les infos ? quand il est plein ? et comment sait-on qu'il est plein ? quelle est sa taille ?
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Dupliquer un UART pour espionner dialogue
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2597
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#5 Message par paulfjujo » jeu. 14 juil. 2016 21:50

bonsoir,

Il faudrait que j'arrive à afficher chaque lettre une à une aussi,


on remplit donc notre buffer TXREG2 avec le caractère reçu.


TXREG2 est le registre de transmission de l'UART2
il suffit de placer le caractere dedans pour qu'il soit envoyé .. c'est un UART HARDWARE !
et cela n'interfere pas avec l'interrupt , vu qu'on appelle pas une fonction externe.
Dans l'exemple que je te propose TXRREG2 = caractere recu , au sein de l'interruption !
il s'ecoule suffisament de cycle pour ne pas se preocuper de TX2IF , TXREG2 sera forcement vide au prochain passage.
sa taille : 1 byte interne au MCU ..

***********************************************************************************

j'ai testé un (demi : car on a pas besoin de RX ) UART3 TX 100% asm , sortie sur RA2
(pin libre sur mon montage) , donc en transmission seulement !

voici le code de test :
il n'est pas optimisé pour un 18F évolué .. peut tourner meme sur un 16F84 !
le point clé est de bien regler la duree d'un bit
à 19200 bauds duree d'un bit=52µS

un GROS PIEGE à IONS .. data complementé ! car niveau 1 au repos
je me suis fait piegé en testant avec 0x55 et 0xAA .. qui donne inversé 0xAA 0X55 ...me semblait OK
alors qu"en ascci en envoyant "bonjour" , j'affichais n'importe quoi.

Envoi_0x55_UART_Soft_160713.jpg



Avec le debugger et la fenetre watch on "voit" exactement le nb de cycles donc de µS ecoulées dans RS_Delay.
conditions : FOSC =8MHz
à adpter si FOSC est different
de meme la sortie RA2 ..

Inconvenient de cette solution bit-bang
sensible aux interruptions activées (Timer..ou autre perturbation)
mais on peut toujours desactiver GIE_bit avant et apres l'envoi d'un car.
Dans le cas present, l'envoi d'un char bouffera 52*10=520 µS minimum ! 10 cars 5,2mS , 100 cars 52mS
reste possible de l'utilser là ou on met habituellement des Delay_ms(xx);
il n'y a pas photo, un UART Hardware est le must.


Code : Tout sélectionner



  
#define Version "160713"
 // #define Test_Oscillo


#define OSCILLATEUR_INTERNE
#define CLS 12
#define CR 13
#define LF 10
#define BEEP 7

unsigned int i,j,k;

volatile unsigned char c1;
unsigned char TEXTE[80];
unsigned char * txt;

volatile unsigned char c3;
unsigned char RS_Count;
unsigned char  RS_tmp;
unsigned char RS_Delay        ; //temporisation de la durée d'un bit


void Send_Char_on_RA2(unsigned char c1);
void strConstRamCpy(char *dest, const char *source);
void UART3_Write_Text(unsigned char *T);

// --- Copie le texte depuis ROM vers RAM
void strConstRamCpy(char *dest, const char *source)
 {
  while(*source) *dest++ = *source++ ;
  *dest = 0 ;    // terminateur
}

void UART3_Write_Text(unsigned char *T)
{
  while(*(T)>0)     // verif sur VBRAY en mode ASCII
   {
     c3=*(T++);  
     Send_Char_on_RA2
(c3);   // c1 variable globale
   }
}



void Send_Char_on_RA2(unsigned char cx)
{
   c3=~cx;  // complement du caractere !
  _asm{
    RSsend:
        movlw   8                ; 8 bits
        movwf   _RS_Count        
; compteur de bits envoyés
        bcf     LATA
,2            ; bit de start
        call    RSdelai1        
; tempo
       
//   rrf        _c1,f        ; on recupere dans C le bit à envoyer
       //  syntaxe à revoir en fonction du PIC utilisé
    L0:
        rrcf    _c3,1        ; on recupere dans C le bit à envoyer
        btfsc   STATUS
,C        ; bit à envoyer = 1 ?
        goto    L1                ; oui
        bsf     LATA
,2          ; sinon 0
        goto    L2                
; on continue sur la tempo
    L1
:
        bcf     LATA,2          ; bit à 1
    L2
:    call    RSdelai1                ; tempo
        decfsz  _RS_Count
,1        ; on decremente le compteur de bits envoyés
        goto    L0                
; on continue sur les bits suivants
        bcf     LATA
,2         ; bit de stop
        call    RSdelai1        
; tempo pour bit de stop
        bsf     LATA
,2
        call    RSdelai1        
; tempo intercaractere
        call    RSdelai1        
; tempo intercaractere
        goto    LA

    RSdelai1
:   // duree d'un bit à 19200 bauds
         movf _RS_Delay,;    //    parametrable via une variable C ou
         //MOVLW 31 ; 51µs   //    en dur dans le code asm
         MOVWF _RS_tmp ;
    RS0:
         DECFSZ _RS_tmp,;
         GOTO   RS0 ;
         RETURN ;

    LA:    nop;
   }
 }


 void main()
 {

  #ifdef OSCILLATEUR_INTERNE
  OSCCON=0x72;  // 8Mhz
  OSCTUNE=0;
  OSCTUNE.PLLEN=0;  //   0 =sans PLL => 1,2,4,8 ou Q= 8,10 ou 20MHz
  //OSCTUNE.PLLEN=1;  // 1= avec PLL => FOSCx4
   #endif

  
  RS_Delay
=31;     //
  TRISA2_bit=0;
  LATA2_bit=1;
  

  Send_Char_on_RA2
(CLS);
  Delay_ms(500);
  UART3_Write_Text("\r\n");
  Send_Char_on_RA2('A');
  Send_Char_on_RA2('B');
  Send_Char_on_RA2('C');
  Send_Char_on_RA2(CR);
  Send_Char_on_RA2(LF);
  
  txt
=&TEXTE[0];
  strConstRamCpy(txt,"Bonjour, TEST UART SOFT on RA2\r\n");
  UART3_Write_Text(txt);

  i=0;
  while(1)
  {
   txt=&TEXTE[0];
   strConstRamCpy(txt,"Ecriture sur UART3 SOFT on pin RA2   i= ");
   k=strlen(txt);
   WordToStr(i,txt+k);
   strcat(txt,"\r\n");
   // UART3 sortie sur RA2   19200,8,N,1
   UART3_Write_Text(txt);
   i++;
   Delay_ms(500);
  }
 }

 


on obtient sur le Display terminal :


<0>
ABC
Bonjour, TEST UART SOFT on RA2
Ecriture sur UART3 SOFT on pin RA2 i= 0
Ecriture sur UART3 SOFT on pin RA2 i= 1
Ecriture sur UART3 SOFT on pin RA2 i= 2
Ecriture sur UART3 SOFT on pin RA2 i= 3
Ecriture sur UART3 SOFT on pin RA2 i= 4
Ecriture sur UART3 SOFT on pin RA2 i= 5
Ecriture sur UART3 SOFT on pin RA2 i= 6




***************************************************

UART3 38400 bauds

Test sur mon appli gerant le RN41 sur mikrobus #1 , à base de clicker2 18F87J50
inclusion de UART3 software à la place de UART1 hardware , pour espionner les echanges
cette fois avec FOSC=48Mhz
à 38400 bauds soit 1bit 26,04µS 1 cycle = 0,083 µS
Delay bit = 75 + 1 nop inseré dans la boucle
sous debug et watch j'ai 25,5µS pour le call RS_delai
VBray terminal accepte bien 38400 bauds 8,N,1

L'envoi UART est inséré dans la routine d'interrupt RX UART2 , qui recoit donc ce qui est envoyé en retour par le RN41
J'envoi aussi sur UART3 la commande .. ce que le PIC envoi au RN41
on voit donc les echanges aller -retour PIC<-> RN41


Code : Tout sélectionner



#define UART3      // aiguillage compilation avec UART3 ( au lieu de UART1)

unsigned char RS_Count;
unsigned char  RS_tmp;
volatile unsigned char c3;


void UART3_Write(unsigned char c1);
void strConstRamCpy(char *dest, const char *source);
void UART3_Write_Text(unsigned char *T);

void UART3_Write_CText(const char *txt3)
 {
   while (*txt3)
     UART3_Write(*txt3++);
}

void UART3_Write_Text(unsigned char *T)    // at adress  0x002 taille 42 bytes
{
  while(*(T)>0)     // verif sur VBRAY en mode ASCII
   {
     c3=*(T++);
    UART3_Write(c3);   // c1 variable globale
   }
}



void UART3_Write(unsigned char cc)       // delay 75 at 48Mhz pour 38400 bds
{
    c3=~cc;    // complement du caractere !
  _asm{
    RSsend2:
        movlw   8                ; 8 bits
        movwf   _RS_Count        
; compteur de bits envoyés
        bcf     LATA
,2            ; bit de start
        call    RSdelai2        
; tempo
       
//   rrf        _c1,f        ; on recupere dans C le bit à envoyer
       //  syntaxe à revoir en fonction du PIC utilisé
    L00:
        rrcf    _c3,1        ; on recupere dans C le bit à envoyer
        btfsc   STATUS
,C        ; bit à envoyer = 1 ?
        goto    L10                ; oui
        bsf     LATA
,2          ; sinon 0
        goto    L20                
; on continue sur la tempo
    L10
:
        bcf     LATA,2          ; bit à 1
    L20
:    
        call    RSdelai2                
; tempo
        decfsz  _RS_Count
,1        ; on decremente le compteur de bits envoyés
        goto    L00                
; on continue sur les bits suivants
        bcf     LATA
,2         ; bit de stop
        call    RSdelai2        
; tempo pour bit de stop
        bsf     LATA
,2
        call    RSdelai2       
; tempo intercaractere
        goto    LA1

    RSdelai2
:
                              ;75 pour 38400 bds et Fosc=48Mhz  
         MOVLW 75 
;
         MOVWF _RS_tmp ;
    RS00:
         NOP;                ; fait parti de la tempo!
         DECFSZ _RS_tmp,;
         GOTO   RS00 ;
         RETURN ;
    LA1:    nop;
   }
 }


**********************
inclusion de la sortie UART3 dans l'interrupt de reception caractere RX UART2 <-- from TX RN41

//UART2
    if((RC2IF_bit==1) && (RC2IE_bit==1))
    {
      if(OERR2_bit)
      {
          CREN2_bit = 0;
          CREN2_bit = 1;
       }
      if(FERR2_bit)   c2 = RCREG2;
      c2 = RCREG2;
      // UART3_Write(c2) ... developpé ci dessous;
       c3=~c2;    // complement du caractere !
      _asm{
  RSsend:
         movlw   8                ; 8 bits
         movwf   _RS_Count        ; compteur de bits envoyés
         bcf     LATA,2            ; bit de start
         call    RSdelai1        ; tempo
L0:
         rrcf    _c3,1        ; on recupere dans C le bit à envoyer
         btfsc   STATUS,C        ; bit à envoyer = 1 ?
         goto    L1                ; oui
         bsf     LATA,2          ; sinon 0
         goto    L2                ; on continue sur la tempo
L1:
         bcf     LATA,2          ; bit à 1
L2: 
         call    RSdelai1                ; tempo
         decfsz  _RS_Count,1        ; on decremente le compteur de bits envoyés
         goto    L0                ; on continue sur les bits suivants
         bcf     LATA,2         ; bit de stop
         call    RSdelai1        ; tempo pour bit de stop
         bsf     LATA,2
         call    RSdelai1        ; tempo intercaractere
         call    RSdelai1        ; tempo intercaractere
         goto    LA  ;

RSdelai1:
         MOVLW 75 ;             31 pour 19200 et 8Mhz, 75 pour 38400 et 48Mhz
         MOVWF _RS_tmp ;
RS0:    
         nop;
         DECFSZ _RS_tmp,1 ;
         GOTO   RS0 ;
         RETURN ;

  LA: 
        nop;
   }

   
      if (c2!=Terminator)
      {
      
        if(i2>=MAXLEN2-1)
        {
         RC2IE_bit=0 ; //interdit IT Reception UART
         buffer2[i2]=0;
         Index2=i2;
         i2=0;
         c2=0;
          UART2_DataReady=1;
         }
         else
        {
        buffer2[i2]=c2;
        Index2=i2;
        i2++;
        }
      }
    }


et coté envoi PIC-> RN41


Code : Tout sélectionner



unsigned int  BT_Configure_With_Answer_Test
()
{

  #ifdef With_LCD
  OUT_LCD
  gotoxy
(0,3);//01234567890123456
  Nokia_PutRomString("Etape : 0 sur 8 ");
  #endif
  Delay_ms(500);
  LD1=0;LD2=0;
  UART1_Write_CText("---\r");
  UART2_Write_CText("---\r");
  Delay_ms(500);
  State=0;
  Cnt3=15; // 15*200mS soit 3 sec
  Arme_Elapsed_Timer3();
 #ifdef UART3
   UART3_Write_CText("$$$\r  AT Mode Enter");
   #else
  UART1_Write_CText("$$$\r  AT Mode Enter");
  #endif
  do
  
{
    //UART2_DataReady=0; RC2IF_bit=0; i2=0; buffer2[0]=0;PBT=&buffer2[0]; // on nettoye avant
    RAZ_UART2();
    Put_RS2('$');Delay_ms(5);
    Put_RS2('$');Delay_ms(5);
    Put_RS2('$');Delay_ms(5);
   // Enter command mode, attend CMD
   // PAS de CR pour prise de contact !
   // suite test en prise directe Terminal <-> RN41 , il semblerait que
   // la commande contigue $$$ ne passe pas , alors que 3x$ est toujours OK
   // attention Macro VBRAY pour envoi $$$ => mettre $$$$$$  car c'est un caractere special VBRAY
   // ou #036#036#036
    // attention ne pas activer l'ECHO sur le RN41
    while ((UART2_DataReady==0) && (Elapsed==0) && (Index2<3));
  } while ((memcmp(buffer2,"CMD",3)!=0)&& (Elapsed==0));
  Test_BT_Answer();
  //if (State!=1) return(0);


   #ifdef UART3
     UART3_Write_CText("SN,MyBT-DB49 => Device name\r\n");
     #else
    UART1_Write_CText("SN,MyBT-DB49 => Device name\r\n");
    #endif
     
  do 
{
   RAZ_UART2(); // on nettoye avant.
   UART2_Write_CText("SN,MyBT-DB49"); //Name of the device, 20 characters maximum
   UART2_Write(13);
   Delay_ms(500);
   while ((UART2_DataReady==0) && (Elapsed==0)&& (Index2<3));
 } while ((memcmp(buffer2,"AOK",3)!=0) && (Elapsed==0));
 Test_BT_Answer();
 //if (State!=2)return (0);

... etc ...


ce qui donne sur le display terminal UART3

Test envoi sur UART3 : Bonjour
$$$
AT Mode EnterCMD
SN,MyBT-DB49 => Device name
AOK
SU,19.2 => bauds
AOK
ST,255 => Allways AT cdes
AOK
SM,5 => ANY
rAOK
SA,0 disable authentification
AOK
SR,0015832B6D87 => Client PC APM
AOK
SX,1 => Bonded=1
AOK
E =>diplay extended setting :
***ADVANCED Settings***
SrvName= SerialPört
SR,Z
SrvClass=0000
DevClass=1F00
InqWindw=0200
PagWindw=0200
CfgTimer=255
StatuStr=18F_
O => display other settings
***OTHER Settings***
Profile= SPP
CfgChar= $
SniffEna=0
LowPower=0
TX Power=4
IOPorts= 0
IOValues=0
DebugMod=0
RoleSwch=0
--- => Fin mode cde AT
END





comme quoi on peut avoir 4 liaisons RS232 sur ce PIC !
2 UART Hardware UART1, UART2
1 UART virtuel COM HID (via USB)
1 UART software UART3
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.
Aide toi, le ciel ou FantasPic t'aidera

Dupliquer un UART pour espionner dialogue
Jérémy
Administrateur du site
Administrateur du site
Messages : 2723
Âge : 45
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#6 Message par Jérémy » sam. 16 juil. 2016 08:24

Bonjour Paul,

Comme d'habitude un grnd bravo pour cette démonstration ! et pour l'explication du TXREG2 . Je comprends mieux maintenant grâce à toi.
Pour le reste j'avoue que tu m'as un peu perdu de temps en temps ! ton niveau est bien supérieur au miens . Mais dans l'idée je t'ai suivis !

Je pense avoir résolu mon problème d'UART et d'espionnage de liaison ! Le module RN-41 garde encore pas mal de secret surtout avec le mode slave/master et la reconnexion !

En tout cas merci ! je vais passer à l'alimentation
C'est en faisant des erreurs, que l'on apprend le mieux !!!


Retourner vers « Langage C »

Qui est en ligne

Utilisateurs parcourant ce forum : Bing [Bot] et 101 invités