Développement logiciel pour le contrôle moteur DSP TMS320F28

Dans mon premier article, j'ai parlé de cette famille de contrôleurs; plus d'une douzaine de personnes m'ont écrit en PM avec des questions à ce sujet, bien que ce ne soit pas le sujet de l'article. Les gens ne voulaient catégoriquement pas aller sur Google, parlant du manque d'informations. J'ai été un peu surpris et j'ai décidé de vérifier - en effet, en russe, il n'y a pratiquement rien sur la famille C2000 (dans le contexte de l'AVR, STM), et surtout, il n'y a pas de guides de démarrage clairs. Les informations peuvent être trouvées en anglais, mais là encore ce n'est pas suffisant. Pour moi, c'est quelque peu surprenant, étant donné que cette famille n'a pas quelques années. Par conséquent, il a été décidé au mieux de leur capacité d'influencer la situation.

Qui a besoin de ces contrôleurs en principe ... Voulez-vous assembler un onduleur de soudage? Alimentation sans coupure? Lisseur de galvanoplastie? Fréquence? Un onduleur pour les énergies alternatives? Machine CNC? Si au moins un point vous concerne, l'article vous est dédié!

D'autres lecteurs seront également intéressés à en apprendre davantage sur le "nouveau-ancien" contrôleur, pourquoi il est nécessaire et comment travailler avec lui. Cette famille est très simple (beaucoup plus simple que STM, LPC et autres Cortex), les pierres sont faciles à acheter (il y a aussi Ali), elles vous permettent de mettre en œuvre des solutions industrielles très fiables, sur leur base vous pouvez construire presque n'importe quel système de contrôle industriel.

Avez-vous déjà décidé que ce contrôleur est votre rêve et êtes-vous prêt à vous lancer dans la bataille? Ensuite, nous achetons pour 17 $ le débogage suivant de F28027-LaunchPad:


As-tu acheté? Maintenant, vous pouvez vous battre. Si la question se pose de savoir où acheter "mieux" et "moins cher", alors nous allons au magasin officiel. Nous allons ici et voyons le prix de 17 $. Pour ce montant, vous recevrez des frais de débogage originaux et une livraison par messagerie à domicile. J'ai commandé une fois en Chine pour la livraison, il s'est avéré 16 $ et c'est avec une remise et un coupon, ainsi qu'un voyage "bonus" au bureau de poste. Par conséquent, je recommande que ce soit l'officiel. C'est parti!

Présentation de la série C2000


Vous pouvez lire le plus en détail sur tout sur le site officiel , bien sûr, en anglais. Je vais en parler brièvement et exprimer mes réflexions sur l'application. Veuillez noter que ce ne sont que mes spéculations et ils ne prétendent pas la vérité.

Tout d'abord, quelques mots sur le C2000 en général. Les caractéristiques distinctives de la famille, associées à son objectif principal de contrôle moteur, sont la présence de HRPWM (PWM haute précision) et CLA (coprocesseur). Ce dernier est vraiment absent dans le plus jeune Piccolo TMS320F2802x, mais il n'y est pas nécessaire, l'essentiel est le HRPWM en place. Qu'est-ce que c'est ... HRPWM lui-même est un PWM régulier, il n'est que très précis et le temps d'enregistrement et de réglage pour un nouveau cycle de service est beaucoup plus rapide. Cela permet par exemple d'obtenir un sinus parfaitement formé dans un onduleur DC / AC ou de piloter des moteurs pas à pas dans une machine CNC avec une très grande précision.

CLA est essentiellement un cœur à part entière, mais il n'a pas accès aux périphériques, uniquement au cœur principal et à la mémoire. Il sert à décharger le noyau principal de l'informatique. Ce coprocesseur digère très facilement et naturellement les données flottantes, ce qui est important lors de la mise en œuvre de divers algorithmes, filtres, etc.



Je vais parler de deux familles principales que vous rencontrerez probablement:

  • Piccolo. Les contrĂ´leurs les plus jeunes, mais aussi les moins chers. Mon TMS320F28027 est de cette famille. Si vous dĂ©cidez de dĂ©velopper l'Ă©lectronique de puissance Ă  des fins commerciales, ce seront vos pierres principales - elles sont assez bon marchĂ©, payantes (LQFP, QFN, TSSOP) et vous permettent de mettre en Ĺ“uvre presque tout. Par exemple, leurs performances sont suffisantes pour un PFC biphasĂ©, un onduleur pour panneaux solaires, un convertisseur de frĂ©quence jusqu'Ă  10 kW avec contrĂ´le vectoriel, etc. Comme vous pouvez le voir, il s'agit d'un segment de produits achetĂ©s par des particuliers et des entreprises, ce qui signifie qu'il est très demandĂ©. Les principales limitations sont la frĂ©quence de 60 MHz, un nombre limitĂ© de canaux PWM.
  • Delfino. IdĂ©ologiquement, ce sont tous les mĂŞmes Piccolo, uniquement gonflĂ©s au meldonium. Dans ce qu'elle exprime - une frĂ©quence allant jusqu'Ă  200 MHz, dans les pierres plus anciennes, il y a dĂ©jĂ  2 cĹ“urs Ă  part entière + 2 coprocesseurs, de gros boĂ®tiers et, par consĂ©quent, de nombreuses jambes, de nombreux canaux PWM, de nombreux ADC et, en gĂ©nĂ©ral, beaucoup. Autrement dit, dans les pierres plus anciennes, nous avons 4 cĹ“urs avec une frĂ©quence de 200 MHz, une performance de 800 MIPS, ce qui est assez impressionnant. Une telle puissance peut ĂŞtre utilisĂ©e de diffĂ©rentes manières, mais l'application principale est des systèmes algorithmiquement complexes, par exemple, le redresseur de Vienne ou autre chose. Également sur un tel contrĂ´leur, vous pouvez implĂ©menter l'ensemble du système de contrĂ´le d'une machine CNC, par exemple le fraisage ou le dĂ©coupage Ă  la flamme du mĂ©tal.

Finalisation du tableau de débogage


Lorsque vous recevez une boîte avec une carte de débogage, vous y trouverez le quartz et les condensateurs manquants. Ils ne sont pas nécessaires, mais il est conseillé de se doper. Je n'ai plus de quartz dans le HC-49, j'ai donc dû emprunter à un ami. Il choisit AVR et STM, il n'a donc trouvé que 8 MHz. Soudé. J'ai ajouté 22 condensateurs pF de l'ancienne mémoire, comme je l'ai fait sur méga à l'école.

Cette solution n'est pas la meilleure et elle est connectée à la configuration PLL. Le multiplicateur maximum pour PLL est x12 (plus peut être, mais n'est pas recommandé, et fonctionne de manière tordue). La fréquence maximale est de 60 MHz. La valeur maximale du diviseur à la sortie PLL est 3. La fréquence du quartz est de 8 MHz. Je ne peux pas multiplier par 8 par un entier et obtenir 60. Nous recherchons la valeur totale la plus proche, dans ce cas 240. Autrement dit, je multiplierai 8 par 30, puis en divisant par 4 j'obtiendra les 60 MHz convoités, mais le problème est que le multiplicateur PLL x30 est inacceptable , divider / 4 est également indisponible. Il y a 2 sorties:

  • Mauvais: multipliez la frĂ©quence de 8 MHz par 7 et divisez par 1 et obtenez 56 MHz. Vous pouvez multiplier par 8 et obtenir 64 MHz, cela fonctionnera de manière stable, mais dans les deux cas, la frĂ©quence n'est pas maximale de 60 MHz. Pas assez de perfectionnisme, hĂ©las. J'ai juste une telle option, soudĂ© 8 MHz et fait une frĂ©quence de 56 MHz.
  • Bon: allez acheter du quartz Ă  10 ou 20 MHz (mieux que 10) et multipliez par 6, eh bien, divisez par 1, nous obtenons le prĂ©cieux 60 MHz. Je vis en dehors de la ville et honnĂŞtement, c'Ă©tait trop paresseux pour aller dans un magasin local, ce qui n'est pas le fait qu'il y a du quartz Ă  10 MHz. Bien sĂ»r, le circuit RC interne et le quartz 8 MHz seront utilisĂ©s pour la formation, mais dans vos projets futurs, mettez le quartz 10 MHz, pas les mutants mammouths dans le boĂ®tier HC-49.

