-
19/05/2011 - 05h46 gcortex
ATmega
Bonjour à tous,
1ère question, triviale mais je trouve pas l'info :
comment initialiser le pointeur de pile sur un ATmega (8) ?
merci. je reviendrai.
-
19/05/2011 - 09h32
Re : ATmega
En assembleur: Code: SPI_INIT:
ldi r16,low(RAMEND)
out Spl,r16
ldi r16,high(RAMEND)
out sph,r16 En C, rien à faire, le compilo s'en occupe. Si tu as le message d'erreur en C, il semblerait que ce soit un problème de versions de logiciels. Si tu veux le trifouiller, il faut aller voir dans la config du linker
-
19/05/2011 - 09h49 gcortex
Re : ATmega
merci
à propos de logiciel tout allait bien avec avr studio 4
maintenant avec la version 5 rien ne va plus -> je vais essayer "import project"
-
19/05/2011 - 10h01 gcortex
Re : ATmega
çà marche ! mais je traine toujours mon problème d'adc depuis des mois
(en fait je programme des pics, et je regarde l'atmega quand j'ai le temps)
atmega8-3x74LS47-3 afficheurs -> fonctionne
pin 20,21 = 5V
pin 28 = potar -> tension OK
mais mon adc me retourne toujours 640 en décimal
cette ébauche de programme alterne 000 et 640 !!! Code: .include "m8def.inc"
SP_INIT:
ldi r16,low(RAMEND)
out Spl,r16
ldi r16,high(RAMEND)
out sph,r16
reset:
LDI R16,0xFF
OUT DDRD,R16 ;aff dizaines & unités
LDI R16,0x0F
OUT DDRC,R16 ; aff centaines
;
CLR R16
OUT PORTD,R16
OUT PORTC,R16 ; affiche 000
;
LDI R20,0x05
STS ADMUX,R20 ; IN=ADC5
LDI R20,0x87
STS ADCSRA,R20 ; En, F/128
MAIN:
CLR R22
CLR R23
CALL tempo
LDI R20,0xC7
STS ADCSRA,R20 ;Start ADC
CALL tempo
LDS R26,ADCL ; lire ADC
LDS R27,ADCH
; LDI R27,0x02 afficher 520 = OK
; LDI R26,0x08
; Hexa -> BCD
C:
TST R27
BREQ OXX
SBIW R26,0x32
SBIW R26,0x32
INC R23
RJMP C
OXX:
CPI R26,0x64
BRLO D
SUBI R26,0x64
INC R23
RJMP OXX
D:
CPI R26,0x0A
BRLO U
SUBI R26,0x0A
INC R22
RJMP D
U:
SWAP R22
ADD R22,R26
OUT PORTD,R22
OUT PORTC,R23
CALL tempo
CALL tempo
RJMP reset
;
tempo:
LDI R17,0x08
LOOP:
SER R18
FLOOP:
SER R19
VFL:
DEC R19
BRNE VFL
DEC R18
BRNE FLOOP
DEC R17
BRNE LOOP
RET -
19/05/2011 - 10h49
Re : ATmega
Attention, le prescaler de l'ADC doit être réglé de façon à ne pas dépasser une certaine fréquence.
De plus, AREF (broche 21) est une sortie si tu utilises la référence interne ou AVcc comme référence. Il ne faut donc pas la relier à Avcc, mais plutôt lui mettre un condo de découplage, et éventuellement t'en servir pour alimenter un potar.
Vu ton code on dirait que c'est bon (clock/128 et utilisation de Aref en externe).
Méfie-toi des tempos. Un AVR ça tourne 4 fois plus vite qu'un PIC16 pour un même quartz. La tempo pourrait être trop courte pour permettre la complétion de la conversion.
Tu devrais plutôt tester ADSC pour vérifier si la conversion est terminée.
Egalement, tu utilises STS pour accéder aux registres ADC, qui est l'accès à la SRAM, hors les registres ne sont pas là.
Si les registres ADC sont déclarés dans ton include à la suite des DDRx, utilise OUT comme pour les registres DDRx.
Si ils sont déclarés avec un offset de 0x20 (alias en RAM), utilise ST
Merci de me remettre le nez dans l'assembleur, ça faisait bien longtemps que je n'y avais pas touché 
Pour plus tard, prends garde à ne pas écraser les adresses mémoire des vecteurs d'interruption. Page 47 de la datasheet de l'Atmega8, tu as un bout de code typique (et le fameux rjmp RESET)....D'ailleurs l'initialisation de la pile y est aussi -
19/05/2011 - 10h54 bobfuck
Re : ATmega
Un AVR ça se programme en C...
Quand on met un bit dans un registre, on met un commentaire à côté pour se rappeler ce que ça veut dire (et pas "0xC7" ) accessoirement avec des #define LISIBLES.
Je sais pas si c'est le cas sur ton AVR mais sur le mien (90PWM3B) il faut attendre que la PLL de l'horloge soit stabilisée.
Et AREF étant une sortie d'impédance élevée si tu choisis AREF=AVCC, il ne faut rien brancher dessus (sauf une capa). Et il faut attendre au boot que la capa se charge si elle est grosse...
Tiens, un exemple : Code: // Deactivate digital inputs on analog pins
DIDR0 = | DIDR0_CURRENT
| DIDR0_VOLTAGE
| DIDR0_BATT_VOLTAGE
| DIDR0_TEMPERATURE
;
/*****************************************
Clock Setup
*****************************************/
// Setup PLL for PSC peripherals :
Start_pll_32_mega();
Wait_pll_ready();
// Setup CPU clock prescaler to 8 MHz.
CLKPR = Bit(CLKPCE);
CLKPR = 1; // divide default 16 MHz clock by 2 => 8MHz
/*****************************************
ADC setup
*****************************************/
ADMUX = ADMUX_REFS_BITS | // Ref is AVcc with external capacitor connected on the AREF pin
ADC_CURRENT;
ADCSRA = Bit(ADEN) | // Enable ADC
Bit(ADATE) | // Autotrigger
Bit(ADIE) | // Enable ADC Interrupt
3; // ADC clock prescaler
ADCSRB = Bit(ADHSM) // ADC High Speed Mode
| 10 // PSC2ASY Event
; Pour détecter la fin de conversion il faut regarder le bit qui t'indique que la conversion est terminée dans le registre approprié (ou utiliser une interruption). Possible que ta tempo soit trop courte...
Vérifie la config de l'ADC (tu as bien configuré tous les registres ?), et que tu lis ADCH et ADCL dans le bon ordre.
-
19/05/2011 - 13h12 gcortex
Re : ATmega
 Envoyé par ftorama De plus, AREF (broche 21) est une sortie si tu utilises la référence interne ou AVcc comme référence. Il ne faut donc pas la relier à Avcc, mais plutôt lui mettre un condo de découplage, et éventuellement t'en servir pour alimenter un potar. A l'origine Aref n'était pas relié
