2017-08-03 1 views
0

Je rencontre des problèmes avec les interruptions de comparaison de sortie du temporisateur sur le HCS12. Le problème semble être que j'écris calculé valeurs aux registres de comparaison de sortie plutôt qu'immédiates, à savoir ...HCS12 embarqué: compteur temporel et valeurs de comparaison calculées de sortie

OCval = x + y; ldd OC1, OCval; // ce que je dois faire

ldd OC1, # 3000; // ce qui fonctionne

Avec les valeurs calculées, l'interruption de la minuterie est erratique, ce qui est inacceptable dans mon application. Le problème a été fermement fixé à l'exigence documentée d'accéder aux registres de minuterie et d'OC en un seul cycle, tout ce qui n'est pas une écriture immédiate viole cela. Je note également que tout l'exemple de code sur le web utilise des opérations immédiates.

Je me demandais simplement s'il existait une solution de contournement logicielle. Je dois permettre au compteur de fonctionner librement (c'est-à-dire sans réinitialisation) car il y a d'autres résultats de sortie avec des écritures immédiates qui doivent rester en action. Seules deux de mes interruptions doivent être calculées.

Un correctif logiciel serait bien parce que les seules autres options que je peux voir impliquent du matériel supplémentaire pour gérer le timing dynamique, désordonné. TIA

+0

Il est difficile de répondre sans aucun code fourni. Je suppose que le code est écrit en C? Si c'est le cas, vous devriez voir le désassemblage pour voir quel code a été généré. Quel compilateur utilisez-vous? Généralement, lorsque vous rencontrez des opérations non désirées dans C, vous devez écrire le code C en plusieurs étapes telles que 'volatile uint16_t result = x + y; OCval = résultat; – Lundin

+0

Spécifiquement pour le HCS12, le code C se traduit souvent par un mauvais assembleur lors de l'effacement des indicateurs de temporisation. Vous devez démonter le code pour effacer les drapeaux de temporisation, peu importe le compilateur, pour voir que cela fonctionne comme prévu. Un bug commun est quand vous avez quelque chose comme 'FLAGREG | = MASK;' qui se traduit par "lire FLAGREG, stocker le résultat dans l'accumulateur, ajouter un masque, écrire le résultat". Et puis, comme les drapeaux sont effacés en leur écrivant un 1, vous détruisez également tous les autres drapeaux dans le même registre. Pour obtenir le bon code assembleur (BSET), 'FLAGREG = MASK;' donne généralement les instructions correctes. Selon le compilateur. – Lundin

+0

Merci d'avoir répondu. Vous avez raison en ce qui concerne la compensation du drapeau, dans ce cas, la liste ASM a montré que ce n'est pas un problème. Les tests ont depuis prouvé clairement que le problème est d'écrire la valeur à la reg de comparaison sur plus d'un cycle. Déplacer cette fonction vers le downcounter modulaire a stabilisé l'application. – BruceV

Répondre

0

C'est un peu hésitant, mais les premiers tests sont encourageants. J'ai déplacé les interruptions fautives de la minuterie principale au modulo downcounter, qui fournit également des interruptions cadencées. La documentation indique que la définition du registre de comptage est soumise aux mêmes règles d'écriture en un seul cycle, mais mes tests approfondis avec la minuterie principale indiquent qu'il est très improbable que des problèmes surviennent tant que le compteur n'a pas fonctionné pendant un certain temps. L'avantage de la nouvelle approche est qu'une valeur ne doit être écrite qu'une seule fois, lors de la définition initiale de la valeur temporelle, contrairement au temporisateur principal où une réécriture doit être effectuée plusieurs fois par seconde. Au cas où cela serait utile, j'arrête le compteur avant d'écrire, puis je le redémarre.