Juste pour le plaisir, et pour prouver que cela peut être fait, j'ai terminé une routine d'assemblage AVR pour calculer les résultats sin (x) en 24 bits (3 octets) avec un bit d'erreur. L'angle d'entrée est en degrés avec un chiffre décimal, de 000 à 900 (0 ~ 90,0) pour le premier quadrant uniquement. Il utilise moins de 210 instructions AVR et fonctionne en moyenne sur 212 microsecondes, variant de 211us (angle = 001) à 213us (angle = 899).
Il a fallu plusieurs jours pour tout faire, plus de 10 jours (heures gratuites) en pensant simplement au meilleur algorithme pour le calcul, compte tenu du microcontrôleur AVR, sans virgule flottante, éliminant toutes les divisions possibles. Ce qui a pris plus de temps, c'était de faire les bonnes valeurs de passage pour les entiers, pour avoir une bonne précision, il faut passer des valeurs de 1e-8 aux nombres entiers binaires 2 ^ 28 ou plus. Une fois que toutes les erreurs responsables de la précision et de l'arrondi ont été trouvées, ont augmenté leur résolution de calcul de 2 ^ 8 ou 2 ^ 16 supplémentaires, les meilleurs résultats ont été obtenus. J'ai d'abord simulé tous les calculs sur Excel en prenant soin d'avoir toutes les valeurs comme Int (x) ou Round (x, 0) pour représenter exactement le traitement de base AVR.
Par exemple, dans l'algorithme, l'angle doit être en radians, l'entrée est en degrés pour faciliter la tâche de l'utilisateur. Pour convertir des degrés en radians, la formule triviale est rad = degrés * PI / 180, cela semble agréable et facile, mais ce n'est pas le cas, PI est un nombre infini - si l'utilisation de quelques chiffres crée des erreurs en sortie, la division par 180 nécessite Manipulation de bits AVR car il n'a pas d'instruction de division, et plus que cela, le résultat nécessiterait une virgule flottante car implique des nombres bien inférieurs à l'entier 1. Par exemple, Radian de 1 ° (degré) est 0,017453293. Puisque PI et 180 sont des constantes, pourquoi ne pas inverser cette chose pour une simple multiplication? PI / 180 = 0,017453293, multipliez-le par 2 ^ 32 et il en résulte une constante 74961320 (0x0477D1A8), multipliez ce nombre par votre angle en degrés, disons 900 pour 90 ° et décalons-le de 4 bits vers la droite (÷ 16) pour obtenir 4216574250 (0xFB53D12A), c'est-à-dire les radians du 90 ° avec une expansion de 2 ^ 28, ajustés en 4 octets, sans une seule division (sauf le 4 décalage de bit à droite). D'une certaine manière, l'erreur incluse dans une telle astuce est inférieure à 2 ^ -27.
Donc, tous les autres calculs doivent se rappeler qu'il est 2 ^ 28 plus élevé et pris en charge. Vous devez diviser les résultats en déplacement par 16, 256 ou même 65536 juste pour éviter qu'il n'utilise des octets de faim croissants inutiles qui n'aideraient pas la résolution. Ce fut un travail minutieux, il suffit de trouver la quantité minimale de bits dans chaque résultat de calcul, en maintenant la précision des résultats autour de 24 bits. Chacun des plusieurs calculs a été effectué en essai / erreur avec un nombre de bits supérieur ou inférieur dans le flux Excel, en regardant la quantité globale de bits d'erreur au résultat dans un graphique montrant 0-90 ° avec une macro exécutant le code 900 fois, une fois par dixième de degré. Cette approche Excel "visuelle" était un outil que j'ai créé, qui m'a beaucoup aidé à trouver la meilleure solution pour chaque partie du code.
Par exemple, en arrondissant ce résultat de calcul particulier 13248737.51 à 13248738 ou tout simplement perdre les décimales "0,51", dans quelle mesure cela affectera-t-il la précision du résultat final pour tous les 900 angles d'entrée (00,1 ~ 90,0) tests?
J'ai pu garder l'animal contenu dans 32 bits (4 octets) à chaque calcul, et je me suis retrouvé avec la magie pour obtenir une précision dans les 23 bits du résultat. Lors de la vérification des 3 octets du résultat, l'erreur est de ± 1 LSB, en suspens.
L'utilisateur peut saisir un, deux ou trois octets du résultat pour ses propres exigences de précision. Bien sûr, si un seul octet est suffisant, je recommanderais d'utiliser une seule table sin de 256 octets et d'utiliser l'instruction AVR 'LPM' pour la saisir.
Une fois que la séquence Excel a été fluide et nette, la traduction finale d'Excel vers l'assemblage AVR a pris moins de 2 heures, comme d'habitude, vous devriez penser plus en premier, travailler moins plus tard.
À ce moment-là, j'ai pu en serrer encore plus et réduire l'utilisation des registres. Le code réel (non définitif) utilise environ 205 instructions (~ 410 octets), exécute un calcul sin (x) en moyenne de 212us, horloge à 16 MHz. À cette vitesse, il peut calculer 4700+ sin (x) par seconde. Ce n'est pas important, mais il peut exécuter une sinusoïde précise jusqu'à 4700 Hz avec 23 bits de précision et de résolution, sans aucune table de recherche.
L'algorithme de base est basé sur la série Taylor pour sin (x), mais a beaucoup changé pour s'adapter à mes intentions avec le microcontrôleur AVR et la précision à l'esprit.
Même que l'utilisation d'une table de 2700 octets (900 entrées * 3 octets) serait une vitesse intéressante, quelle est l'expérience amusante ou d'apprentissage à ce sujet? Bien sûr, l'approche CORDIC a également été envisagée, peut-être plus tard, le point ici est de presser Taylor dans le cœur de l'AVR et de prendre l'eau d'une roche sèche.
Je me demande si Arduino "sin (78.9 °)" peut exécuter Processing (C ++) avec 23 bits de précision en moins de 212us et le code nécessaire plus petit que 205 instructions. Peut-être si C ++ utilise CORDIC. Les croquis Arduino peuvent importer du code d'assemblage.
Cela n'a aucun sens de publier le code ici, plus tard, je modifierai ce message pour y inclure un lien Web, peut-être sur mon blog à cette URL . Le blog est principalement en portugais.
Cette entreprise sans passe-temps était intéressante, repoussant les limites du moteur AVR de près de 16MIPS à 16MHz, sans instruction de division, multiplication uniquement en 8x8 bits. Il permet de calculer sin (x), cos (x) [= sin (900-x)] et tan (x) [= sin (x) / sin (900-x)].
Surtout, cela a aidé à garder mon cerveau de 63 ans poli et huilé. Quand les adolescents disent que les «vieux» ne savent rien de la technologie, je réponds «détrompez-vous, qui pensez-vous a créé les bases de tout ce que vous aimez aujourd'hui?».
À votre santé