Architecture et fonctionnalités périphériques


Tout ce qui se passera ensuite s'applique au contrôleur TMS320F28027. Pour commencer, regardons simplement la structure tirée de la fiche technique :



La première chose à laquelle vous devez faire attention est que la RAM est divisée en 3 secteurs: M0, M1 et SARAM. Les volumes de ces secteurs de mémoire dans notre cas sont 1k, 1k et 4k. Il convient de noter que dans ce cas, le mot n'est pas de 8 bits, mais de 16 bits, c'est-à-dire, dans une forme plus familière, il est de 2 kB + 2 kB + 8 kB. La particularité de ce module est que les secteurs M0 et M1 sont plus rapides que les 8 Ko restants de RAM. Formellement, vous pouvez le prendre comme cache. Les secteurs M0 et M1 stockent généralement les données les plus fréquemment utilisées, ainsi que les données les plus critiques pour les performances de la mémoire. Par défaut, nous pouvons utiliser l'éditeur de liens pour spécifier quoi et où est stocké, mais je ne soulèverai pas cette rubrique dans cet article, ici un article séparé est nécessaire au moins.

La deuxième caractéristique importante est que tous les périphériques sont cadencés à partir du bus système, c'est-à-dire à partir de 60 MHz (dans mon cas, 56 MHz). Par exemple, je vais donner les microcontrôleurs STM32, où la fréquence de base est, par exemple, 180 MHz pour F4, mais les périphériques sont cadencés par une série de diviseurs. J'appelle cette approche «faux mégahertz» pour moi, bien que cela soit très exagéré. Par conséquent, 60 MHz pour TMS320F28 et 180 MHz pour stm32 ne sont pas si différents, et si vous vous souvenez de la présence de CLA, alors 60 + 60 MHz sont au moins comparables. Il est clair qu'une telle comparaison n'est pas correcte, mais elle montre clairement que non seulement les mégahertz en ont marre.

Un point également intéressant - faites attention à la structure générale: HRPWM, ADC, comparateurs avec DAC interne, module de traitement de codeur (eCAP) ... Un convertisseur de fréquence prêt à l'emploi avec contrôle vectoriel à l'état pur! C'est l'essence même de cette famille - le minimalisme. D'une part, la périphérie est assez pauvre par rapport à Cortex, mais d'autre part, il suffit de mettre en œuvre une réponse en fréquence, dc / dc, dc / ac, et un pilote de moteur pas à pas. Pour cette raison, travailler avec les contrôleurs TMS320F28 est très simple, compréhensible et n'est pas surchargé d'actions inutiles. Mais si vous avez soudainement besoin de 3 UART, et pour eux une paire d'i2c et de 3 SPI supplémentaires, ces contrôleurs ne sont certainement pas pour vous - ils ont des tâches différentes.

Environnement de développement



Avez-vous regardé le logo Splash? Souviens-toi d'elle. Si vous décidez de commencer à utiliser des articles dans le développement des héros de l'article, alors ce logiciel vous appartient, et comme vous le voyez, le logiciel s'appelle controlSUITE .

Cette application est une collection et une bibliothèque de tout ce dont vous avez besoin pour développer un logiciel pour la famille de contrôleurs C2000. L'installation de cette application est la première chose à faire et à voir sa composition, elle contient:

  • Description de tous les contrĂ´leurs et cartes de dĂ©bogage existants basĂ©s sur eux. Sources de circuits, cartes de circuits imprimĂ©s, nomenclatures principalement dans Altium Designer
  • Exemples de circuits et de conception de cartes de circuits imprimĂ©s
  • Bibliothèques de base pour le dĂ©veloppement de firmware
  • Bibliothèques mathĂ©matiques et DSP, y compris pour une utilisation avec CLA
  • Un exemple de projets logiciels pour chaque type de pĂ©riphĂ©rique
  • Un grand nombre d'apnouts pour la mise en Ĺ“uvre de la plupart des algorithmes de contrĂ´le des moteurs, convertisseurs cc / cc, contrĂ´leurs MPPT et autres systèmes
  • Un ensemble de programmes qui vous permettent de crĂ©er un système de gestion de moteur sans programmation du tout, simplement en utilisant un environnement graphique
  • L'IDE lui-mĂŞme, qui sera dĂ©veloppĂ©

Tout ce que j'ai décrit ci-dessus est très bref et modeste. Il vous faudra quelques semaines pour voir et faire défiler au moins en diagonale. Bien sûr, vous n'aurez pas besoin de la plupart de cette quantité de données au début, mais vous devez vous rappeler où aller si quelque chose vous est incompréhensible et bizarre.

Maintenant, nous allons travailler avec l'IDE aujourd'hui, dont la partie graphique est basée sur la célèbre Eclipse. Le compilateur n'est pas GCC, mais le sien du Texas, ce qui, à mon avis, est certainement meilleur que le premier. Bien que l'on soupçonne que cela est complètement dopé, tout de même gcc. L'environnement de développement s'appelle Code Composer Studio , la version actuelle 7.4.

Création de projet


Au début, je voulais implémenter une tâche identique au premier article, c'est-à-dire dessiner un sinus. En principe, dans le cadre d'un article, cela aurait pu être fait en laissant derrière un cadre un très grand volume de petites choses, mais comme vous le savez, l'essentiel est précisément dans les petites choses. Il existe plusieurs articles sur le TMS sur Internet, mais ils sont tous très superficiels et se résument au type de «copier ceci et tout fonctionne», c'est-à-dire que le processus lui-même et l'idéologie ne sont pas du tout pris en compte. Par conséquent, dans le cadre de cet article, nous allons créer un projet, le nettoyer des composants inutiles, configurer le firmware dans la mémoire flash du contrôleur et apprendre à travailler avec GPIO, et ils sont très intéressants ici.

Téléchargez CCS7 depuis le site Web du fabricant, installez et commencez à créer le projet de la manière habituelle: Fichier → Nouveau → Projet CCS ...


Nous voyons cette fenêtre et nous devons y sélectionner le contrôleur qui nous intéresse, dans mon cas c'est TMS320F28027, indiquer le nom du projet et prescrire le chemin où il sera stocké. Vous devez d'abord créer un dossier dans lequel le projet sera stocké. Le nom du projet et le nom du dossier peuvent ne pas correspondre. Cliquez sur le bouton Terminer et notre projet est créé.

Vous devez maintenant remplir notre projet avec du contenu et le connecter. Avant cela, pour améliorer la structure du projet, créez cet ensemble de dossiers:


  • inc - un dossier qui contient tous les fichiers d'en-tĂŞte
  • system_inc - cette section stockera les fichiers d'en-tĂŞte des bibliothèques standard, les fichiers que nous crĂ©erons nous-mĂŞmes, par exemple, main.c sont dans le dossier inc. Cela ne cassera pas quelque chose sans rĂ©flĂ©chir ni ne supprimera
  • src - dossier avec toutes les sources
  • system_src - dossier avec les fichiers source pour les bibliothèques standard

Veuillez noter que cette structure n'est pas une sorte de dogme, mais seulement mon idée de commander. Bien que je le recommande aux personnes ayant une expérience minimale, au fil du temps, vous le modifierez pour l'adapter à votre vision du monde, mais pour l'instant cela réduira le nombre de jambages.

Créez maintenant le fichier main.h dans le dossier inc et connectez-le à main.c. Grâce à elle, les bibliothèques de base seront connectées. Et avant de commencer à transférer des bibliothèques et d'autres fichiers, notons le chemin d'accès aux dossiers où nos futurs fichiers d'en-tête seront stockés dans les paramètres du projet. Pour ce faire, cliquez avec le bouton droit sur le projet (Test) dans l'arborescence du projet et cliquez sur Propriétés en bas ou appuyez simplement sur Alt + Entrée . Dans la fenêtre qui s'ouvre, allez à Build → C2000 Compiler → Include Options et ici nous avons besoin de deux chemins existants - enregistrez le chemin vers les dossiers inc et system_inc. Cliquez sur Ajouter , puis sur Espace de travail , puis sur le dossier inc souhaité, puis faites de même et accrochez-vous au deuxième dossier. Ainsi, nous avons prescrit des chemins relatifs; lors du transfert d'un projet, vous n'aurez rien à reconfigurer. En conséquence, nous obtenons une telle image et cliquez sur OK :



Nous avons maintenant un projet vide avec les chemins et autres paramètres prescrits, il ne reste plus qu'à le remplir de bibliothèques. La seule chose à faire est de vérifier si tout est connecté. En théorie, vous devriez obtenir un tel code et une image, compiler le projet. Pour ce faire, appuyez sur CTRL + B ou accédez à Projet → Tout construire en haut. Le projet doit compiler sans erreur et ressembler à ceci (l'image est cliquable):



Parlons maintenant un peu de l'éditeur de liens. Initialement, lors de la création d'un projet, l'IDE génère le fichier 28027_RAM_lnk.cmd , il place notre programme en RAM lors du débogage et du firmware. C'est pratique lorsque nous déboguons, car Les ressources de mémoire flash ne sont pas gaspillées et entrer le débogage dans la RAM est beaucoup plus rapide. Mais que se passe-t-il si nous voulons coudre en flash? Pour ce faire, il existe un autre fichier de lien qui placera notre programme en flash. Je vais montrer cette option.

Tout d'abord, supprimez le fichier 28027_RAM_lnk.cmd . Comme je l'ai dit - controlSUITE est notre tout. Nous l'ouvrons. Allez maintenant Anglais → Appareil → Piccolo F2802x → Bibliothèques prises en charge → Fichiers d'en-tête pour F28027x . Sur la droite, nous voyons des dossiers - ce sont les bibliothèques standard et tout ce qui est nécessaire, y compris les éditeurs de liens. Maintenant, nous allons dans le dossier f2802x_common → cmd et ici nous voyons un ensemble de linkers pour toutes les pierres de la ligne. Il n'est pas difficile de deviner les fichiers _RAM pour le téléchargement de code sur la RAM, et sans cette balise pour le téléchargement via flash. Nous prenons le fichier F28027.cmd et le copions dans notre projet à la place de l'ancien éditeur de liens distant.

Il est maintenant temps de migrer les bibliothèques elles-mêmes. Nous allons dans le dossier f2802x_common → source et voyons un tas de fichiers. Il existe deux types de bibliothèques: les registres standard (similaires à CMSIS) et une sorte de SPL. Dans ce cas, nous ne sommes intéressés que par la première vue, c'est-à-dire les fichiers avec le préfixe f2802x_ . Bien sûr, vous pouvez tous les faire glisser dans notre projet, mais pourquoi l'obstruer si nous n'utilisons pas tout? Si vous avez besoin de quelque chose, nous l'ajouterons à l'avenir. Pour l'instant, nous nous limitons aux ensembles de fichiers suivants:

  • f2802x_codestartbranch.asm
  • f2802x_defaultisr.c
  • f2802x_piectrl.c
  • f2802x_pievect.c
  • f2802x_sysctrl.c

Nous copions le fichier de données et le collons dans notre dossier system_src . Maintenant, nous allons dans le dossier source f2802x_headers → et prenons le fichier F2802x_GlobalVariableDefs.c à partir de là et le copions à nouveau dans notre dossier system_src . Ensuite, accédez au dossier f2802x_headers → cmd et copiez le fichier F2802x_Headers_nonBIOS.cmd à partir de là dans le même dossier. Ceci termine le remplissage du dossier system_src et passe aux en-têtes.

Nous allons dans le dossier f2802x_headers → inclure et copier tous les fichiers de là dans notre dossier system_inc . Maintenant, nous allons dans le dossier f2802x_common → source et copions les fichiers à partir de là:

  • f2802x_examples.h
  • f2802x_globalprototypes.h
  • f2802x_i2c_defines.h
  • f2802x_epwm_defines
  • f2802x_swprioritizedisrlevels.h
  • f2802x_defaultisr.h

Nous devrions obtenir cette image dans l'arborescence du projet:


Vous devez maintenant connecter les bibliothèques de base, le fichier main.h prend la forme suivante:

#pragma once #include "F2802x_Device.h" #include "F2802x_examples.h" 

Nous essayons de compiler. Si le projet a été compilé sans erreurs ni avertissements, alors tout est correctement connecté. Si cela ne s'est pas produit, alors revérifiez les 10 fois, et si cela ne fonctionne pas du tout, puis écrivez au PM - j'aiderai , comme l'a dit Owl: "Baz-woz-mEz-bottom, c'est-à-dire pour rien . "

Initialisation du contrôleur et du système d'horloge


Dans cette section, nous allons écrire une fonction qui initialise le temporisateur de surveillance et les vecteurs d'interruption, et met les drapeaux d'interruption à zéro. Nous avons également mis en place le système d'horloge, à la suite duquel le quartz externe plutôt que la chaîne RC interne deviendra la source d'horloge, configurera la PLL et activera la synchronisation pour tous les périphériques.

Pour la précision du code, je propose de mettre toutes les initialisations de base dans un fichier séparé, dont le frontend sera la fonction void InitStartSystem (void) . Pour ce faire, créez les fichiers systemInitStart.h et systemInitStart.c . J'écrirai immédiatement une fonction et ensuite nous analyserons simplement son contenu:

 void InitStartSystem (void) { DisableDog(); XtalOscSel(); InitPll(TMS320_PLLCR, TMS320_DIVSEL); InitPeripheralClocks(); InitPieCtrl(); InitPieVectTable(); } 

Toutes les fonctions appelées dans InitStartSystem () sont standard. Je vous conseille de voir en détail comment ils sont implémentés, pour cela vous pouvez maintenir CTRL et cliquer sur la fonction qui vous intéresse. As-tu regardé? Maintenant, passez brièvement en revue ...

  • DisableDog () - la fonction dĂ©sactive le "chien". Il s'agit d'une Ă©tape obligatoire lors de la configuration de la partie principale des pĂ©riphĂ©riques critiques, par exemple, un système d'horloge. Dans le code de bibliothèque, vous voyez souvent cela, il sera dupliquĂ© et dupliquĂ©
  • XtalOscSel () - cette fonction implĂ©mente le passage d'une source d'horloge interne Ă  un quartz externe. Un point important! Il y a une erreur dans la bibliothèque standard avec cette fonction - elle n'est pas dĂ©clarĂ©e. On passe au fichier f2802x_globalprototypes.h et parmi tous les autres, on ajoute la ligne extern void XtalOscSel (void)



    Le deuxième point important! Accédez à la fonction XtalOscSel et supprimez la fonction de retard.



    Le troisième point important! Nous allons dans le fichier f28027x_exmaples.h et commentons la fonction d'implémentation du retard.


  • InitPll (TMS320_PLLMUL, TMS320_DIVSEL) - la fonction configure la PLL. 2 valeurs lui sont transfĂ©rĂ©es: multiplicateur et diviseur. Leur valeur est spĂ©cifiĂ©e dans le fichier d'en-tĂŞte. Un point important! Nous ouvrons cette fonction dans la bibliothèque et vous devez commenter le retard tout en bas

  • InitPll (TMS320_PLLMUL, TMS320_DIVSEL) - la fonction configure la PLL. 2 valeurs lui sont transfĂ©rĂ©es: multiplicateur et diviseur. Leur valeur est spĂ©cifiĂ©e dans le fichier d'en-tĂŞte. Un point important! Nous ouvrons cette fonction dans la bibliothèque et vous devez commenter le retard tout en bas
  • InitPeripheralClocks () - cette fonction permet simplement de cadencer pour toute la pĂ©riphĂ©rie. Oui, pour tous. C2000 n'est pas une solution pour les presse-Ă©toupes alimentĂ©s par batterie,
    cette solution d'unités-dizaines-centaines de kilowatts et pathétique 2-3 mA ne jouera pas un rôle ici. Eh bien, vous n'avez pas à vous souvenir de chaque fois que vous allumez l'horloge pour une sorte de SPI ou non
  • InitPieCtrl () - la fonction dĂ©sactive toutes les interruptions et rĂ©initialise les indicateurs d'interruption
  • InitPieVectTable () - la fonction remplit la table avec des vecteurs d'interruption

En fait, ici tout est initialisation. Je pense que beaucoup ont remarqué les «points importants» associés à la fonction Delay . Pourquoi l'avons-nous coupé sur la vigne? Oui, tout est simple - c'est une béquille.

Les ingénieurs TI ont ajouté ces retards complètement inutiles à certaines fonctions, ajoutés dans les mises à jour récentes. Pourquoi - un mystère non seulement pour moi. Les registres et autres entrées critiques sont déjà protégés, donc cela ne rendra pas notre contrôleur stupide. Soit dit en passant, lors de l'initialisation dans l'électronique de puissance, il est impossible de "carrément" du tout, sinon ce sera des poules mouillées. Par conséquent, oubliez pour toujours les fonctions de retard et autres diaboliques, seulement les minuteries! Les retards ne sont autorisés qu'à certaines fins pédagogiques, par exemple, pour clignoter rapidement avec une LED.

Afin de vérifier que le code fonctionne, nous appelons la fonction d'initialisation dans main, compile, flash et hook sur l'oscilloscope GPIO18 . Cette broche est similaire au MCO du STM32, ce qui signifie qu'elle délivre la fréquence du système. Un oscilloscope devrait voir un signal avec une fréquence de 56 MHz. Si l'oscilloscope est bon, alors vous verrez le méandre, si les chinois (même bons), alors ce sera probablement quelque chose de plus proche du sinus. La définition de GPIO18 pour produire la fréquence du système est visible dans la fonction InitPeripheralClocks () . Vous devez d'abord «connecter» gpio à la sortie de fréquence, puis régler le diviseur sur 1:

  GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 3; // GPIO18 = XCLKOUT SysCtrlRegs.XCLK.bit.XCLKOUTDIV=2; // Set XCLKOUT = SYSCLKOUT/1 

Configuration GPIO


Pour travailler avec cette famille, nous n'avons besoin que d'un manuel de référence, que les développeurs TI ont divisé en plusieurs fichiers, chacun décrivant une certaine périphérie, ce qui est très pratique. Téléchargez la fiche technique ici et allez à la section Support de la documentation à la page 126. Ici, nous voyons un ensemble de liens vers la documentation avec sa brève description: errata, un guide pour démarrer la gestion du moteur et des guides sur chaque périphérie. Nous sommes intéressés par un document appelé TMS320F2802x / TMS320F2802xx Piccolo System Control and Interrupts Reference Guide , il contient la description du GPIO et d'autres paramètres de base du système qui nous intéressent. Nous regardons le schéma de principe GPIO:



Nous voyons une image assez familière des ports d'entrée / sortie de l'appareil. Ici et la possibilité d'activer la suspension interne, et l'utilisation d'un signal avec GPIO pour les interruptions et autres délices. La principale caractéristique de ce périphérique dans le C2000 est la possibilité de suppression des interférences matérielles, par exemple, le cliquetis des contacts mécaniques d'un bouton. Regardons un diagramme intéressant:



Il montre le principe de lecture de l'état des entrées. Dans la plupart des contrôleurs, l'état d'entrée est lu avec la fréquence d'horloge de cette périphérie, c'est-à-dire par défaut avec une fréquence de 56 MHz dans notre cas, et pour le même stm dans les familles plus anciennes, ces fréquences sont encore plus élevées. Je pense que tout le monde comprend qu'à une telle fréquence, le contrôleur a le temps de «voir» toute interférence et bruit. Parfois, une telle fréquence est nécessaire, et parfois pas, par exemple, si nous devons interroger un bouton. Pourquoi l'interviewerions-nous toutes les 18 ns? Par conséquent, nous avons réalisé la possibilité de réduire la fréquence d'horloge d'un port spécifique en utilisant le registre CTRL et les bits QUALPRDx , où X prend une valeur de 0 à 3: QUALPRD0 est responsable de GPIO0 ... 7, QUALPRD1 est responsable de GPIO8 ... 15 et ainsi de suite. En fait, il s'agit d'un diviseur de fréquence ordinaire avec un coefficient de 1 à 510.



Souvent, cela n'a aucun sens d'interroger un bouton, nous allons donc régler le diviseur à 510, c'est-à-dire au maximum. Nous regardons à nouveau le diagramme et voyons que le signal n'est considéré comme stable que lorsque son niveau est resté inchangé pendant 6 ticks. Le nombre de mesures nécessaires pour la fixation peut être 1, 3 ou 6. Plus le diviseur est grand et plus nous fixons de cycles, plus la protection contre les bavardages est stable. Lorsqu'il y a un bavardage de contacts, ce sera d'abord des transitions chaotiques de 0 à 1 et vice versa, lorsque le bavardage passera et que le signal s'arrêtera et ne changera pas pour 6 horloges, cela signifiera que le bouton est enfoncé. Tout ingénieux est simple.

Maintenant, regardons les registres principaux, nous ne toucherons pas aux interruptions - seulement les paramètres des ports eux-mêmes. Vous devez d'abord dire que les registres sont divisés en 2 types: les registres de configuration et les registres de données . Les premiers sont responsables de la configuration des propriétés, par exemple, cette entrée ou cette sortie. Le deuxième groupe est responsable de l'écriture et de la lecture de l'état du port.

Registres de configuration:

  • GPxCTRL - inscrivez-vous pour Ă©crire le diviseur d'horloge. Au lieu de «x», nous substituons la lettre «A» - si nous avons GPIO0 ... 31, «B» - si nous utilisons GPIO32 ... 63 et ainsi de suite
  • GPAQSELx - registre pour dĂ©finir le nombre de ticks pour fixer la valeur Ă  l'entrĂ©e
  • GPAMUX1 est un registre pour sĂ©lectionner les pĂ©riphĂ©riques connectĂ©s, par exemple, il indique que GPIO ou UART, ou peut-ĂŞtre PWM, vient au pied.
  • GPADIR - Registre de sĂ©lection de direction GPIO: entrĂ©e ou sortie. Par dĂ©faut, tous les ports sont configurĂ©s pour l'entrĂ©e.
  • GPAPUD est le registre responsable de la connexion du porte-jarretelles interne au VCC.
    Il convient de noter que pour certains ports, par défaut, le pull-up est désactivé et pour une partie, il est activé.
    C'est important Ă  retenir!

Registres de données:

  • GPADAT - registre d'Ă©tat de sortie. Si la sortie est configurĂ©e pour l'entrĂ©e, alors nous lisons l'Ă©tat de l'entrĂ©e. S'il est configurĂ© pour une sortie, alors nous pouvons Ă©crire la valeur que cette sortie devrait prendre, c'est-Ă -dire 0 ou 1
  • GPASET - registre dĂ©finissant la sortie sur "1". Pour mettre Ă  "1", vous devez Ă©crire "1", lors de l'Ă©criture de "0" la commande est ignorĂ©e
  • GPACLEAR - registre dĂ©finissant la sortie sur "0". Pour mettre Ă  "0", vous devez Ă©crire "1", lors de l'Ă©criture de "0" la commande est ignorĂ©e
  • GPATOGGLE est un registre qui inverse la valeur actuelle de l'Ă©tat de sortie. Pour inverser la valeur, Ă©crivez «1»; lors de l'Ă©criture de «0», la commande est ignorĂ©e

Voici un ensemble de registres si simple. Même à partir de la description ci-dessus, vous pouvez déjà comprendre ce qui doit être fait pour configurer le port, mais les ingénieurs ou rédacteurs techniques prudents de TI ont fait une autre instruction étape par étape:



Je dirai tout de suite que les étapes 6 et 7 ne sont pas nécessaires pour nous, car ni le chien ni l'interruption ne sont utilisés dans cet article. Je décrirai brièvement les étapes restantes pour les personnes qui ont étudié l'allemand à l'école:

  • Étape 1 - dĂ©terminer la fonctionnalitĂ© de sortie: que ce sera une entrĂ©e ou une sortie,
    gpio ou sortie vers d'autres périphériques et autres
  • Étape 2 - activer ou dĂ©sactiver le pull-up interne
  • Étape 3 - Configurer la protection contre les horloges et les rebonds pour un port spĂ©cifique
  • Étape 4 - sĂ©lectionnez la fonction souhaitĂ©e: gpio ou pĂ©riphĂ©riques
  • Étape 5 - dĂ©finir la direction de sortie: entrĂ©e ou sortie

C'est toute la configuration, comme vous le voyez, c'est élémentaire et logique. Je veux noter tout de suite qu'il n'est pas nécessaire dans cet ordre de faire des réglages, par exemple, vous pouvez définir la direction (entrée ou sortie) dès la première étape. Peu importe.

Super important!

Lorsque vous travaillez avec des registres de la famille C2000, il est nécessaire de prendre en compte le moment où ils sont protégés. Tout ce qui est décrit ci-dessous s'applique principalement aux registres du groupe de configuration. Si vous avez examiné attentivement les fonctions standard, vous y avez probablement vu d'étranges commandes: EALLOW; et EDIS; . Commande EALLOW - supprime la protection et donne accès au travail avec les registres système. Commande EDIS - active la protection arrière et permet d'accéder au travail avec les registres système. Autrement dit, tout travail avec des registres système devrait TOUJOURS ressembler à ceci:

 EALLOW; //    ,   ,  EDIS; 

Une telle opération n'est pas requise si nous travaillons avec des registres de données, par exemple, si nous définissons notre sortie sur «1» à l'aide du registre GPxSET , nous n'avons pas besoin de supprimer la protection de celui-ci et, par conséquent, de la réactiver . Partout, la documentation indique ce qui doit être protégé et ce qui ne l'est pas, par exemple, comme ceci:



Sur la base de tout ce qui précède, configurons GPIO0 ... 3 avec des LED pour la sortie. Je suggère de placer tous les paramètres GPIO dans la fonction InitLEDgpio et de l'écrire:

 void InitLEDgpio (void) { EALLOW; GpioCtrlRegs.GPADIR.bit.GPIO0 = 1; GpioCtrlRegs.GPADIR.bit.GPIO1 = 1; GpioCtrlRegs.GPADIR.bit.GPIO2 = 1; GpioCtrlRegs.GPADIR.bit.GPIO3 = 1; EDIS; } 

Par défaut, nos GPIO sont déjà configurés comme GPIO, comme toutes les valeurs de registre sont effacées, ce qui signifie que «0» est déjà écrit dans le registre GPAMUX1. Pour GPIO0 ... 11, le pull-up est désactivé par défaut, nous ne pouvons donc prendre et déterminer la direction du travail vers la sortie qu'en utilisant GPADIR. Si vous vous souvenez, les LED sont connectées au contrôleur par des cathodes, ce qui signifie que immédiatement après l'initialisation, elles brillent. Fixons ces conclusions directement dans la fonction d'initialisation à «1»:

 void InitLEDgpio (void) { EALLOW; GpioCtrlRegs.GPADIR.bit.GPIO0 = 1; GpioCtrlRegs.GPADIR.bit.GPIO1 = 1; GpioCtrlRegs.GPADIR.bit.GPIO2 = 1; GpioCtrlRegs.GPADIR.bit.GPIO3 = 1; EDIS; GpioDataRegs.GPASET.bit.GPIO0 = 1; GpioDataRegs.GPASET.bit.GPIO1 = 1; GpioDataRegs.GPASET.bit.GPIO2 = 1; GpioDataRegs.GPASET.bit.GPIO3 = 1; } 

