CAN de l'ATmega328P sur Arduino Uno sans Arduino.h

Bonjour, pour un projet étudiant, je dois utiliser le CAN de la Uno mais SANS utiliser les fonctions de la bibliothèque Arduino...

Pour être honnete avec vous, j'ai récuperé un ancien bout de code d'un projet sur Atmega 16, je l'ai bien relus normalement les registres sont les même....

Voici donc mon code :

 #define AREF 5 



void init_ADC(void)
{
  DDRC = 0x00;                          // PortC initialise en ENTRE
  PORTC=0x00;                           // Activation résistance de pullup sur port C 
                          
  ADCSRA=(1<<ADEN)|(1<<ADIF)|(1<<ADPS2)|(1<<ADPS0);       // Activation convertisseur, mise à 0 du flag de fin de conversion
                                    
  ADMUX=0x00;                           // Choix de l'entré de conversion ( ici ADC0)
}

unsigned int convertir (void)
{
  ADCSRA=ADCSRA|(1<<ADSC);                      // Démarrage conversion

  do {
  }while(!(ADCSRA & (1<<ADIF)));                    // Attente fin de conversion 

  ADCSRA= ADCSRA | (1<<ADIF);                   // RAZ flag fin de conversion
  //Serial.println(ADC);
  return ADC ;
                                  // Retourne resultat convertion
}

Mon code est donc sensé faire :

Fonction d'initialisation :

-Tension de réference à 5 Volts
-Port C en entré avec Pullup ( mon entré analogique sur A0 qui est le PIN 23 de l'atmega nommé PC0
-Active le convertiseur et définie l'entre sur A0

Convertion :

  • Démarrage de la convertion ( ADSC = 1 )
    -Attendre que la convertion soit fini
    -Remettre à 0 du flag de fin de convertion

J'ai inclus les bibliothèques : #include <avr/io.h>
#include<stdio.h>
#include <stdlib.h>
#include <arduino.h>
#include <avr/interrupt.h>

Aucun problème à la compilation et pour compiler, mais la valeur de ADC vaut toujours 1023 même quand rien n'es connécté à A0...

Sachant que je controle la valeur de la convertion en la convertissant en tableau de char et la renvoyant sur le port série

J'ai bien relu la doc, je ne comprend vraiment pas...

Merci d'avance pour vos réponses qui me seront d'une grande aide :slight_smile:

Bonjour, pour un projet étudiant, je dois utiliser le CAN de la Uno mais SANS utiliser les fonctions de la bibliothèque Arduino...

Tu ouvre la datasheet du micro atmega328p, au chapitre ADC tu as tous les renseignements nécessaires pour configurer et utiliser l'ADC.
Cerise sur le gateau Atmel joint des petits exemples en C

Copier des "bouts de programme" est la pire des solutions, cela ne te permettra pas de comprendre ce qu'il faut faire.

Pour "ton incompréhension" réfléchi un peu

D'un coté tu écrit :
"Port C en entré avec Pullup"
et de l'autre tu écris :
"mais la valeur de ADC vaut toujours 1023 même quand rien n'est connecté à A0"

Traduis le mot "pull up" en français au lieu de l'utiliser sans comprendre :
Pull up = Résistance de tirage à l'alimentation.
Donc si tu n'a rien en entrée et que la résistance de 30 à 70 k reliée au Vcc est en service c'est peut-être normal que tu mesure 5V c'est à dire 1023 pas.

Par contre si tu as quelque chose de raccordé en entrée tout va dépendre de ce qui est raccordé qui va interagir avec la pull up la résistance de tirage à l'alim, mais comme tu ne dis rien sur ton montage il est impossible de donner une explication matérielle.
PS : l'erreur peut aussi être logicielle.

return ADC ;

Le paragraphe 24.9.3 de la datasheet du ATMEGA328 indique :

Le résultat de la conversion se trouve dans les registres ADCH et ADCL

ADCH et ADCL étant l'octet de poids fort et l'octet de poids faible. Ces valeurs dépendent du flag ADLAR (bit 5) du registre ADMUX.
Dans ton cas

ADMUX=0x00;

donc le flag ADLAR=0

resultat=ADCL|(ADCH<<8);

Bonjour, merci pour vos réponses, j'essaye ça au plus vite, mais il est vrai que vu comme ça ça parait logique !

Et 68tjs, j'ai évidement passé du temps sur la Datasheet avant de faire appel à vous

Certe j'aurai dû passé plus de temps que ça avant de faire appel à ce forum, mais étant en pleine période de partiels, je n'ai pas eu le temps de faire plus que ça, et dans la panique j'ai préferé vite demander de l'aide

Vis à vis de la pullup, j'ai évidement essayer de raccorder quelque chose à l'entré, par le biais premierement de la sortie 3,3 de l'arduino puis ensuite avec un pont diviseur dont je ne connaissait pas la valeur des résistances donc pas la tension de sortie

Vis à vis de récuperer ADC, je vais essayer ta technique, mais la variable ADC existée de base dans l'ATmega 16 sans que j'ai à faire moi même l'assemblage des 2 registres étant donné que cette variable ( ADC) me renvoyé un chiffre en rapport potentiel avec le CAN je me suis dit que cela marche.

Je vais essayer ça au plus vite, encore merci ! :slight_smile:

EDIT : Après ajout de resultat=ADCL|(ADCH<<8); pas plus de résultat, toujours 1023 même avec 3,3V en entrée....

Pourquoi as tu ativé la résistance de tirage ?
Elle te fout la pagaille.

Une "pull-up" sert à fixer un potentiel pour qu'en absence de signal d'entrée il n'y ait pas de "bagotage" en fonction du bruit reçu.
Sans cette résistance si, sur une entrée digitale, on raccorde un long fil dont on laisse l'autre extrémité en l'air, le fil se comportera comme une antenne et on lira aléatoirement des 1 et des 0.
Si l'entrée est analogique elle passera aléatoirement par toutes les valeurs comprises entre 0 et 1023.
Mais dès que l'entrée est raccordée à une charge ce "bagotement" cessera.

Tu teste avec un pont diviseur dont tu ne connais pas les valeurs.
Dessine le schéma sur un bout de papier -> la pull-up se retrouve en parrallèle sur la résistance du pont reliée à l'alim. D'après la datasheet la pull-up peut faire entre 30k et 70k selon le lot de fabrication, si les valeurs du pont ne sont pas nettement plus faibles le résultat est impossible à prédire.
Tu manques de méthode, pour mettre au point il ne faut travailler que sur des montages connu, sinon il ne reste que la boule de cristal.

Déjà il y avait un test simple à faire : utiliser les fonctions arduino, connue pour être fonctionnelles, pour vérifier que le schéma et/ou le câblage est correct, et ensuite mettre au point la mesure avec l'utilisation des registres.

Bonjour,

Dans l'init tu sélectionnes VREF comme référence, je ne sais pas ce que tu as mis sur VREF.

Si tu veux sélectionner AVcc c'est

  ADMUX=(1<<REFS0)|0x00;  // Choix de l'entré de conversion ( ici ADC0) et référence AVcc