Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //******************************************************************************
- //******************************************************************************
- // Onglet principal voitue_rc_gal_1
- //******************************************************************************
- //******************************************************************************
- //Michel COLIN ................aucuns droits...peut être recopié.......
- //******************************************************************************
- // Programme de pilotage voiture RC
- //******************************************************************************
- // Lecture de 6 voies de télécommande RC et pilotage de 6 servos
- // la lecture des voies se trouve dans la variable valeurV1 à valeurV6
- // les valeurs des pulses de sortie sont à mettre dans le tableau valeurS[0 à 5]
- //******************************************************************************
- // ATTENTION, les valeurs lues et à écrire sont le double des valeurs
- // conventionnelles (3000 pour un point milieu à la place de 1500)
- //*******************************************************************************
- // Le programme utilise l'interruption changement d'état des I/O PCINT1
- // ainsi que le timer 1
- // Il utilise également l'IT de comparaison COMPA1
- // utilisable uniquement sur un récepteur de télécommande
- // et ne permet pas la mesure de pulses en //
- //*********************************************************************************
- #include "avr/io.h"
- #include <avr/interrupt.h>
- //*****************************************************************
- // déclaration des variables globales
- //*****************************************************************
- volatile int valeurV1=3000; // contient la valeur*2 de la durée impulsion entrée PC0
- volatile int valeurV2=3000; // contient la valeur*2 de la durée impulsion entrée PC1
- volatile int valeurV3=3000; // contient la valeur*2 de la durée impulsion entrée PC2
- volatile int valeurV4=3000; // contient la valeur*2 de la durée impulsion entrée PC3
- volatile int valeurV5=3000; // contient la valeur*2 de la durée impulsion entrée PC4
- volatile int valeurV6=3000; // contient la valeur*2 de la durée impulsion entrée PC5
- volatile int valeurS[6]; // tableau des durées d'impulsions à générer
- //**************************************************************************
- // déclaration de la fonction Interruption écrite en assembleur Atmega 328
- //**************************************************************************
- extern "C" {void PCINT1_vect();}
- extern "C" {void TIMER1_COMPA_vect();}
- byte nombre;
- byte sequence=0;
- int i;
- int j;
- int valeursortie;
- unsigned long oldmilli;
- byte etat_inter=0;
- byte sens_V4=0;
- void setup()
- {
- Serial.begin(9600);
- //*****************************************************************
- // Configuration des registres
- //*****************************************************************
- cli(); // masquage des IT
- //**************** Configuration du port C en entrées **************************
- DDRC=0x00; // Toutes pins du port C en entrée
- PORTC=0x00; // pas de pullup sur le port C
- //**************** Configuration du port D en sorties **************************
- DDRD=0xFF; // Toutes pins du port D en sorties
- //**************** Initialisation Timer 1 ******************************
- TCCR1B=0x02; // Horloge compteur à 2 Mhz
- TCCR1A=0x00; // Fonctionnement en mode standard
- //TIFR1=0x02; // démasquage IT de comparaison COMPTA1
- OCR1AL=0xF0; // prépositionnement du comparateur A1
- OCR1AH=0xFF; // à FFF0h (à la mise sous tension)
- TIMSK1=0x02; // validation interruption comparaison
- //**************** Initialisation interruptions changement état Voies 1 à 6 ******
- PCMSK1=0x3F; // valide les changements d'état entrées
- PCICR=0x02; // valide l'interruption PCINT1
- PCIFR=0x02; // valide l'interruption PCINT1
- sei(); // démasquage des IT
- }
- void loop()
- {
- if(Serial.available()>0){nombre=Serial.read();}
- if (nombre==49){sequence=1;}
- if (sequence==1)
- {for (i=1000;i<5000;i++){valeurS[0]=i;delay(1);}
- for (j=5000;j>1000;j--){valeurS[0]=j;delay(1);}
- sequence=0;}
- else {valeurS[0]=valeurV1;}
- if (valeurV4>3000){etat_inter=1;}
- else {etat_inter=0;}
- if (((millis()-oldmilli)>3)&&(etat_inter==1))
- {oldmilli=millis();
- if (valeurS[3]>=4000){sens_V4=1;}
- if (valeurS[3]<=2000){sens_V4=0;}
- if (sens_V4==0){valeurS[3]=valeurS[3]+5;}
- if (sens_V4==1){valeurS[3]=valeurS[3]-5;}
- }
- valeurS[1]=valeurV1;
- valeurS[2]=valeurV1;
- //valeurS[3]=valeurV3;
- valeurS[4]=valeurV2;
- valeurS[5]=valeurV2;
- }
- //******************************************************************************
- //******************************************************************************
- // Onglet lecture pulses RC lecturerx.S
- //******************************************************************************
- //******************************************************************************
- //Michel COLIN
- //*****************************************************************
- // Lecture des pulses récepteur Voies 1, 2, 3, 4, 5, 6
- // utilise le timer 1, code testé sur ATMEGA 328P
- //****************************************************************
- // voie 1 = PORTC0, A0 -> valeurV1
- // voie 2 = PORTC1, A1 -> valeurV2
- // voie 3 = PORTC2, A2 -> valeurV3
- // Voie 4 = PORTC3, A3 -> valeurV4
- // Voie 5 = PORTC4, A4 -> valeurV5
- // Voie 6 = PORTC5, A5 -> valeurV6
- //*****************************************************************
- #include "avr/io.h"
- // Déclaration des variables locales
- //************************************
- .DATA
- .lcomm compteurV1,2 ;déclaration des compteurs de durée voies 1 à 6 et réservation 2 octets
- .lcomm compteurV2,2
- .lcomm compteurV3,2
- .lcomm compteurV4,2
- .lcomm compteurV5,2
- .lcomm compteurV6,2
- .lcomm oldportc,1 ; déclaration valeur du PORTC à l'interruption it-1 et réservation 1 octet
- // programme interruption, mesure de la durée des pulses
- //*******************************************************
- .org 0x0010 // adresse vecteur PCINT1
- .section .text
- .global PCINT1_vect
- PCINT1_vect :
- cli // masquage des IT
- push R24
- lds R24,SREG
- push R24
- push R16
- lds R16,PINC // lecture portC
- push R17 // sauvegarde des registres utilisés ici
- push R18 // R16 à R24, SREG
- push R19
- push R20
- push R21
- push R22
- push R23
- lds R18,TCNT1L // chargement compteur TCNT1 dans R18 R19
- lds R19,TCNT1H
- andi R16,0x3F // test si un front montant parmi 6
- mov R24,R16
- lds R17,oldportc
- com R17
- andi R17,0x3F
- and R17,R16
- breq passe_montant // si pas de front montant,aller à test si front descendant
- call f_montant1 // recherche la(les)voie(s) avec front montant
- passe_montant: mov R16,R24
- lds R17, oldportc // test si un front descendant parmi 6
- com R16
- and R16,R17
- breq fin // recherche la(les)voie(s) avec front descendant
- call f_descendant1
- ori R24,0x0
- brne fin
- fin: sts oldportc, R24
- mov R24, R18
- pop R23
- pop R22
- pop R21
- pop R20
- pop R19
- pop R18
- pop R17
- pop R16
- pop R24 // Récupérationa dans la pile des registres
- sts SREG,R24 // R16 à R24, SREG
- pop R24
- sei
- reti
- // détection front montant on charge le compteur de la voie détectée avec la valeur de TCNT1
- //******************************************************************************************
- f_montant1: ror R16 // si front montant détecté sur voie 1 compteurV1 = TCNT1 lu à l'interruption
- brcc f_montant2
- sts compteurV1,R18
- sts compteurV1+1,R19
- f_montant2: ror R16 // si front montant détecté sur voie 2 compteurV2 = TCNT1 lu à l'interruption
- brcc f_montant3
- sts compteurV2,R18
- sts compteurV2+1,R19
- f_montant3: ror R16 // si front montant détecté sur voie 3 compteurV3 = TCNT1 lu à l'interruption
- brcc f_montant4
- sts compteurV3,R18
- sts compteurV3+1,R19
- f_montant4: ror R16 // si front montant détecté sur voie 4 compteurV4 = TCNT1 lu à l'interruption
- brcc f_montant5
- sts compteurV4,R18
- sts compteurV4+1,R19
- f_montant5: ror R16 // si front montant détecté sur voie 5 compteurV5 = TCNT1 lu à l'interruption
- brcc f_montant6
- sts compteurV5,R18
- sts compteurV5+1,R19
- f_montant6: ror R16 // si front montant détecté sur voie 6 compteurV6 = TCNT1 lu à l'interruption
- brcc fin_montant
- sts compteurV6,R18
- sts compteurV6+1,R19
- fin_montant: ret
- // détection front descendant on calcule la durée de l'impulsion de la voie correspondante
- //****************************************************************************************
- f_descendant1 : ror R16 // si front descendant détecté sur voie 1 valeurV1 = TCNT1 - compteurV1
- brcc f_descendant2
- movw R20,R18
- lds R22,compteurV1
- lds R23,compteurV1+1
- sub R20,R22
- sbc R21,R23
- sts valeurV1,R20
- sts valeurV1+1,R21
- f_descendant2: ror R16 // si front descendant détecté sur voie 1 valeurV2 = TCNT1 - compteurV2
- brcc f_descendant3
- movw R20,R18
- lds R22,compteurV2
- lds R23,compteurV2+1
- sub R20,R22
- sbc R21,R23
- sts valeurV2,R20
- sts valeurV2+1,R21
- f_descendant3: ror R16 // si front descendant détecté sur voie 1 valeurV3 = TCNT1 - compteurV3
- brcc f_descendant4
- movw R20,R18
- lds R22,compteurV3
- lds R23,compteurV3+1
- sub R20,R22
- sbc R21,R23
- sts valeurV3,R20
- sts valeurV3+1,R21
- f_descendant4: ror R16 // si front descendant détecté sur voie 1 valeurV4 = TCNT1 - compteurV4
- brcc f_descendant5
- movw R20,R18
- lds R22,compteurV4
- lds R23,compteurV4+1
- sub R20,R22
- sbc R21,R23
- sts valeurV4,R20
- sts valeurV4+1,R21
- f_descendant5: ror R16 // si front descendant détecté sur voie 1 valeurV5 = TCNT1 - compteurV5
- brcc f_descendant6
- movw R20,R18
- lds R22,compteurV5
- lds R23,compteurV5+1
- sub R20,R22
- sbc R21,R23
- sts valeurV5,R20
- sts valeurV5+1,R21
- f_descendant6: ror R16 // si front descendant détecté sur voie 1 valeurV5 = TCNT1 - compteurV5
- brcc fin_descendant
- movw R20,R18
- lds R22,compteurV6
- lds R23,compteurV6+1
- sub R20,R22
- sbc R21,R23
- sts valeurV6,R20
- sts valeurV6+1,R21
- fin_descendant: ret
- //******************************************************************************
- //******************************************************************************
- // Onglet eriture pulses RC ecrituerx.S
- //******************************************************************************
- //******************************************************************************
- //Michel COLIN
- //*****************************************************************
- // Génération des pulses Voies 1, 2, 3, 4, 5, 6
- // utilise le timer 1, code testé sur ATMEGA 328P
- //****************************************************************
- // voie 1 = PORTD2, D2 ->valeurS[0]
- // voie 2 = PORTD3, D3 ->valeurS[1]
- // voie 3 = PORTD4, D4 ->valeurS[2]
- // Voie 4 = PORTD5, D5 ->valeurS[3]
- // Voie 5 = PORTD6, D6 ->valeurS[4]
- // Voie 6 = PORTD7, D7 ->valeurS[5]
- //*****************************************************************
- #include "avr/io.h"
- // Déclaration des variables locales
- //************************************
- .DATA
- .lcomm voiesortie,1 // déclaration n° de voie de sortie et réservation 1 octet
- .lcomm pinsortie,1 // déclaration n° de pin en cours du PORTB et réservation 1 octet
- // programme interruption, génération des pulses
- //*******************************************************
- .org 0x002C // adresse vecteur TIMER1_COMPTA
- .section .text
- .global TIMER1_COMPA_vect
- TIMER1_COMPA_vect :
- cli // masquage des IT
- push R24
- lds R24,SREG
- push R24
- push R16
- clr R16
- sts PORTD,R16 // mise à 0 des bits de sortie portD
- push R17 // sauvegarde des registres utilisés ici
- push R18 // R16 à R19, R26, R27, R24, SREG
- push R19
- push R25
- push R26
- push R27
- lds R17, pinsortie // lecture n° pin de sortie active
- lds R16, voiesortie // lecture voie de sortie en cours
- cpi R16,0x0C // on vérifie si la voie de sortie en cours est la n°6
- brne prem
- ldi R16,0x0 // on repositionne la voie de sortie sur la n°1
- ldi R17,0x4 // on positionne la pin de sortie sur D2
- prem: ldi R26,lo8(valeurS) // chargement du pointeur des valeurs de pulses
- ldi R27,hi8(valeurS)
- add R26,R16 // On rajoute l'offset de la voie de sortie au pointeur
- brbc 0,deuze
- inc R27
- deuze: ld R18,X+ // chargement de la valeur de la voie en cours
- ld R19,X
- lds R24,TCNT1L // chargement de la valeur du compteur TCNT1
- lds R25,TCNT1H
- add R18,R24 // rajout de la valeur de la voie au compteur TCNT1
- adc R19,R25
- sts OCR1AH,R19 // chargement comparateur COMPA
- sts OCR1AL,R18
- sts PORTD,R17 // positionnnement à 1 du bit en sortie
- clc
- rol R17 // décalage pour voie suivante (prochain cycle)
- sts pinsortie,R17 // sauvegarde de la pin de sortie voie suivante
- inc R16 // préparation voie de sortie prochain cycle
- inc R16
- sts voiesortie,R16
- pop R27
- pop R26
- pop R25
- pop R19
- pop R18
- pop R17
- pop R16
- pop R24 // Récupération dans la pile des registres
- sts SREG,R24 // R16 à R24, SREG
- pop R24
- sei
- reti
Advertisement
Add Comment
Please, Sign In to add comment