Comme vous pouvez le voir, je n'utilise pas le registre GPADAT pour l'écriture, mais j'utilise SET, CLEAR, TOGGLE . Notez également que j'ai effectué cette entrée en dehors de la zone protégée, c'est-à-dire après la commande EDIS . Maintenant, dans la même fonction, configurez GPIO12 pour fonctionner avec le bouton et ajoutez notre fonction:

 void InitLEDgpio (void) { EALLOW; GpioCtrlRegs.GPADIR.bit.GPIO0 = 1; GpioCtrlRegs.GPADIR.bit.GPIO1 = 1; GpioCtrlRegs.GPADIR.bit.GPIO2 = 1; GpioCtrlRegs.GPADIR.bit.GPIO3 = 1; GpioCtrlRegs.GPAPUD.bit.GPIO12 = 1; GpioCtrlRegs.GPACTRL.bit.QUALPRD1 = 0xFF; GpioCtrlRegs.GPAQSEL1.bit.GPIO12 = 2; EDIS; GpioDataRegs.GPASET.bit.GPIO0 = 1; GpioDataRegs.GPASET.bit.GPIO1 = 1; GpioDataRegs.GPASET.bit.GPIO2 = 1; GpioDataRegs.GPASET.bit.GPIO3 = 1; } 

Tout d'abord, je désactive le serrage interne en écrivant «1» dans le registre GPAPUD , car il est activé par GPIO12 par défaut. Comme je l'ai écrit plus tôt, tous les ports après l'initialisation sont configurés pour l'entrée, comme les zéros sont écrits dans le registre GPADIR , nous ne le configurons pas ici.

Il reste à configurer la protection contre les rebonds, pour cela on divise les diviseurs 0xFF , ce qui correspond à la valeur / 510. Dans le registre GPAQSEL1, nous écrivons la valeur «10» ou 2, qui définit la valeur sur un échantillon de 6 mesures. C'est fait! Pour lire la valeur d'une entrée spécifique, il vous suffit de lire la valeur du registre GPADAT :

 if (GpioDataRegs.GPADAT.bit.GPIO12) { //      +3.3 (. 1)  ,     } 

C'est ainsi que nous interrogeons les conclusions nécessaires. Appelons maintenant la fonction de configuration gpio dans notre fonction principale et obtenons sa forme finale:

 void InitStartSystem (void) { DisableDog(); XtalOscSel(); InitPll(TMS320_PLLMUL, TMS320_DIVSEL); InitPeripheralClocks(); InitPieCtrl(); InitPieVectTable(); /*********************************/ InitLEDgpio(); } 

Maintenant, nous appelons la fonction InitStartSystem dans le corps principal du programme dans main et ceci termine la configuration. Nous obtenons le code suivant:

 #include "main.h" int main (void) { InitStartSystem(); while(1) { } } 

Il est temps d'écrire notre premier programme de test et de tester tout cela. L'algorithme est le suivant: la LED qui se trouve sur GPIO3 clignote, et lorsque vous appuyez sur le bouton sur GPIO12, nous allumons simplement la LED GPIO0. Ainsi, nous vérifierons le fonctionnement des ports pour l'entrée et la sortie. Nous écrivons le code suivant:

 #include "main.h" int main (void) { InitStartSystem(); while(1) { if (GpioDataRegs.GPADAT.bit.GPIO12) { GpioDataRegs.GPACLEAR.bit.GPIO0 = 1; } else { GpioDataRegs.GPASET.bit.GPIO0 = 1; } GpioDataRegs.GPATOGGLE.bit.GPIO3 = 1; delay(100000); } } 

Nous compilons, allons dans le débogueur, démarrez-le et voyons comment une LED clignote constamment, et lorsque vous appuyez sur le bouton, une autre s'allume. À la fin de la section, je joindrai un projet avec ce code, si quelque chose ne fonctionne pas, examinez-le. Surtout pour ceux qui sont durs sur les textes ou qui n'ont pas compris tous les points, je suggère de regarder cette vidéo sur le travail avec GPIO, tout se passe là-bas, comme dans la section "GPIO". Je vous préviens que la vidéo pendant une heure, morne, longue, mais aussi détaillée que possible et tout est visible:



Fichiers de l'article


  • Archive avec le projet pour CCS7 Ă  tĂ©lĂ©charger ici
  • Vous pouvez voir le code sur github

Résumé


À ce stade, je termine l'article d'aujourd'hui. Je pense que vous avez compris que si je décidais immédiatement de montrer la mise en œuvre de l'onduleur DC / AC, l'article aurait été plusieurs fois plus grand ou de nombreux détails importants seraient simplement restés dans les coulisses, ce qui, à mon avis, est inacceptable.

J'espère que mon article aidera tout le monde à commencer le développement de cette famille de contrôleurs et à commencer le développement dans le domaine de l'électronique de puissance et des machines-outils. À l'avenir, j'écrirai probablement autre chose sur ce sujet, par exemple, je voudrais envisager de travailler avec PWM ou de mettre en œuvre une sorte d'algorithme. L'essentiel est d'avoir du temps.

Si vous avez des questions ou si quelque chose ne fonctionne pas pour vous, vous pouvez m'écrire dans des messages privés et j'essaierai de répondre à vos questions et de fournir toute l'aide possible dans l'étude. Je vous souhaite du succès dans la formation!

UPD Merci pour le conseil de BelerafonL sur le livre "Embedded High-Performance Digital Control Systems"

Source: https://habr.com/ru/post/fr410161/


All Articles