j'ai ensuite mis un strap pour être sûr
mais tu soulèves un problème intéressant :
si je mets une référence de tension externe
et que je configure accidentellement une
référence interne (5V ou 2V56), çà va cramer ?
La tempo pourrait être trop courte pour permettre la complétion de la conversion.
c'est sûr
ici j'ai de la marge (1s) 
Tu devrais plutôt tester ADSC pour vérifier si la conversion est terminée.
pourquoi pas
ici j'ai voulu aller au plus simple
Egalement, tu utilises STS pour accéder aux registres ADC, qui est l'accès à la SRAM, hors les registres ne sont pas là.
Si les registres ADC sont déclarés dans ton include à la suite des DDRx, utilise OUT comme pour les registres DDRx.
Si ils sont déclarés avec un offset de 0x20 (alias en RAM), utilise ST

Le problème est donc là.
j'ai pas tout saisi. tu n'aurais pas un cours dessus ?
Pour plus tard, prends garde à ne pas écraser les adresses mémoire des vecteurs d'interruption. Page 47 de la datasheet de l'Atmega8, tu as un bout de code typique (et le fameux rjmp RESET)....D'ailleurs l'initialisation de la pile y est aussi quand j'arriverai jusque là, j'aurai des cheveux blancs 
Un grand merci -
19/05/2011 - 13h19 gcortex
Re : ATmega
 Envoyé par bobfuck Un AVR ça se programme en C... probablement mais vu la richesse du jeu d'instruction et le nombre de registres,
je me suis laissé tenté par l'assembleur (tous mes collègues disent que je suis mazo) 
Merci pour tes réponses
-
19/05/2011 - 14h01
Re : ATmega
 Envoyé par gcortex A l'origine Aref n'était pas relié
