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
3em UART software sur 18F46K22 avec IT RB0
- paulfjujo
Expert- Messages : 2597
- Âge : 73
- Enregistré en : juillet 2015
- Localisation : 01800
- Contact :
bonjour,
Pour des besoins de debugging,il peut s'averer avoir besoin d'un 3em UART pour
afficher des resultats , ou recevoir une commande via clavier terminal
(liaison au PIC , via cordon USB/TTL PL2303 ou via Bluetooth mode SSP, ou vrai R232 avec MAX232)
Il est relativement facile d'envoyer des caractères , en définissant la durée d'un bit élémentaire.
En regle générale on part sur un moment de 10 bits classique :
1 start, 8 datas, 1 stop, pas de parité
à 9600 bauds, un bit dure donc : 1 000 000 / 9 600 => 104 µS
La version proposé , utilise RB2 en emission TX et RB0 en reception RX
On peut prendre n'importe quel autre bit , en sortie, pour la transmission
mais le choix RB0 s'impose ici , sur la reception, pour benefitier d'un mode Interruption
preferable à un mode " pooling" bloquant le programme.
nota: J'ai rajouté des R de rappel de 4,7K au +VCC sur RB0 RX et RB2 TX. pour bien fixer les potentiels.
L'envoi d'un caractere 100% en C ou 90% en ASM (inclus dans le C)
le choix étant fait au moment d ela compilation avec la directive
#define Version_ASM
à noter:
les branchement relatif avec la directive d'assemblage pour l'adresse en cours "$" , ne passe pas en mikroC
il faut utiliser une etiquette de branchement.
La Rotation à droite RRF pour PIC16F devient RRCF pour le PIC18F
Au repos RB2 est à 1!
On place le bit de Start =0 pendant 104µS
puis, on pousse chacun des 8 bits data successifs à droite..bit qui tombe alors dans le Carry
suivant le test de celui ci on met à 1 ou pas le bit de sortie B2 (TX)
et on termine par le placement du bit de STOP à 1
les bytes utilises dans les parties en ASM
sont definie dans la Bank0 à des adresses fixes, permettant de les utiliser plus facilement
donc directement avec leur adresses connues.
sinon,il faudrait passer par des pointeurs...etc..gestion de bank..
La partie RECEPTION est plus ardue , car le front descendant RB0 signale l'arrivé d'un caractere
mais avant qu'il soit pris en compte, il faut rajouter les durées de traitement
(Les 2 versions 100%en C ou 90% en ASM à choisir via la directive #define Version_ASM )
Voir le schema explicatif ci-joint , traitant la reception d'un caractere 'A'
T0 globalise les durees de :
- sauvegarde du contexte
- Entre dans le traitement
- quelques inits..
cett duree empiete sur la duree du bit de start , donc on ne voit que 104µS - duree T0
La premiere tempo est legerment inferieure à celle du bit.. mais de toute facon,
on sera ainsi déja situé temporellement sur l'etat du bit suivant ( et non pas sur un front)
de sorte à tester l'etat de RB0 pour savoir si ce bit data est à 1 ou 0
On compte ainsi les 8 bits de data et on se sert d'un bit special CARRY situé dans le registre MCU STATUS
pour le pousser avec l'etat correspondant à la lecture de RB0, dans le registre Ram get_RsByte
via une rotation à doite via Carry bit.
ainsi de suite apres application d'un delay de 104µS.. on echantillone les bits de data toujours au meme endoit.
Au bout de 8 rotations , on a bien les 8 bits datas recu
et on laisse passer le bit de Stop .. avec une tempo plus courte,car il reste du traitement à faire
voir T1 et TX sur schema explicatif..
Le timming est rick rack ! entre la fin d'un car et le debut du suivant,
si les caracteres sont contigus, on ne dispose que de 104µS ,pour stocker le car, sortir de l'interrupt, et y revenir.
Un index Idx permet le rangement de chaque byte reçu dans le buffer_SU
ce traitement reste en C ..
Ici le caractere CR=13=0x0D sert de delimiteur de reception de string
Quand il est rencontré on arme le drapeau RB0_Flag ,
permettant de recuperer le string envoyé par le terminal..
Test d'envoi d'un seul tenant => OK
Cette solution presente l'avantage de ne pas etre BLOQUANTE pour recevoir un message...
MAIS CE N'EST PAS EQUIVALENT A LA SOLUTION SOFT HARDWARE !
le buffer hardware permettant 104µS*10=1040µS minimum entre 2 cars.
10 fois plus de temps dispo.
Des l'arrivé d'un caract par le front descendant, on est bloqué sur les 10 moments du caractere , soit 10x104)1,04mS
Si les caracteres sont contigus..on est Bloqué sur la reception pendant la duree du message
Si 80 car => 80x10x104µS => 83,2mS mimum
Mais le reste du temps , on peut vaquer à autre chose.
le code UART reception via RB0
Projet MikroC
exemple de sortie USARTS
Je pense que notre gourou en ASM MAÏ
saura me (nous) montrer à quel point cela peut etre perfectible...
sans etre à 100% ASM en MPLABX ,car il faut bien pouvoir l'intégré dans MikroC, disons à 99%
Pour des besoins de debugging,il peut s'averer avoir besoin d'un 3em UART pour
afficher des resultats , ou recevoir une commande via clavier terminal
(liaison au PIC , via cordon USB/TTL PL2303 ou via Bluetooth mode SSP, ou vrai R232 avec MAX232)
Il est relativement facile d'envoyer des caractères , en définissant la durée d'un bit élémentaire.
En regle générale on part sur un moment de 10 bits classique :
1 start, 8 datas, 1 stop, pas de parité
à 9600 bauds, un bit dure donc : 1 000 000 / 9 600 => 104 µS
La version proposé , utilise RB2 en emission TX et RB0 en reception RX
On peut prendre n'importe quel autre bit , en sortie, pour la transmission
mais le choix RB0 s'impose ici , sur la reception, pour benefitier d'un mode Interruption
preferable à un mode " pooling" bloquant le programme.
nota: J'ai rajouté des R de rappel de 4,7K au +VCC sur RB0 RX et RB2 TX. pour bien fixer les potentiels.
L'envoi d'un caractere 100% en C ou 90% en ASM (inclus dans le C)
le choix étant fait au moment d ela compilation avec la directive
#define Version_ASM
à noter:
les branchement relatif avec la directive d'assemblage pour l'adresse en cours "$" , ne passe pas en mikroC
il faut utiliser une etiquette de branchement.
La Rotation à droite RRF pour PIC16F devient RRCF pour le PIC18F
Au repos RB2 est à 1!
On place le bit de Start =0 pendant 104µS
puis, on pousse chacun des 8 bits data successifs à droite..bit qui tombe alors dans le Carry
suivant le test de celui ci on met à 1 ou pas le bit de sortie B2 (TX)
et on termine par le placement du bit de STOP à 1
les bytes utilises dans les parties en ASM
sont definie dans la Bank0 à des adresses fixes, permettant de les utiliser plus facilement
donc directement avec leur adresses connues.
sinon,il faudrait passer par des pointeurs...etc..gestion de bank..
Code : Tout sélectionner
void UARTS_Write(unsigned char c)
{
#ifdef Version_ASM
Put_RsByte=c;
_asm {// ------------------------------
// le caractere à envoyer doit se trouver en Put_RsByte
Send_Char:
Movlw 8 ;correspond … un byte de 8 bits
Movwf _RsCount ;place dans RsCount
BCF LATB, 2 ;bit start … 0
Call delay_RS ;wait valeur 1bit at 9600 Bauds (8Mhz)
Send0:
rrcf _Put_RsByte,F ;shift droite dans carry (rrf avec 16F)
Btfsc STATUS,C ;si carry 0 alors saute
// Goto $+3 ; usage de saut relatif pas possible avec mikroC
Goto Send1 ; il faut utiliser des etiquettes de branchement
BCF LATB, 2 ;Tx =0
// Goto $+2
Goto Send2
Send1:
BSF LATB, 2 // TX=1
Send2:
Call delay_RS
Decfsz _RsCount,F ;RsCount =RsCount -1
Goto Send0
BSF LATB, 2
Call delay_RS ;byte envoyé
return
;---------------
//special pour routine d'attente bit 9600 Bauds =>1000000/9600=104µS
// ;3+ 67*3*3=207cycles at 8Mhz => 203* 0.5µS => 103.5 µS
delay_RS:
MOVLW 67 ; .67 pour 9600bds at 8Mhz
MOVWF _Count1 ; 1000000/9600=104µS
delay1:
DECFSZ _Count1,F ; 1 cycle si pas de saut
GOTO delay1 ; // $-1 =>2cycles
NOP
NOP
Return
}
//------ fin asm ------------------------
#else
unsigned int i,j;
unsigned int a;
a=0;
LATB.B2=0,
Delay_us(102);
LATB.B2=1,
sc=c;
// les 8 bits data
for (i=0;i<8;i++)
{
a=sc & Poids[i];
if (a>0)
LATB.B2=1;
else
LATB.B2=0;
Delay_us(84); // au lieu de 104µS
// Init_Timer0(); // 104µS
//while(TMR0IF==0);
}
LATB.B2=1; // bit de stop
Delay_us(102);
//Init_Timer0; //104µS
//while(TMR0IF==0);
LATB.B2=1; // au repos
#endif
}
La partie RECEPTION est plus ardue , car le front descendant RB0 signale l'arrivé d'un caractere
mais avant qu'il soit pris en compte, il faut rajouter les durées de traitement
(Les 2 versions 100%en C ou 90% en ASM à choisir via la directive #define Version_ASM )
Voir le schema explicatif ci-joint , traitant la reception d'un caractere 'A'
T0 globalise les durees de :
- sauvegarde du contexte
- Entre dans le traitement
- quelques inits..
cett duree empiete sur la duree du bit de start , donc on ne voit que 104µS - duree T0
La premiere tempo est legerment inferieure à celle du bit.. mais de toute facon,
on sera ainsi déja situé temporellement sur l'etat du bit suivant ( et non pas sur un front)
de sorte à tester l'etat de RB0 pour savoir si ce bit data est à 1 ou 0
On compte ainsi les 8 bits de data et on se sert d'un bit special CARRY situé dans le registre MCU STATUS
pour le pousser avec l'etat correspondant à la lecture de RB0, dans le registre Ram get_RsByte
via une rotation à doite via Carry bit.
ainsi de suite apres application d'un delay de 104µS.. on echantillone les bits de data toujours au meme endoit.
Au bout de 8 rotations , on a bien les 8 bits datas recu
et on laisse passer le bit de Stop .. avec une tempo plus courte,car il reste du traitement à faire
voir T1 et TX sur schema explicatif..
Le timming est rick rack ! entre la fin d'un car et le debut du suivant,
si les caracteres sont contigus, on ne dispose que de 104µS ,pour stocker le car, sortir de l'interrupt, et y revenir.
Un index Idx permet le rangement de chaque byte reçu dans le buffer_SU
ce traitement reste en C ..
Ici le caractere CR=13=0x0D sert de delimiteur de reception de string
Quand il est rencontré on arme le drapeau RB0_Flag ,
permettant de recuperer le string envoyé par le terminal..
Test d'envoi d'un seul tenant => OK
Cette solution presente l'avantage de ne pas etre BLOQUANTE pour recevoir un message...
MAIS CE N'EST PAS EQUIVALENT A LA SOLUTION SOFT HARDWARE !
le buffer hardware permettant 104µS*10=1040µS minimum entre 2 cars.
10 fois plus de temps dispo.
Des l'arrivé d'un caract par le front descendant, on est bloqué sur les 10 moments du caractere , soit 10x104)1,04mS
Si les caracteres sont contigus..on est Bloqué sur la reception pendant la duree du message
Si 80 car => 80x10x104µS => 83,2mS mimum
Mais le reste du temps , on peut vaquer à autre chose.
le code UART reception via RB0
Code : Tout sélectionner
//======= Pour UART Software avec RX sur RB0 ================
#ifdef With_RB0
// IT on RB0
if ((INT0IE_bit==1) && (INT0IF_bit==1))
{
INT0IE_bit=0;
RB0_IT=1;
#ifdef Version_ASM
_asm {
CLRF _Get_RsByte,1
//special pour routine d'attente bit 9600 Bauds =>1000000/9600=104µS
// 3+ 67*3*3=207cycles at 8Mhz => 203* 0.5µS => 103.5 µS
// en fait on se retouve ensuit bien à l'interieur d'un bit , vu qu'on depasse le delai global Start Bit
// avec le traitement sauvegarde contexte et d'entree interruption front descendant RB0
// --- delai Start Bit -----------------
MOVLW 67 ; .67 pour 9600 bauds et 4Mhz ou 9600bds at 8Mhz
MOVWF _Count1 ; 1000000/9600=104µS
delay10:
DECFSZ _Count1,F ; 1 cycle si pas de saut
GOTO delay10 ; // $-1 =>2cycles
NOP
NOP
// --------
MOVLW 8
MOVWF _Count2
PAS0: ; on pousse le bit adequate à droite dans le registre
BCF STATUS,C ; RAZ Carry
BTFSC RB0_bit,0
BSF STATUS,C ;Set Carry
RRCF _Get_RsByte,1
//--- bit delai ----------------
MOVLW 67 ; .67 pour 104µS avec 9600 bauds at 8Mhz
MOVWF _Count1 ; 1000000/9600=104µS
delay11:
DECFSZ _Count1,F ; 1 cycle si pas de saut
GOTO delay11 ; // $-1 =>2cycles
NOP
NOP
//---------------------------------
DECFSZ _Count2,1 ; // 8 bits passés ?
Goto PAS0
//--- bit Stop un peu plus court ----------------
MOVLW 50 ; .67 pour 9600 bauds et 4Mhz ou 9600bds at 8Mhz
MOVWF _Count1 ; 1000000/9600=104µS
delay12:
DECFSZ _Count1,F ; 1 cycle si pas de saut
GOTO delay12 ; // $-1 =>2cycles
NOP
NOP
} //--- fin asm ----
#else
// TXREG1='@'; // pour debugging sur UART1
isu=0;
Get_RsByte=0;
/*Init_Timer0 à 104µS at 8Mhz
TMR0IF_bit=0;
T0CON = 0xC8;
TMR0L = 0x30;
while(TMR0IF_bit==0);
*/
Delay_us(100);
//on est bien Passé par dessus le bit Start + quelques µS
while(isu<8)
{ /*Init_Timer0 à 104µS at 8Mhz
TMR0IF_bit=0;
T0CON = 0xC8;
TMR0L = 0x30; */
if (PORTB.B0==1)
{
Get_RsByte= Get_RsByte+Poids[isu];
Delay_us(95); // duree d'un bit - plusieurs µS !
}
else
Delay_us(102); // duree 1 bit - 2 µS
// while(TMR0IF_bit==0); // wait fin de bit
isu++;
}
Delay_us(50); // 1/2 bit pour le STOP + code restant à executer
#endif
// le traitement ci dessous empiete sur la duree du bit stop
if ((Get_RsByte==13) || (IdxSU >= MAXLEN_SU-1))
{
Rb0_Flag=1 ;
buffer_SU[IdxSU]=0;
INT0IE_bit=0;
}
else
{
buffer_SU[IdxSU]=Get_RsByte;
IdxSU++;
INT0IE_bit=1;
}
// Delay_us(50); // 1/2 bit pour le STOP + code restant à executer
INT0IF_bit=0;
}
#endif
Projet MikroC
exemple de sortie USARTS
27/09/2016
Test Emission UART Soft sur RB2=TX
18F46k22_UART1_HARDW_SOFT_UART_RB2_RB0_LCD1x16_4bits_160927.c
ÁBCabc123
Test Reception UART Soft RX=RB0=> interrupt
IdxSU= 39
buffer_SU= 27 sept 2016 avec reception 90% en ASM <- string preparé et envoyé depuis le terminal
Je pense que notre gourou en ASM MAÏ
saura me (nous) montrer à quel point cela peut etre perfectible...
sans etre à 100% ASM en MPLABX ,car il faut bien pouvoir l'intégré dans MikroC, disons à 99%
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.
Qui est en ligne
Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 20 invités