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 en BASIC et PASCAL !

Modérateur : Gérard

[PASCAL] problème interruptions timer0 et UART
k_lab
Membre
Membre
Messages : 10
Enregistré en : septembre 2016

#11 Message par k_lab » dim. 11 sept. 2016 17:40

Re Re!

Je continue mon monologue (désolé d'inonder de messages).

Eureka! Ca marche!

J'ai retiré les caractères nuls dans les envois comme expliqué dans mon dernier post.

Il semble que UART1_Read_Text n'appréciait pas la lecture du seul caractère 'z'.
Je teste donc d'abord si RxData correspond au caractère "z" et puis pour les autres cas, ce qui fonctionnait déjà pour mon entier (word) sous forme de string, j'utilise UART1_Read_Text.

Voilà, j'espère que c'est clair et que ça servira a un débutant en UART comme moi!

Merci maï et Jeremy vos justes remarques et votre stimulation.

Bravo pour le forum! Dommage que je ne joue pas encore dans la cour des grands (ASM et C), je viens de m'y mettre avec l'excellent livre de Remy Mallard (sonelec): "Les microcontrolleurs Pic pour les débutants" (avec mikroPascal) , elektor.

voici le code fonctionnel pour la partie réception:

Code : Tout sélectionner

program DISPLAYV2;

Declarations section }

var
iValueword;
iDispbyte;
txtstring[5];
RxStatusbyte;
RxDatabyte;
toDispAbyte;  // unités
toDispBbyte;  // dizaines
toDispCbyte;  // centaines

function DispChar(charnumbyte): byte;
begin
     
case charnum of
          0 
result := %11000000;
          
result := %11111001;
          
result := %10100100;
          
result := %10110000;
          
result := %10011001;
          
result := %10010010;
          
result := %10000010;
          
result := %11111000;
          
result := %10000000;
          
result := %10010000;
     
end;
end;

procedure Disp_Refresh;
var
toDispbyte;

begin
     PORTC.5 
:= 0;     // display 1 off
     
PORTA.4 := 0;     // display 2 off
     
PORTA.5 := 0;     // display 3 off

     
case iDisp of
          1 
begin

            PORTC.5 
:= 1;              // display 1 on
            
toDisp := DispChar(toDispA);
            
end;
          
begin

            
if iValue >= 10 then
            begin
            PORTA.4 
:= 1;              // display 2 on
            
toDisp := DispChar(toDispB);
            
end;
            
end;
          
begin

            
if iValue >= 100 then
            begin
            PORTA.5 
:= 1;              // display 3 on
            
toDisp := DispChar(toDispC);
            
end;
            
end;
      
end;

      
PORTA.2 := toDisp.0;
      
PORTC.0 := toDisp.1;
      
PORTB.6 := toDisp.2;
      
PORTB.4 := toDisp.3;
      
PORTC.2 := toDisp.4;
      
PORTA.1 := toDisp.5;
      
PORTA.0 := toDisp.6;
      
PORTC.1 := toDisp.7;
end;

procedure Interrupt;
begin

if PIR1.RCIF 1 then // interruption réception donnée module UART
begin
     RxStatus 
:= RCSTA;    // détection erreur flux de données reçues
     
RxData := RCREG;      // lire ce registre pour reset UART Interrupt flag
     
if (RxStatus and %00000110) = 0 then  // si pas d'erreur
        
begin
        
if RxData 122 then          // char 'z' received
           
PORTC.4 := PORTC.4 xor 1
        
else
          
begin
          UART1_Read_Text
(txt'*'10);
          
iValue := StrToword(txt);
          
end;
        
end
      
else
      
begin                        // si erreur on efface!
      
Clearbit(RCSTA CREN);
      
Setbit(RCSTACREN);
      
end;

end;

if 
INTCON.T0IF =  1 then        // timer 0 overflow
   
begin
        INTCON
.T0IF := 0;         // reset flag to enable further interrupts
        
Inc(iDisp);
        if 
iDisp 4 then
        iDisp 
:= 1;
        
Disp_Refresh;
   
end;
end;


procedure mainInit;

begin

  OSCCON
.SCS := 1;               // Internal oscillator is used for system clock
  
OSCCON.IRCF0 := 1;           // 8 Mhz Internal Clock
  
OSCCON.IRCF1 := 1;           // 8 Mhz Internal Clock
  
OSCCON.IRCF2 := 1;           // 8 Mhz Internal Clock

  
CM1CON0 := 0;                 // comparator C1 off
  
CM2CON0 := 0;                 // comparator C2 off

  
TRISA := %00001000;
  
TRISB := %00100000;            // RB5 = RX = USART IN
  
TRISC := %00000000;

  
ANSEL := %00000000;          // disable analog channels
  
ANSELH := %00000000;         // disable analog channels
  //ADC_Init;                    // initialize adc module

  
INTCON.GIE := 1;             // global Interrupts enable
  
INTCON.PEIE := 1;            // peripheral interrupts enable

  
OPTION_REG.T0CS := 0;        // source: internal FOSC/4 for timer 0
  
OPTION_REG.PSA := 0;         // prescale assigned to timer 0
  
OPTION_REG.PS0 := 1;         //
  
OPTION_REG.PS1 := 0;         // 1:64
  
OPTION_REG.PS2 := 1;         //

  
INTCON.T0IE := 1;            // enable timer 0 interrupts
  
INTCON.T0IF := 0;            // reset timer 0 flag


  
delay_ms(100);               // stabilize

  
  ///////////////USART
  
  
TXSTA.TX9 :=0;
  
TXSTA.TXEN := 1;
  
RCSTA.CREN := 1;
  
RCSTA.SPEN :=1;
  
PIE1.RCIE := 1;              // enable uart RX interrupts
  
PIE1.TXIE := 0;              // no TX interrupt
  
UART1_init(9615);            // initialize UART module for RS232 display
  
delay_ms(200);               // stabilize


  
    
a

  
// display off

  
PORTA.0 :=  1;
  
PORTA.1 :=  1;
  
PORTA.2 :=  1;
  
PORTC.0 :=  1;
  
PORTB.6 :=  1;
  
PORTB.4 :=  1;
  
PORTC.2 :=  1;
  
PORTC.1 :=  1;

end;



begin
  
Main program }
  
mainInit;

  
iDisp := 1;
  
iValue := 0;


  while 
true do
  
begin
    toDispA 
:= iValue mod 10;              // unités
    
toDispB := (iValue div 10mod 10;     // dizaines
    
toDispC := (iValue div 100mod 10;    // centaines
  
end;




end

[PASCAL] problème interruptions timer0 et UART
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 44
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#12 Message par Jérémy » dim. 11 sept. 2016 17:58

Désolé de ne pas plus participé, mais je débute aussi en langage 'C'. Alors je ne voudrais pas te mettre dans la mouise avec un conseil foireux , car je ne suis pas sûr de moi.

Je pense qu'en même que ta facon de traiter la reception n'est pas la meilleur .
d'apres mes lectures et exemples trouvé ici et la, j'ai opté pour une méthode plus traditionnelle disons .

Je lis le buffer UART sur Interruption et l'enregistre ( ainsi il raz le flag).

Si ce charactere recu est un certain caractère ( par exemple CR ou LF) , alors cela signifie que c'est la fin de notre chaine de caractére ( string). donc on rajoute un NULL a la suite pour former une chaine de caractère.
Si on a pas ce caractère spécial , on continue a enregistrer les caractères à la suite en incrémentant un index pour former notre chaine.

voici un exemple en 'c' avec les commentaires pour bine comprendre.

Code : Tout sélectionner

void interrupt(){

  if (
RCIF_bit == 1) {      // Si INT UART détecté

    
temp UART1_Read();      // On récupere et stock la donnée

          
if (temp == 10)         // Si "LF" detecté fin du message
             
{
               
DataReady 1;      // On signale au main qu'un message est pret
               
Buffer[Index] = // On rajoute un terminateur de string pour former la chaine
               
Index ;         // On se place au depart pour le mot suivant
              
}
           else
            {
               
Buffer[Index] = temp// Sinon on rajoute la lettre au Buffer
               
Index++;              // On incremente pour le caractere suivant
            
}
   }


Sinon pas de problème tu ne pollue le forum bien au contraire, tu le fais vivre !
C'est en faisant des erreurs, que l'on apprend le mieux !!!

[PASCAL] problème interruptions timer0 et UART
Guest
Confirmé
Confirmé
Messages : 800
Enregistré en : mars 2017

#13 Message par Guest » lun. 12 sept. 2016 09:46

Bonjour

C'est très bien, tu as trouvé :bravo: Simple remarques. Tu devrais laisse le verrou sur le TIMER, quand tu reçois de UART de plus est plusieurs données .C'est juste bon à perdre des données en cours de route. Quand il a problème il faut s'assurer, que chaque module fonctionne correctement, et sans possibilité de perturbation (exemple modification de variable).

Après ce n'est que des remarques :wink:

Allez A +
Et plaisir de te lire

[PASCAL] problème interruptions timer0 et UART
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2589
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#14 Message par paulfjujo » lun. 12 sept. 2016 17:41

bonoir k_lab

si en pascal , c'est comme en C
'z' delimite 1 seul caractere Z
"z" delimite un string => caractere 'Z' suivi d'un zero implicite

Code : Tout sélectionner

UART1_Write_Text('z*0');

à remplacer par
UART1_Write_Text
("z");


oops j'etais encore sur la page 1 de ce post !
Aide toi, le ciel ou FantasPic t'aidera


Retourner vers « Langage BASIC & PASCAL »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 36 invités