IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

[ATMEGA32] Communication UART trop lente


Sujet :

C

  1. #1
    Membre actif
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2006
    Messages
    245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2006
    Messages : 245
    Points : 232
    Points
    232
    Par défaut [ATMEGA32] Communication UART trop lente
    Bonjour,

    J'ai développé une bibliothèque très simple permettant de faire fonctionner une liaison série avec des ATMega.
    Tout se passe bien avec des ATMega88, ATMega128, mais ca plante magnifiquement avec un ATMega32.

    Enfin, quand je dis que ca plante, c'est pas tout à fait vrai : j'arrive bien à envoyer une suite de bits, mais plutôt que de l'envoyer à 19200, il l'envoie à 300, ce qui, vous en conviendrez, n'ai pas très satisfaisant.

    J'ai donc regardé plus en détail la datasheet de l'ATMega32 : tout me paraît correct.
    J'ai vérifié les fuses pour la fréquence d'horloge de mon bousin : 8MHz comme prévu.

    Mais où se cache donc le problème ?

    Voici le code d'initialisation de mon ATMega :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    void uart_init(void)
    {
    #if (CPU_ATMEGA168 == 1 || CPU_ATMEGA88 == 1)
    	// Set baud rate
    	UBRR0 = UBRR_VALUE;
    	// Enable receiver RXEN and transmitter TXEN and RxCIE
    	UCSR0A = (0<<RXC0)|(0<<TXC0)|(0<<UDRE0)|(0<<FE0)|(0<<DOR0)|(0<<UPE0)|(0<<U2X0)|(0<<MPCM0);
    	UCSR0B = (1<<RXCIE0)|(0<<TXCIE0)|(0<<UDRIE0)|(1<<RXEN0)|(1<<TXEN0)|(0<<UCSZ02)|(0<<RXB80)|(0<<TXB80);
    	UCSR0C = (0<<UMSEL01)|(0<<UMSEL00)|(0<<UPM01)|(0<<UPM00)|(0<<USBS0)|(1<<UCSZ01)|(1<<UCSZ00)|(0<<UCPOL0);
    #elif (CPU_ATMEGA128 == 1 || CPU_ATMEGA32 == 1)
            UBRR0H = 0;
    	UBRR0L = UBRR_VALUE;
    	// Enable receiver RXEN and transmitter TXEN and RxCIE
    	UCSR0A = (0<<RXC0)|(0<<TXC0)|(0<<UDRE0)|(0<<FE0)|(0<<DOR0)|(0<<UPE0)|(0<<U2X0)|(0<<MPCM0);
    	UCSR0B = (1<<RXCIE0)|(0<<TXCIE0)|(0<<UDRIE0)|(1<<RXEN0)|(1<<TXEN0)|(0<<UCSZ02)|(0<<RXB80)|(0<<TXB80);
    	UCSR0C = (0<<UMSEL1)|(0<<UMSEL0)|(0<<UPM01)|(0<<UPM00)|(0<<USBS0)|(1<<UCSZ01)|(1<<UCSZ00)|(0<<UCPOL0);
    /*#elif (CPU_ATMEGA32 == 1)
            UBBRH = 0;
            UBBRL = UBBR_VALUE;
    	// Enable receiver RXEN and transmitter TXEN and RxCIE
    	UCSR0A = (0<<RXC0)|(0<<TXC0)|(0<<UDRE0)|(0<<FE0)|(0<<DOR0)|(0<<UPE0)|(0<<U2X0)|(0<<MPCM0);
    	UCSR0B = (1<<RXCIE0)|(0<<TXCIE0)|(0<<UDRIE0)|(1<<RXEN0)|(1<<TXEN0)|(0<<UCSZ02)|(0<<RXB80)|(0<<TXB80);
    	UCSR0C = (0<<UMSEL1)|(0<<UMSEL0)|(0<<UPM01)|(0<<UPM00)|(0<<USBS0)|(1<<UCSZ01)|(1<<UCSZ00)|(0<<UCPOL0);
    */#else
    #  error Unsupported UART !
    #endif
    }
    Je vous fais grâce des lignes de redéfinition des RXC0 en RXC et tout le bataclan.

    Petite précision : je veux aller à 19200 bauds avec une fréquence d'horloge de 8MHz. D'après la datasheet, le UBRR devrait être à 25, soit 0x19, et c'est bien ce que j'ai...

    Merci d'avance pour vos réponses encore une fois écalirantes, je le sais
    Les gens croient qu'il est agréable d'être un super-génie, mais s'ils savaient à quel point il est difficile d'être entouré de super-crétins !
    Calvin dans Calvin et Hobbes (Bill Watterson)

  2. #2
    Membre actif
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2006
    Messages
    245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2006
    Messages : 245
    Points : 232
    Points
    232
    Par défaut
    C'est bon, j'ai trouvé...
    Après une journée de recherches fastidieuses, le problème s'est résolu très facilement, comme d'habitude.
    Le problème venait de ma configuration d'UCSRC : en effet, le bit URSEL (bit n°7) doit être écrit à 1, pour accéder à UCSRC.
    La bonne configuration est donc la suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    UCSRA = (0<<RXC) | (0<<TXC) | (1<<UDRE) | (0<<FE) | (0<<DOR) | (0<<PE) | (0<<U2X) | (0<<MPCM) ;
    UCSRB = (1<<RXCIE) | (0<<TXCIE) | (0<<UDRIE) | (1<<RXEN) | (1<<TXEN) | (0<<UCSZ2) | (0<<RXB8) | (0<<TXB8) ;
    UCSRC = (1<<URSEL) | (0<<UMSEL) | (0<<UPM1) | (0<<UPM0) | (0<<USBS) | (1<<UCSZ1) | (1<<UCSZ0) | (0<<UCPOL) ;
    Dans cette configuration, on a :
    1°) Interruption sur réception
    2°) Pas d'interruption sur envoi
    3°) 1 bit de stop
    4°) 8 bits de données
    5°) Pas de bit de parité

    Si ça peut aider quelqu'un qui a du mal comme moi ...
    Les gens croient qu'il est agréable d'être un super-génie, mais s'ils savaient à quel point il est difficile d'être entouré de super-crétins !
    Calvin dans Calvin et Hobbes (Bill Watterson)

  3. #3
    Membre à l'essai
    Inscrit en
    Novembre 2008
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 6
    Points : 11
    Points
    11
    Par défaut j'ai pas compris ton code
    Serais tu m'expliquer ton code car je n'ai pas très bien compris sachant que j'utilise un atmega 128

    Merci

  4. #4
    Membre du Club
    Inscrit en
    Décembre 2004
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 33
    Points : 40
    Points
    40
    Par défaut
    #elif (CPU_ATMEGA128 == 1
    j'ai pas compris ton code

    serais tu m'expliquer ton code car je n'ai pas très bien compris
    sachant que j'utilise un atmega 128
    Merci
    Comme je vois que l'on n'a pas répondu , je vais essayer de te l'expliquer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ;UCSR0A = (0<<RXC0)|(0<<TXC0)|(0<<UDRE0)|(0<<FE0)|(0<<DOR0)|(0<<UPE0)|(0<<U2X0)|(0<<MPCM0);
    dans UCSR0A tout les bits son a zero donc il ni as aucune configuracion
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ;UCSR0B = (1<<RXCIE0)|(0<<TXCIE0)|(0<<UDRIE0)|(1<<RXEN0)|(1<<TXEN0)|(0<<UCSZ02)|(0<<RXB80)|(0<<TXB80);
    dans UCSR0B les bits 3 - 4 - 7 sont marqués à 1 ce qui veut dire selon le datasheet


    ; RXCIE RX le bit à 1 permet de prendre en compte les interruptions sur la réception complète dans RXC
    ; RXEN0: doit être a 1 pour valider l'opération à partir de l'UART en mode de réception
    ; TXEN0 TX le bit à 1 permet de prendre en compte l´Activation de la transmission de l’USART

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    ;|RXCIE0 |TXCIE0 |UDRIE0|RXEN0|TXEN0|UCSZ02|RXB80|RXB80|
    ;   1       0       0     1      1     0      0     0     LDI  R16,0x98
    LDI TEMP,(1<<RXEN0)|(1<<TXEN0)|(1<<RXCIE0);/ Active Réception et Transmission
    OUT UCSR0B,TEMP ;\ en tenant compte les interruptions sur la réception
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ;UCSR0C = (0<<UMSEL1)|(0<<UMSEL0)|(0<<UPM01)|(0<<UPM00)|(0<<USBS0)|(1<<UCSZ01)|(1<<UCSZ00)|(0<<UCPOL0);
    ; Le registre UCSR0C distribue la même position d'entrée - sortie pour enregistrer UBRR0L
    ; Le Registre UCSR0C Choisi entre le fonctionnement synchrone et asynchrone ;Set frame format

    ;UCSR0C:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    ;|UMSEL01|UMSEL00|UPM01 |UPM00 |USBS0 | UCSZ01 /UDORD0 | UCSZ00 / UCPHA0 | UCPOL0 |
    ;   0       0       0      0      0          1                  1            0    = LDI  R16,0x06
    ; UCSZ01 - UCSZ00 du registre UCSR0C:
    ; combiné avec le registre UCSZ02 du registre UCSR0B:
    ; Défini le nombre de bits de données Du caractère a envoyé ou a recevoir

    ; UMSEL01 | UMSEL00 = sélectionne le Protocole = 0 0 = Asynchronous USART
    ; UPM01 | UPM00 | = sélectionne la parité = 0 0 = Pas de bit de parité
    ; USBS0 | /= Sélectionne le nombre de bits de stop
    ; \= A la fin de Transmission = 0 = 1 bit de stop
    ; UCSZ01 / UDORD0 | =\ (1<<UCSZ01)=1=\détermine la quantité de bits du caractère
    ; UCSZ00 / UCPHA0 | =/ (1<<UCSZ00)=1=/ 8 bits de données
    ; UCPOL0 | = polarité de l´horloge de départ vers Rx Tx = Falling XCKn Edge

    LDI TEMP,(1<<UCSZ01)|(1<<UCSZ00) ;= 8data,1stop bit
    STS UCSR0C,TEMP

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Convolution trop lente...
    Par progfou dans le forum Traitement d'images
    Réponses: 6
    Dernier message: 05/08/2006, 11h44
  2. Communication Série un peu trop lente?
    Par SimonBrodeur dans le forum VB 6 et antérieur
    Réponses: 22
    Dernier message: 16/01/2006, 14h41
  3. boucle while trop lente
    Par atouze dans le forum Access
    Réponses: 17
    Dernier message: 15/06/2005, 16h35
  4. [SAGE] ODBC trop lent
    Par tileffeleauzed dans le forum Décisions SGBD
    Réponses: 1
    Dernier message: 14/11/2004, 09h56
  5. Envoi de mail trop lent
    Par MASSAKA dans le forum ASP
    Réponses: 3
    Dernier message: 15/10/2004, 10h57

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo