Micro-Info asbl - Layout pour ATMega16 -------------------------------------- $regfile = "m16def.dat" ' Chargement de la bibliothèque $crystal = 8000000 ' Définition de la fréquence du quartz $hwstack = 32 ' Valeur par défaut pour hardware stack $swstack = 10 ' Valeur par défaut pour SW stack $framesize = 40 ' Valeur par défaut pour frame space ' Initialisation du port A Ddra = &B11111111 ' Toutes les pins du port A en sortie Porta = &B00000000 ' Toutes les pins mises à zéro ' Initialisation du port D Ddrd = &B00000000 ' Toutes les pins du port D en entrée Portd = &B11111011 ' Toutes avec PullUp sauf D2 qui est raccordée à S5 Dim Pas As Byte ' numéro du pas, varie de 0 à 29 Dim Intensite As Byte ' "niveau" pour chaque led, peut varier de 0 à 36 ' puis valeur de l'intensité d'éclairement Dim N As Byte ' indice du numéro de led, varie de 0 à 7 Dim Led(8) As Byte ' intensité de chaque led, varie de 0 à 255 Dim Duree As Byte ' définit la durée d'éclairement des leds Dim I As Byte ' variable de comptage pour la durée Dim J As Byte Dim K As Byte Dim L As Byte Dim Nbre As Byte ' définit le nombre de niveaux d'intensité Dim A As Byte ' constante calculée, définit le nombre de pas Dim B As Byte ' constante calculée, définit un seuil de test Dim C As Byte ' constante calculée, définit un seuil de test Dim D As Byte ' constante calculée, définit le multiplicateur ' utilisé pour allumer la led avec PWM Dim Sens As Bit ' Définition du sens de "rotation" de la vague Dim Vitsens As Bit ' Etat de l'Interruption 0 (0= pas d'interrupt, 1 = Interrupt) Dim Longueur As Bit ' Variable définissant la longueur de l'appuis sur S5 Dim Interruption0 As Bit ' La valeur est 1 s'il y a eu interruption 0 Let Duree = 1 ' définit durée comme une constante. Ceci nous ' permettra de "jouer" avec la durée d'éclairement ' afin de déterminer le meilleur effet. ( Choisi valeur 5 ) Let Nbre = 16 ' définit le nombre de niveaux d'intensité. Ici ' aussi, nous pourrons "jouer" sur cette valeur ' pour varier les différents effets. Let A = Nbre * 2 ' définit a, b , c et d comme des constantes Let A = A - 3 ' les valeurs a, b, c et d étant dérivées de nbre. Let B = A + 1 Let C = Nbre - 1 Let D = 255 / Nbre Let Sens = 1 Let Interruption0 = 0 ' L'interruption 0 n'a pas eu lieu Let Longueur = 0 On Int0 Interruption ' sur Interruption va à la sous-routine Enable Int0 ' Activation de l'interrupt 0 (S5) Config Int0 = Low Level ' Définition du mode de déclenchement Enable Interrupts ' Activation des interrupts sur le µP. '- Principal ------------------------------------------------------------------------------ Do ' Début de la boucle "infinie" If Sens = 1 Then Gosub Horlogique Else Gosub Antihorlogique End If Loop ' Fin de la boucle infinie End ' Fin du programme ' - Sous-routines ' ------------------------------------------------------------------------------ Horlogique: If Interruption0 = 1 Then ' Placé le Gosub TESTINTERRUPTION ici afin de Gosub Testinterruption ' modifier les valeurs seulement après des End If ' des sens de défilement complets For Pas = 0 To B ' Boucle sur le nombre de pas défini par Nbre For L = 1 To Duree ' Boucle de durée de l'effet For N = 1 To 8 ' Boucle de calcul de l'intensité des leds Let Intensite = Pas + N ' Calcul de l'intensité de chaque led Let Intensite = Intensite - 1 ' (voir le raisonnement pour la structurée) If Intensite > A Then Let Intensite = Intensite - B Else If Intensite > C Then Let Intensite = B - Intensite End If End If Let Led(n) = D * Intensite Next ' Fin de la boucle de calcul de l'intensité Porta = 255 ' Début de la bouce "PWM" (Allumages des 8 leds For K = 0 To 255 ' Boucle sur les 255 valeurs For I = 1 To 8 ' Boucle de test sur chaque led Let J = I - 1 ' Mise à jour de l'index du port de sortie If Led(i) = K Then ' Si la valeur de led(x) est égale au compteur Reset Porta.j ' Extinction de la led correspondante End If ' Fin du test de la valeur de led(x) Next ' Fin de boucle sur les 8 leds Next ' Fin de la boucle "PWM") Next ' Fin de la boucle de durée de l'effet Next ' Fin de la boucle sur le nombre de pas Return Antihorlogique: If Interruption0 = 1 Then Gosub Testinterruption End If For Pas = B To 0 Step -1 ' Le reste de la boucle est identique For L = 1 To Duree For N = 1 To 8 Let Intensite = Pas + N Let Intensite = Intensite - 1 If Intensite > A Then Let Intensite = Intensite - B Else If Intensite > C Then Let Intensite = B - Intensite End If End If Let Led(n) = D * Intensite Next Porta = 255 For K = 0 To 255 For I = 1 To 8 Let J = I - 1 If Led(i) = K Then Reset Porta.j End If Next Next Next Next Return Testinterruption: If Pind.2 = 0 Then ' Si la touche S5 est appuyée Let Longueur = 1 ' nous avons un appuis long If Vitsens = 0 Then ' test le sens de défilement Incr Duree ' on incrémente la durée If Duree > 6 Then ' Valeur maximale dépassée Let Duree = 5 ' Valeur maximale choisie pour un bel effet Let Vitsens = 1 ' on change la variable pour décrémenter au End If ' prochain passage Else Decr Duree ' on décrémente la durée If Duree < 2 Then ' Test pour valeur minimale Let Duree = 1 ' Fixe la valeur minimale Let Vitsens = 0 ' on change la variable pour incrémenter au End If ' prochain passage End If Else If Longueur = 0 Then ' Dans ce cas, nous avons un appuis court Toggle Sens ' on inverse le sens de défilement Else Let Longueur = 0 ' Réinitialisation pour prochain INTERRUPT End If Let Interruption0 = 0 ' Réinitialisation de l'état d'interruption Enable Int0 ' Réactivation de l'interruption 0 End If Return Interruption: ' Routine de l'interruption INT0 (appuis sur S5) Disable Int0 ' Il faut d'abord arrêter les interruptions Let Interruption0 = 1 ' Puis indiquer qu'il y a eu une interruption par S5 Waitms 100 ' Attente de 100 millisecondes Return ' * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *