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 ---
- 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 ---
Modérateur : Jérémy
Dupliquer un UART pour espionner dialogue
-
Jérémy
Administrateur du site- Messages : 2723
- Âge : 45
- Enregistré en : juillet 2015
- Localisation : Dans le sud
- Contact :
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 .
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) :
Et le Header :
Peut être existe-t-il une façon élégante d'obtenir le résultat souhaité
Bonne journée
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 .
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=0 ;
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
Dupliquer un UART pour espionner dialogue
- paulfjujo
Expert- Messages : 2597
- Âge : 73
- Enregistré en : juillet 2015
- Localisation : 01800
- Contact :
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
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
Dupliquer un UART pour espionner dialogue
-
Jérémy
Administrateur du site- Messages : 2723
- Âge : 45
- Enregistré en : juillet 2015
- Localisation : Dans le sud
- Contact :
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).
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).
Dupliquer un UART pour espionner dialogue
-
Jérémy
Administrateur du site- Messages : 2723
- Âge : 45
- Enregistré en : juillet 2015
- Localisation : Dans le sud
- Contact :
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 ?
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 ?
Dupliquer un UART pour espionner dialogue
- paulfjujo
Expert- Messages : 2597
- Âge : 73
- Enregistré en : juillet 2015
- Localisation : 01800
- Contact :
bonsoir,
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.
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.
on obtient sur le Display terminal :
***************************************************
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
et coté envoi PIC-> RN41
ce qui donne sur le display terminal UART3
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
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.
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,0 ; // parametrable via une variable C ou
//MOVLW 31 ; 51µs // en dur dans le code asm
MOVWF _RS_tmp ;
RS0:
DECFSZ _RS_tmp,F ;
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,F ;
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.
Dupliquer un UART pour espionner dialogue
-
Jérémy
Administrateur du site- Messages : 2723
- Âge : 45
- Enregistré en : juillet 2015
- Localisation : Dans le sud
- Contact :
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
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
Qui est en ligne
Utilisateurs parcourant ce forum : Bing [Bot] et 101 invités