j'ai ensuite mis un strap pour être sûr
mais tu soulèves un problème intéressant :
si je mets une référence de tension externe
et que je configure accidentellement une
référence interne (5V ou 2V56), çà va cramer ? Y'a des chances effectivement, comme toute broche mise en court-jus d'ailleurs...Par défaut, Aref est configuré en entrée, les risques sont moindres.
c'est sûr
ici j'ai de la marge (1s) J'ai pas calculé, j'ai juste émis le doute, on sait jamais 
pourquoi pas
ici j'ai voulu aller au plus simple
Pas besoin de plus pour le moment...
Le problème est donc là.
j'ai pas tout saisi. tu n'aurais pas un cours dessus ?
page 18 de la datasheet, tu as le schéma avec la correspondance. En gros les 1ko de SRAM sont placés en mapping mémoire à partie de 0x060 jusqu'à 0x45F.
Les 32 registres de travail sont à partir de 0x0000 et les registres d'entrées-sorties sont à partir de l'adresse 0x020. Seulement, ils disposent d'un autre mode d'adressage ou ils sont placés à partir de l'adresse 0x000. Je ne sais pas trop pourquoi ces deux adresses cohabitent, sans doute pour des questions de compatibilité...
Page 24 de la doc, on te dit que si tu accèdes via les adresses partant de 0, tu dois utiliser IN et OUT. Si tu utilises les adresses à partir de 0x20, tu dois utiliser ST et LD.
Je soupçonne STS et LDS de n'être utiles qu'à partir de 0x060 mais je ne m'y engagerai pas, je ne maîtrise pas assez l'assembleur.
Un petit tour dans le m8def.inc te dira à quelle valeur correspond ADCSRA.
Si tu as un ".equ ADCSRA 0x06" alors il faut utiliser IN et OUT.
Si tu as un ".equ ADCSRA 0x26", ST et LD
L'avantage d'utiliser les adresses basses, c'est de pouvoir accéder directement aux bits par CBI et SBI
Par exemple, pour lancer la conversion, tu écris: Code: LDI R20,0xC7
STS ADCSRA,R20 ;Start ADC Alors que tu peux écrire plus simplement: Deux fois plus rapide, pas de registre utilisé comme buffer et une conservation de l'état précédent de ADCSRA (autrement dit, pas besoin de modifier tout le prog si tu touches au prescaler par exemple ou de faire un masquage)
quand j'arriverai jusque là, j'aurai des cheveux blancs Encore faudrait-il qu'ils repoussent 
Les interruptions sont hyper simples à utiliser...un vecteur différent par interruption (ça change hein ), pas de priorité à gérer (mais leur hiérarchie est assez logique), le placement des adresses sur la pile est automatique.
Au pire, il faut sauvegarder les registres de travail à la main, mais avec 32 registres, il est aussi possible de les répartir entre programme principal et routines d'interruption.
En gros ton programme commence par un ensemble de sauts, le premier étant le reset, dirigé normalement vers le début du programme Code: rjmp Reset
rjmp INT0_H
rjmp INT1_H
rjmp TIMER2_COMP_H
.
.
.
rjmp SPM_RDY_H
Reset: début effectif du programme
INT0_H:
//routine éventuelle
iret Dans les interruptions inutilisées, tu fais un rjmp Reset. Comme ça si une interruption non souhaitée (erreur de config) survient, le programme redémarre plutôt que de partir dans la quatrième dimension. Sinon un simple iret dans la routine permet d'en sortir immédiatement et de continuer l'exécution, moyennant la perte de quelques temps de cycle
Un grand merci De rien...mais je suis assez d'accord avec Bobfuck pour te conseiller le C. Tu t'évites bien des noeuds dans les neurones, pour un résultat quasi-identique, voire meilleur que l'assembleur à la main
Dernière modification par ftorama ; 19/05/2011 à 14h04.
-
19/05/2011 - 19h22 bobfuck
Re : ATmega
Et puis les libraries C pour l'AVR sont quand même bien faites.
Au début, par exemple tu utilises les fonctions setup_machin() et adc_get_result(), tu as pratiquement une fonction C par fonction du uC, c'est très clair.
Ensuite, tu regardes dans les headers et la datasheet, et tu remplaces certaines fonctions par le code source original (par exemple c'est pas la peine d'appeler 4 fonctions pour initialiser le même registre !... ça économise de la flash).
A la fin sans t'en apercevoir tu as appris à utiliser les registres du uC.
La gestion des interruptions en C est aussi totalement classe : Code: ISR(ADC_vect)
{
uint16_t adc = Adc_get_10_bits_result();
...
} et hop une routine d'interruption !
-
19/05/2011 - 22h17 PIC sur PAC
Re : ATmega
bonsoir,
Et puis les libraries C pour l'AVR sont quand même bien faites.
Au début, par exemple tu utilises les fonctions setup_machin() et adc_get_result(), tu as pratiquement une fonction C par fonction du uC, c'est très clair.
je profite de cette discussion pour en apprendre encore un peu:
j'ai foncé bille en tête pour utiliser l'AVR sans penser aux librairies car j'ai pas l'impression quelles soient fournies avec la suite AVR, je me trompe?
-
19/05/2011 - 22h32 bobfuck
Re : ATmega
C'est fourni avec avrstudio, fouille dans les programmes d'exemple.
Ceci dit tu peux aussi bien patouiller les registres à la main... mais c'est sympa pour débuter, ça te donne un stock de code tout cuit.
-
19/05/2011 - 22h53
Re : ATmega
 Envoyé par bobfuck C'est fourni avec avrstudio, fouille dans les programmes d'exemple.
Ceci dit tu peux aussi bien patouiller les registres à la main... mais c'est sympa pour débuter, ça te donne un stock de code tout cuit. Mais...mais...je les ai pas vu ces programmes d'exemple...à moins que ce soit dans la v 5
-
19/05/2011 - 23h15 bobfuck
Re : ATmega
beuah c'est peut-être avec avr-gcc alors XDDD
je sais plus mais elles sont bien venues de quelque part ces libraries...
-
19/05/2011 - 23h28
Re : ATmega
 Envoyé par bobfuck beuah c'est peut-être avec avr-gcc alors XDDD
je sais plus mais elles sont bien venues de quelque part ces libraries... Effectivement, c'est avec la V5: http://atmel.com/dyn/products/tools_...family_id=2138 | | |