Description des microcontrôleurs Stm32. Nous commençons à étudier le Cortex-M en utilisant le STM32 comme exemple. Ecrire des données à une adresse en mémoire

Cet article est le premier d'une série d'articles sur l'étude de la programmation de microcontrôleurs. En étudiant divers matériaux, j'ai remarqué que presque tous commencent par le fait qu'un débutant est invité à télécharger (ou à utiliser la bibliothèque fournie avec l'environnement de développement) bibliothèque pour travailler avec des périphériques et l'utiliser pour écrire son premier programme (généralement clignoter une LED).

Contrôle de l'horloge des unités périphériques

Premièrement, l'utilisation dans des produits commerciaux est interdite : le planaire ne doit pas être utilisé comme un « ordinateur de processus ». Les développeurs ne prennent pas en charge la version 64 bits du système d'exploitation. Parmi les autres systèmes d'exploitation, le flux de travail est facile à comprendre. Plus d'informations peuvent être trouvées ici.

Configuration des paramètres des broches de sortie du port GPIO

Ce problème peut être résolu en l'adaptant selon le schéma suivant. Supprimez le bloc affiché dans l'extrait sans remplacement - les fichiers de polices sont également inclus dans la compilation ; l'inclure deux fois entraîne des erreurs de l'éditeur de liens. Après avoir terminé tous les chemins, la compilation devrait réussir. Au ce moment l'exemple de programme clignote encore « juste » - envoyez-le à l'ordinateur de processus pour vous convaincre de la bonne fonction.

Cela m'a beaucoup surpris. Selon ces articles, il n'est même pas nécessaire de lire la documentation de l'automate à programmer. on m'a appris la sagesse "Programmation du fer" complètement différent.

Dans cet article, le chemin de la phrase "Oui, je veux essayer!" avant le clin d'œil joyeux de la LED, il sera bien plus long que celui des autres auteurs. Je vais essayer de révéler les aspects de la programmation des microcontrôleurs qui se cachent derrière l'utilisation de fonctions de bibliothèque et d'exemples prêts à l'emploi.
Si vous avez l'intention d'étudier sérieusement la programmation de microcontrôleurs, cet article est pour vous. Cela peut peut-être intéresser ceux qui ont suffisamment joué avec Arduino et qui souhaitent mettre la main sur toutes les capacités matérielles du fer.

Générateur de fonctions pour les nuls

Les mauvaises langues soutiennent que le passage du laboratoire semi-professionnel au laboratoire professionnel obtient un générateur de fonctions. C'est un appareil qui génère des courbes de tension en fonction, ce qui facilite le test des émetteurs et autres circuits. A l'ère des fonctions grises, les générateurs de fonctions étaient implémentés "discrètement" : des circuits analogiques complexes étaient animés pour osciller afin d'obtenir le comportement souhaité. Ce sont des générateurs de fonctions qui réalisent la fonction souhaitée en produisant rapidement des "paquets d'ondes".

Sélection du microcontrôleur

Beaucoup de gens pourraient dire qu'il vaut mieux commencer à apprendre les microcontrôleurs avec un AVR, PIC, 8051 ou autre chose. La question est multiple et controversée. Je connais suffisamment d'exemples où des personnes après avoir appris le Cortex-M ont programmé AVR, ARM7, etc. J'ai moi-même commencé avec le Cortex-M3. Si vous avez une tâche spécifique, il y a beaucoup d'informations sur Internet avec une comparaison différents types microcontrôleurs et tâches résolues avec leur aide. Sur Habré, cette question a également été soulevée, par exemple.

Nous supposerons que nous avons déterminé le type de microcontrôleur. Mais le marché propose une vaste gamme de modifications différentes provenant de différents fabricants. Ils diffèrent par de nombreux paramètres - de la taille de la mémoire flash au nombre d'entrées analogiques. Pour chaque tâche, le choix doit être fait individuellement. Il n'y a pas de recommandations générales ici et ne peut pas l'être. Je noterai seulement qu'il vaut la peine de commencer l'étude avec le MK des fabricants avec le plus grand assortiment possible. Ensuite, lors du choix d'un MC pour une tâche spécifique, il y a de bonnes chances que quelque chose de l'assortiment présenté vous convienne.

Ici, nous utilisons trois valeurs alignées sur douze bits, qui forment une sorte de "vague d'escalier". La compilation de ce programme échoue probablement en raison des déclarations de fonction manquantes. La figure 7 montre le signal résultant.

En raison de la nature particulière du système d'horloge, il faut adapter l'ordre des méthodes d'initialisation selon le schéma suivant. Pour des raisons d'espace, nous nous limitons à la cartographie écran bleu... Étant donné que votre code peut écrire dans une partie de la mémoire d'image actuellement manquante à l'écran, cela empêche le "déchirure" souvent observé sur les plus anciens. ordinateurs de poche.

j'ai opté pour STM32(même si je pense qu'il vaut mieux commencer à apprendre avec MK de Texas Instruments - la documentation est très bien écrite), car ils sont répandus parmi les développeurs d'électronique russes. Si vous avez des problèmes ou des questions, vous pouvez facilement trouver des solutions sur les forums. Un autre avantage est la riche sélection de cartes de démonstration du fabricant et d'organisations tierces.

Implémenter discrètement des interfaces utilisateur complexes via un framebuffer n'est pas une tâche facile. Malheureusement, ici aussi examen détaillé produit n'entre pas dans le cadre de cet article - nous ne mentionnons le produit que pour vous éviter un travail manuel inutile.

Sélection et installation du logiciel

Notre groupe électrogène offre un potentiel d'expansion à plusieurs endroits. Étant donné que travailler avec des ordinateurs de traitement est toujours une science interdisciplinaire, il existe un potentiel d'optimisation du côté du matériel. Si vous souhaitez utiliser votre générateur de fonctions en laboratoire, l'instrument doit au moins fournir un amplificateur instrumental.

Qu'avez-vous besoin d'apprendre ?

Malheureusement, un PC seul ne suffit pas pour commencer à programmer le MK. Nous devrons trouver une carte de démonstration et un programmeur quelque part. Bien que cela réduise la concurrence sur le marché du travail.

J'utilise moi-même une carte de démonstration STM3220G-EVAL et programmeur J-Link PRO... Mais pour commencer, ça suffira STM32F4DÉCOUVERTE, qui peut être acheté sans aucun problème pour une petite quantité.

Qu'avez-vous besoin d'apprendre ?

Pour contrer l'ondulation résiduelle, il est nécessaire d'utiliser un filtre de reconstruction qui « étrier » l'escalier existant avec une réponse lente. Enfin, vous pouvez également augmenter votre vitesse de travail. La description architecturale prendra plusieurs centaines de pages. Le marché regorge de systèmes d'exploitation temps réel, de périphériques sophistiqués grâce à leurs propres couches d'abstraction matérielle.

D'ici là, nous vous souhaitons un bon code ! Ils ont moins de fonctions et donc leurs fiches techniques sont plus faciles à comprendre pour les débutants. Pour la correction, une résistance de 1,8 kΩ peut être connectée en parallèle. Il a été signalé à plusieurs reprises que cette carte a été accidentellement livrée en utilisant "Write Protect" ou "Write Protect" dans "Option Bytes".

Tous les exemples seront uniquement pour la carte de débogage. STM32F4DÉCOUVERTE... A ce stade, peu nous importe que cette carte coûte un MC basé sur le noyau Cortex-M4. Dans un avenir proche, nous n'utiliserons pas ses fonctionnalités et ses avantages par rapport au Cortex-M3. Et ce qui se passera ensuite - nous verrons.

Si vous avez en stock une autre carte basée sur STM32F2xx / STM32F4xx, vous pouvez travailler avec. Dans la présentation du matériel, je vais essayer de décrire le plus en détail possible Pourquoi nous le faisons de cette façon et pas autrement. J'espère que personne n'aura de problèmes avec le transfert d'exemples vers un autre matériel.

Pourquoi un environnement de développement payant ?

Le quartz de table avec une fréquence de 32 kHz est très facile à casser. Ils peuvent gérer 5 mA individuellement, mais seulement un maximum de 25 mA. Les courants de surtension supérieurs à 5,5 V ne sont pas autorisés. Ici aussi, seuls 5 mA peuvent être utilisés, mais pour l'ensemble, un maximum de 25 mA est autorisé.

Les sorties sont chargées individuellement avec 20 mA, les niveaux logiques autorisés garantissent jusqu'à 8 mA. Cependant, toutes les sorties ne peuvent être chargées qu'avec une puissance maximale de 150 mA. En mode drain ouvert, les sorties de 5 tonnes peuvent être pilotées à 5 V à l'aide de résistances externes. Les sorties ne sont pas protégées contre court-circuit.

Environnement de développement

Comme déjà mentionné à plusieurs reprises, il existe un nombre suffisant d'environnements de développement pour les microcontrôleurs ARM, à la fois payants et moins. Et encore une fois, je voudrais omettre la controverse sur cette question. J'utilise IAR Embedded Workbench pour ARM 6.60. Tous les exemples seront dans cet environnement. Si vous aimez (ou utilisez dans votre organisation) autre chose (Keil, Eclipse, CCS, CooCoc, etc.), alors cela ne vous fera pas vraiment de mal non plus. Je porterai une attention particulière aux fonctionnalités associées spécifiquement à l'environnement de développement.

Pourquoi un environnement de développement payant ?

Les résistances pull-up et pull-up internes sont généralement de 40k ohms. Les impulsions de réinitialisation internes durent au moins 20 s. Guide du programmeur Affectation des broches et données électriques de la puce électronique. Cela peut être utile si vous consultez des programmes plus anciens.

Ecrire des données à une adresse en mémoire

Cependant, ils ne doivent pas être utilisés pour de nouvelles conceptions. Il s'agit essentiellement d'un ensemble de définitions pour tous les registres, vous pouvez donc vous y référer par leur nom plutôt que par des codes hexadécimaux. Vous devez procéder comme suit. Cependant, il coûte environ 9 Ko de mémoire flash. Liste complète les optimisations peuvent être trouvées ici.

Peut-être que quelqu'un ne sera pas entièrement satisfait du fait que je propose d'utiliser un environnement de développement payant, mais dans IAR, il est possible d'obtenir une licence temporaire sans limiter les fonctionnalités, ou une licence illimitée avec une taille de code limitée (32 Ko pour MK est beaucoup).
De plus, je noterai tout de suite que pour certains MCU il n'y a pas d'environnements de développement libres. Et malheureusement, ces MC sont irremplaçables dans certains domaines.

Interfaces de programmation et de débogage

Le bootloader détecte automatiquement le débit en bauds. Réglez la vitesse d'horloge correcte et appuyez sur le bouton Démarrer. Les instructions sont partielles 16 bits et partielles 32 bits. Les données sont chargées en 8, 16 ou 32 bits. Ils ne doivent pas nécessairement avoir la même taille qu'un mot de 32 bits. Mais on obtient de meilleures performances lorsque les données 16 bits sont alignées sur des adresses 16 bits et les données 32 bits sur des adresses 32 bits.

Chaque entrée de la table est une adresse de branche de 32 bits. Pour toutes les adresses de saut, le bit 0 doit être défini, mais toujours sauter à l'adresse qui le précède. Pour toutes les autres interruptions, vous pouvez définir la priorité. Les gestionnaires d'interruption ne peuvent être interrompus que par des interruptions de priorité plus élevée.


Je ne décrirai pas le processus d'installation.

Où commencer?

Création de projet
Tout d'abord, créons un projet vide. IAR vous permet de créer des projets en ASM, C et C++. Nous utiliserons C.

Un projet vide avec un fichier principal apparaîtra devant nous.


Vous devez maintenant configurer le projet pour commencer à travailler avec "notre" MK et le débogueur. MK installé sur la carte STM32F4DISCOVERY STM32F407VG... Il doit être sélectionné dans les propriétés du projet (Options générales-> Cible-> Appareil) :

Réglage de la valeur sur la broche MK

La boucle de délai ci-dessus ne fonctionne pas, mais 8x plus rapide, mais seulement 6x plus rapide. Le tampon de prélecture est libéré pour chaque saut dans la boucle. L'exemple suivant génère une horloge système de 48 MHz avec un cristal externe de 8 MHz. Si le processeur est désactivé pendant le débogage, ce temporisateur s'arrête également.

Les signaux de synchronisation pour les périphériques peuvent être ralentis ou désactivés à tout moment pour économiser de l'énergie. Compilez à nouveau le programme et transférez-le sur le microcontrôleur. Le débit en bauds n'a pas d'importance. Vous recevez le texte "Bonjour !" Chaque seconde.


Lorsqu'un processeur programmable cible est sélectionné, sa description est chargée, ce qui offre de nombreuses possibilités de débogage (cela sera discuté ci-dessous). De plus, un fichier de configuration est automatiquement joint avec une description de l'espace d'adressage disponible pour l'éditeur de liens. Si nécessaire, nous aborderons le sujet du fichier de configuration de l'éditeur de liens dans les articles suivants.

On trouve un langage commun

Bien que nous parlions d'un microcontrôleur différent, la procédure est très similaire. Les horodatages sont réinitialisés à chaque nouvelle configuration de connexion et prennent de 0 à 99 secondes.


La page d'assistance est disponible uniquement pour les utilisateurs enregistrés. Vous y trouverez les téléchargements de firmware actuels et le guide d'installation de l'interface.

Module 1 : Introduction au système embarqué

Cependant, il faudra un certain temps avant que tout soit mis en œuvre. L'étendue de la livraison correspond approximativement à la figure ci-dessus, fig. 5. L'acheteur accepte cela en cliquant sur le bouton Acheter maintenant. L'interface sera à nouveau vérifiée avant l'expédition.

Chapitre 1 : Introduction générale

Chapitre 3 : Les bases pour commencer. Variables et types Représentation numérique et chaînes Opérateurs ternaires Règles de priorité.

Après cela, vous devez configurer le débogueur. Le débogage du programme s'effectue directement dans le matériel. Cela se fait à l'aide du débogueur JTAG. Vous pouvez en savoir plus sur la façon dont cela se produit sur Wikipedia. La carte STM32F4DISCOVERY dispose d'un débogueur ST-LINK / V2 intégré. Pour travailler avec le débogueur, vous devez sélectionner son pilote dans le menu Débogueur-> Configuration-> Pilote... Il est également nécessaire d'indiquer que le débogage doit être effectué directement dans le matériel. Pour ce faire, vous devez définir le drapeau Débogueur-> Télécharger-> Utiliser le ou les chargeurs flash



Chapitre 5 : Organisez mieux votre code

Fonctions et procédures Chaînes de tableau Types structurés Pointeurs Courte critique bonnes règles de programmation en intégré. Définition de macros et de constantes pragmatiques.

Module 3 : Langage et matériel

Durée totale du cours : 8 heures. Le matériel sera fourni gratuitement par le Fablab Bergame. Ce matériel sera mis à la disposition des participants du laboratoire.

Détermination des adresses des registres spéciaux

Ce billet réservera une place dans la classe. Le matériel sera utilisé tout au long du cours et est disponible dans le laboratoire. L'adhésion coûte 30 € par personne pour les membres réguliers et 20 € par personne pour les étudiants. L'adhésion peut se faire en ligne le jour même de l'événement. Il est très probable que l'utilisation de différentes versions des Logiciel nécessitera de petits changements de configuration qui pourraient fonctionner.

Pour ceux qui ont vu le mot Simulator

En théorie, IAR vous permet de déboguer des programmes à l'aide d'un simulateur. Mais je ne l'ai jamais vu utilisé dans la pratique.

Le projet est maintenant prêt pour le travail (programmation, téléchargement et débogage).

"TK" pour le premier projet
Résumons le résultat intermédiaire : MC et carte de débogage sont sélectionnés, le projet est préparé. Il est temps de décider de la tâche.

Ne nous écartons pas des classiques. Le premier projet sera une LED clignotante. Heureusement, il y en a beaucoup sur le tableau, alors qu'est-ce que cela signifie du point de vue de la programmation ? La première étape consiste à étudier le schéma de principe de la carte de démonstration et à comprendre comment la LED démarre.
disponible sur le site du fabricant. V cette description il y a même une section séparée sur les LED sur la carte - 4.4 LED... Par exemple, nous utiliserons Utilisateur LD3... Trouvons-le sur le schéma :


La chaîne d'outils n'est pas suffisante pour compiler facilement. La LED orange de la carte clignotera à 1 Hz, puis les LED bleue et verte clignoteront comme expliqué sur la page de démonstration officielle.


Mais que nous le voulions ou non, le temps presse et je me demande pourquoi ces microcontrôleurs sont toujours aussi populaires et populaires.

Oui, il y a encore beaucoup de choses dans le tutoriel, tout comme les programmeurs homebrew. Microcontrôleurs modernes, très rapides et à faible consommation à un prix très populaire. Le kit de développement comprend déjà un programmeur et un débogueur. Prix ​​: La plupart des raisons pour lesquelles rester avec les "vieux" microcontrôleurs est qu'ils sont moins chers.

L'analyse la plus simple du circuit suggère que pour "allumer" la LED, il faut appliquer "1" sur la broche du MK (qui pour ce MK correspond à 3,3V). La mise hors tension s'effectue en alimentant cette broche "0". Dans le schéma, cette broche est notée PD13(c'est probablement le plus une information important de ce document).

En conséquence, nous pouvons écrire "TK" pour notre premier programme :
Le programme pour le MK devrait transférer l'état de la broche du MK PD13 de l'état "0" à l'état "1" et inversement avec une certaine périodicité, distinguable pour l'œil humain (une note importante, si l'œil cligne trop souvent, l'œil peut ne pas être capable de le distinguer).

Ceci, cependant, cesse de s'appliquer aux versions. Vous ne pouvez pas et n'êtes pas limité au choix. À 266 $, vous obtenez une quantité infinie de kits de développement. L'avantage est qu'il est facile pour vous d'écrire des codes. L'inconvénient est alors la taille plus importante du code résultant. De même, il s'agit d'une bibliothèque périphérique standard.

Vous configurerez le programme dans lequel vous souhaitez utiliser les périphériques que vous souhaitez utiliser et le programme créera un projet fini. L'administrateur de ce site ou l'auteur des articles n'est pas responsable de l'exactitude et de la fonctionnalité des documents répertoriés ici. L'administrateur de ce site décline toute responsabilité en cas de blessures corporelles, de dommages ou de destruction de biens résultant de l'électricité, d'erreurs de schémas ou même d'instructions théoriques.

Avant de commencer la programmation, ou un peu de théorie
Avant de procéder à la mise en œuvre de notre cahier des charges, il est nécessaire de comprendre comment le MC est géré.

Pour commencer, tout MCU comprend un noyau, une mémoire et des blocs périphériques. Je pense que tout est clair avec la mémoire jusqu'à présent. Je mentionnerai seulement que le STM32 a une mémoire flash dans laquelle le programme MK est stocké (dans le cas général, ce n'est pas une affirmation vraie, le programme peut être stocké dans une mémoire externe non volatile, mais pour l'instant nous l'omettreons ) et d'autres données, y compris les données de l'utilisateur. Il y a aussi SRAM - mémoire vive.

Les informations fournies et la participation sont divulguées indépendamment de tout tiers. Les demandes d'indemnisation fondées sur des modifications, des erreurs ou des omissions sont en grande partie exclues. Toutes les marques déposées ou autres marques utilisées ici sont la propriété de leurs propriétaires respectifs. Cela n'est pas nié en raison des droits de propriété. Étant donné que l'origine des matériaux soumis ne peut en aucun cas être retracée, ils ne peuvent pas être utilisés à des fins commerciales ! Ce site non commercial ne tire aucun profit de ces engagements ou conceptions.

Le noyau est une partie du microcontrôleur qui effectue l'exécution d'un flux d'instructions. Dans notre MK, le type de noyau est Cortex-M4. Le cœur du MCU peut être comparé à un processeur dans un PC. Il ne peut qu'exécuter des commandes et transférer des données vers d'autres unités (les processeurs avec accélérateurs graphiques intégrés ne sont pas pris en compte dans cette comparaison).
Dans le même temps, le fabricant de MC ne développe pas le noyau. Le noyau est acheté auprès d'ARM Limited. La principale différence entre les différents MC réside dans la périphérie.

Les blocs périphériques sont des blocs qui interagissent avec le "monde extérieur" ou exécutent des fonctions spécifiques inaccessibles au noyau MC. Les MCU modernes (y compris STM32) contiennent une vaste gamme de blocs périphériques. Les unités périphériques sont conçues pour résoudre diverses tâches, de la lecture de la valeur de tension de l'entrée analogique du MK à la transmission de données à des appareils externes via le bus SPI.
Contrairement au noyau MK, les unités périphériques n'exécutent pas d'instructions. Ils n'exécutent que les commandes du noyau. Dans ce cas, la participation du noyau lors de l'exécution de la commande n'est pas requise.

Exemple

Un exemple est le bloc UART, qui est conçu pour recevoir et transmettre des données du MC vers des appareils externes. Depuis le noyau, il vous suffit de configurer le bloc et de lui donner des données à transmettre. Le noyau peut alors continuer à exécuter des instructions. Sur les épaules de l'unité périphérique se trouve le contrôle de la sortie correspondante du MC pour la transmission de données conformément au protocole. L'unité périphérique elle-même transfère la sortie MK à l'état requis "0" ou "1" au bon moment, effectuant la transmission.

Interaction du noyau avec l'unité périphérique
L'interaction du noyau MK avec l'unité périphérique s'effectue à l'aide de registres spéciaux (il y a aussi une interaction via le mécanisme d'interruption et le DMA, mais plus à ce sujet dans les prochains articles). Du point de vue du noyau, c'est juste un morceau de mémoire avec une adresse spécifique, mais en réalité ce n'est pas le cas... Écrire des données dans un registre spécial équivaut à envoyer une commande ou des données à une unité périphérique. Lecture - recevoir des données d'un bloc ou lire son état. La description des blocs périphériques et de leurs registres spéciaux occupe la part du lion de la description du MC.

IMPORTANT: Après l'écriture des données dans un registre spécial et la lecture ultérieure, vous pouvez obtenir des données complètement différentes. Par exemple, transmettre des données au bloc UART pour envoi et lire les données reçues par le bloc de dispositif externe, s'effectue à l'aide du même registre.

Les registres spéciaux sont généralement divisés en champs de bits. Un (ou plusieurs) bits contrôlent un paramètre spécifique du bloc périphérique, généralement indépendamment. Par exemple, différents bits d'un registre contrôlent l'état de différentes sorties du MC.

Rappelez-vous C
Si vous êtes un gourou du langage C, vous pouvez ignorer cette section en toute sécurité. Il est principalement destiné à ceux qui ont appris (ou ont appris eux-mêmes) à programmer pour PC. L'expérience montre que les gens ne se souviennent souvent pas des commandes importantes. Ici, je rappellerai brièvement les opérations au niveau du bit et le travail direct avec la mémoire à son adresse.

Ecrire des données à une adresse en mémoire

Supposons qu'en lisant la description de l'unité périphérique, nous nous rendions compte que pour son bon fonctionnement, il est nécessaire d'y écrire le nombre 0x3B. Adresse de registre spécial 0x60004012. Le registre est de 32 bits.
Si vous ne savez pas immédiatement comment faire cela, je vais essayer de décrire une chaîne de raisonnement pour obtenir la bonne commande.

La valeur 0x60004012 n'est rien de plus que la valeur d'un pointeur vers un emplacement mémoire. C'est exactement ce que nous devons indiquer dans notre programme, c'est-à-dire effectuer une conversion de type selon la syntaxe du langage C :

(non signé long *) (0x60004012)

Ainsi, nous avons un pointeur sur l'élément. Vous devez maintenant écrire la valeur requise dans cet élément. Cela se fait en déréférençant le pointeur. Ainsi, nous obtenons la commande correcte :

* (non signé long *) (0x60004012) = 0x3B;

Définir des bits arbitraires sur 1

Supposons que vous deviez définir "1" sur 7 et 1 bits à l'adresse 0x60004012, sans modifier la valeur de tous les autres bits du registre. Pour ce faire, vous devez utiliser l'opération binaire |. Je vais vous donner la bonne réponse tout de suite :

* (non signé long *) (0x60004012) | = 0x82;

Faites attention à 2 faits. Les bits sont comptés à partir de zéro, pas à partir du premier. Cette opération prend en fait au moins 3 cycles d'horloge - lecture d'une valeur, modification, écriture. Parfois, cela n'est pas autorisé, car entre la lecture et l'écriture, la valeur d'un des bits que nous ne sommes pas autorisés à modifier peut avoir été modifiée par l'unité périphérique. N'oubliez pas cette fonctionnalité, sinon des bugs extrêmement difficiles à détecter peuvent survenir.

Mise à 0 de bits arbitraires

Supposons que vous deviez définir "0" sur 7 et 1 bits à l'adresse 0x60004012, sans modifier la valeur de tous les autres bits du registre. Pour ce faire, vous devez utiliser l'opération binaire &. Je vais vous donner la bonne réponse tout de suite :

* (non signé long *) (0x60004012) & = 0xFFFFFF7D;

Ou son écriture plus simple (ne vous inquiétez pas d'une opération supplémentaire, le compilateur calculera tout à l'avance même avec une optimisation minimale) :

* (non signé long *) (0x60004012) & = (~ 0x82);

Certaines fonctionnalités des programmes pour MK
Ici, je vais essayer de décrire certaines des caractéristiques des programmes pour MK, qu'il est important de retenir. Les choses sont assez évidentes, mais quand même.
Le programme n'a pas de fin
Contrairement à la plupart des logiciels PC, le logiciel MK ne devrait jamais se terminer, JAMAIS ! Et qu'est-ce que MK devra faire exactement après la fin de votre programme ? La question est pratiquement rhétorique. Alors n'oubliez pas de vous assurer que vous n'avez pas oublié le cycle perpétuel. Si vous le souhaitez, vous pouvez mettre le MK en mode veille.
Utiliser des variables entières
Malgré le fait que nous utilisons un MK avec un cœur Cortex-M4, qui effectue des opérations matérielles sur des nombres à virgule flottante, je vous conseille d'arrêter de les utiliser. Dans un MCU sans prise en charge de telles opérations, le temps de calcul sera tout simplement énorme.
Oubliez l'allocation dynamique de mémoire
C'est juste un conseil. La raison est simple - il y a peu de mémoire. J'ai rencontré des bibliothèques avec des fuites de mémoire lentes. C'était très désagréable quand, après plusieurs semaines de fonctionnement stable, le MK gelait avec une erreur. Il est préférable de réfléchir à l'avance à l'architecture de votre programme afin de ne pas avoir à utiliser l'allocation dynamique de mémoire.
Si vous souhaitez toujours utiliser, étudiez attentivement le travail du gestionnaire de mémoire ou écrivez le vôtre.

Mettons-nous au travail!

Le travail sur un programme pour MK commence toujours par la lecture de la documentation. Pour notre MK est disponible sur le site du fabricant. Il y a beaucoup de pages, mais lisez tout tandis que pas nécessaire. Comme déjà mentionné, la plupart de la documentation est une description des unités périphériques et de leurs registres. Je veux aussi attirer votre attention sur le fait que ce Manuel de Référence a été écrit non pas pour un MC, mais pour plusieurs lignes. Cela suggère que le code sera portable lors du passage à d'autres MCU dans ces lignes (à moins, bien sûr, d'essayer d'utiliser des unités périphériques qui ne sont pas dans le MCU utilisé).

Tout d'abord, vous devez décider avec quels blocs vous devez travailler. Pour cela, il suffit d'étudier les sections introduction et Caractéristiques principales.

Le contrôle direct de l'état des broches MC est effectué à l'aide du bloc GPIO. Comme indiqué dans la documentation du STM32 MK, il peut y avoir jusqu'à 11 blocs GPIO indépendants. Les différents blocs périphériques GPIO sont communément appelés ports. Les ports sont désignés par des lettres de A à K. Chaque port peut contenir jusqu'à 16 broches. Comme nous l'avons noté précédemment, la LED est connectée à la broche PD13. Cela signifie que cette broche est contrôlée par le port D de l'unité périphérique GPIO. Le numéro de broche est 13.

Nous n'aurons pas besoin d'autres unités périphériques cette fois.

Contrôle de l'horloge des unités périphériques
Pour réduire la consommation électrique du MC, presque toutes les unités périphériques sont éteintes après avoir allumé le MC. L'appareil est allumé/éteint en donnant/arrêtant le signal d'horloge à son entrée. Pour un fonctionnement correct, il est nécessaire de configurer le contrôleur de signal d'horloge du MCU de sorte que le signal d'horloge soit fourni à l'unité périphérique requise.
Important: L'unité périphérique ne peut pas démarrer tout de suite après avoir activé le signal de l'horloge. Il faut attendre plusieurs cycles d'horloge pour qu'il "démarre". Les personnes utilisant des bibliothèques pour périphériques ignorent souvent cette fonctionnalité.

Les registres sont chargés de permettre la synchronisation des blocs périphériques Registre de validation d'horloge périphérique RCC XXX.À la place de XXX peuvent être des pneus AHB1, AHB2, AHB3, APB1 et APB2. Après une étude attentive de la description des registres correspondants, nous pouvons conclure que la synchronisation de l'unité périphérique GPIOD est activée en mettant "1" au troisième bit du registre Registre de validation d'horloge périphérique RCC AHB1 (RCC_AHB1ENR):


Maintenant, vous devez savoir comment trouver l'adresse du registre lui-même RCC_AHB1ENR.

Commenter: La description du système d'horloge MK STM32 mérite un article séparé. Si les lecteurs le souhaitent, je couvrirai cette section plus en détail dans l'un des articles suivants.

Détermination des adresses des registres spéciaux
La détermination des adresses des registres spéciaux doit commencer par la lecture de la section Carte mémoire dans le Manuel de référence. Vous pouvez voir que chaque bloc a sa propre partie de l'espace d'adressage. Par exemple, pour le bloc RCC, il s'agit du segment 0x4002 3800 - 0x4002 3BFF :



Pour obtenir l'adresse du registre, il faut ajouter à la valeur initiale de l'espace d'adressage du bloc RCC Adr. décalage le registre souhaité. Décalage d'adresse indiqué dans la description du registre (voir capture d'écran ci-dessus).

En conséquence, nous avons déterminé l'adresse du registre RCC_AHB1ENR- 0x4002 3830.

Bloc GPIO
Pour une introduction générale au bloc GPIO, je recommande fortement de lire l'intégralité de la section Manuel de référence dans son intégralité. Alors que vous ne pouvez pas prêter beaucoup d'attention à Mode alternatif... Nous laisserons cela pour plus tard.

Maintenant, notre tâche est d'apprendre à gérer l'état des broches MC. Passons directement à la description des registres GPIO.

Heures d'ouverture
Tout d'abord, vous devez définir le mode de fonctionnement de la broche 13 du port D comme Mode de sortie à usage général, ce qui signifie que le bloc GPIO contrôlera l'état de la broche MK. Le mode de fonctionnement des broches MK est contrôlé à l'aide du registre Registre de mode de port GPIO (GPIOx_MODER) (x = A..I / J / K):


Comme vous pouvez le voir dans la description, pour compléter le réglage requis, vous devez écrire la valeur 01b dans les 26-27 bits du registre GPIOx_MODER... L'adresse du registre peut être déterminée en utilisant la même méthode que celle décrite ci-dessus.

Configuration des paramètres des broches de sortie du port GPIO
Le bloc GPIO vous permet d'appliquer paramètres additionnels pour les broches de sortie du port. Ces réglages sont effectués dans des registres :
  • Registre de type de sortie du port GPIO (GPIOx_OTYPER)- le type de sortie est réglé sur push-pull ou open-drain
  • Registre de vitesse de sortie du port GPIO (GPIOx_OSPEEDR)- la vitesse de la sortie est réglée
Nous ne modifierons pas ces paramètres car nous sommes d'accord avec les valeurs par défaut.
Réglage de la valeur sur la broche MK
Enfin, nous arrivons au point de gérer l'état de la sortie MK. Il existe deux méthodes pour définir la valeur de sortie sur une broche spécifique du MC.

Nous utilisons le registre de jeu de bits de port GPIO / registre de réinitialisation (GPIOx_BSRR)


L'écriture de "0" ou "1" sur les bits 0-16 entraîne un changement correspondant de l'état des broches du port. Afin de fixer une certaine valeur à la sortie d'une ou plusieurs broches du MC et de ne pas changer l'état du reste, il sera nécessaire d'utiliser l'opération de modification de bits individuels. Cette opération est effectuée en au moins 3 cycles d'horloge. S'il est nécessaire d'écrire 1 sur certains bits et 0 sur d'autres, alors au moins 4 cycles d'horloge seront nécessaires. Cette méthode il est préférable de l'utiliser pour inverser l'état d'une sortie si son état initial n'est pas connu.

Jeu de bits de port GPIO / registre de réinitialisation (GPIOx_BSRR)


Contrairement à la méthode précédente, écrire 0 sur l'un des bits de ce registre ne mènera à rien (et en effet, tous les bits sont en écriture seule !). L'écriture de 1 sur les bits 0-15 définira "1" sur la sortie MK correspondante. L'écriture de 1 sur les bits 16-31 mettra "0" sur la sortie MK correspondante. Cette méthode est préférable à la précédente, si vous devez définir une certaine valeur sur la broche "MK", ​​​​et ne pas la modifier.

On allume la LED !
Après avoir trouvé les adresses de tous les registres nécessaires, vous pouvez écrire un programme qui allume la LED :
void main () (// Activer la synchronisation du port D * (unsigned long *) (0x40023830) | = 0x8; // peu de retard pour GPIOD se préparer volatile non signé long i = 0; i ++; i ++; i ++ ; i = 0; // Définir PD13 comme sortie à usage général * (unsigned long *) (0x40020C00) = (* (unsigned long *) (0x40020C00) & (~ 0x0C000000)) | (0x04000000); // Allumer la LED ! * (non signé long *) (0x40020C14) | = 0x2000; while (1);)
Il est possible de compiler ( Projet-> Compiler) et remplissez ( Projet-> Télécharger-> Télécharger l'application active). Ou lancez le débogage ( Projet-> Dpwnload et débogage) et lancer l'exécution (F5).
La LED est allumée !
LED clignotante
Le clignotement de la LED n'est rien de plus qu'une alternance d'allumage et d'extinction avec un délai entre ces actions. Le moyen le plus simple est de mettre l'activation et la désactivation dans une boucle éternelle et d'insérer un délai entre les deux.
void main () (// Activer la synchronisation du port D * (unsigned long *) (0x40023830) | = 0x8; // peu de retard pour GPIOD se préparer volatile non signé long i = 0; i ++; i ++; i ++ ; i = 0; / / Définir PD13 comme sortie à usage général * (unsigned long *) (0x40020C00) = (* (unsigned long *) (0x40020C00) & (~ 0x0C000000)) | (0x04000000); tandis que (1) (/ / Allumer la LED * ( non signé long *) (0x40020C14) | = 0x2000; // Délai pour (i = 0; i<1000000 ;++i); //Turn LED OFF *(unsigned long*)(0x40020C14) &= ~0x2000; //Delay for(i=0; i<1000000 ;++i); } }
La valeur de 1 000 000 dans le délai a été sélectionnée expérimentalement afin que la période de clignotement de la LED soit discernable à l'œil, mais pas trop longue.
Optimiser l'algorithme
L'inconvénient de l'approche choisie en faisant clignoter la LED est que le noyau MK passe la plupart de son temps dans des cycles vides, bien qu'il puisse faire quelque chose d'utile (il n'y a pas d'autres tâches dans notre exemple, mais elles apparaîtront dans le futur).

Afin d'éviter cela, un compteur de cycles est généralement utilisé et l'état de commutation de la broche MC se produit lorsque le programme passe un certain nombre de cycles.
void main () (// Activer la synchronisation du port D * (unsigned long *) (0x40023830) | = 0x8; // peu de retard pour GPIOD se préparer volatile non signé long i = 0; i ++; i ++; i ++ ; i = 0; // Définir PD13 comme sortie à usage général * (unsigned long *) (0x40020C00) = (* (unsigned long *) (0x40020C00) & (~ 0x0C000000)) | (0x04000000); tandis que (1) (i ++; if (! (I % 2000000)) (// Allumer la LED * (non signé long *) (0x40020С14) | = 0x2020;) else if (! (I% 1000000)) (// Éteindre la LED * ( non signé long *) (0x40020С14) & = ~ 0x2000;)))
Mais même ici, ce ne sera pas sans problèmes, avec un changement du nombre de commandes exécutées au cours du cycle, la période de clignotement de la LED (ou la période d'exécution d'autres commandes dans le cycle) changera. Mais à ce stade, nous ne pouvons pas le combattre.

Un peu sur le débogage
IAR vous permet de déboguer une application directement dans le matériel. Tout ressemble à peu près au débogage d'une application PC. Il existe un mode d'exécution pas à pas, saisie d'une fonction, visualisation de la valeur des variables (En mode débogage Affichage-> Regarder-> Regarder1 / 4).


Mais à côté de cela, il est possible de visualiser les valeurs des registres principaux, des registres spéciaux des blocs périphériques (View-> Register), etc.
Je vous recommande fortement de vous familiariser avec les capacités du débogueur tout en apprenant la programmation MK.

Quelques mots pour conclure

Peut-être que beaucoup diront que l'écriture manuelle d'adresses dans le programme n'est pas correcte, car le fabricant fournit des fichiers avec les définitions de registres et de champs de bits, des bibliothèques pour travailler avec des périphériques et d'autres outils qui facilitent la vie du développeur. Je suis tout à fait d'accord avec cela, mais je pense toujours que les premières étapes de la programmation de MK doivent être effectuées en fouillant dans la documentation pour définir manuellement, de manière indépendante, les registres et les champs de bits nécessaires. À l'avenir, vous n'avez pas besoin de l'utiliser, mais vous devez en être capable.
Voici quelques raisons de cette affirmation :
  • Il y a parfois des erreurs dans les librairies du constructeur ! Une fois, j'ai failli manquer la date limite du projet à cause de cela. J'ai ressoudé la puce plusieurs fois, pensant que j'avais endommagé le cristal une centaine de fois pendant la soudure (c'est arrivé avant). Et le problème était que l'adresse du registre spécial était mal enregistrée dans la bibliothèque. Cela se produit généralement avec les lignes MK ou MK qui viennent d'entrer sur le marché.
  • Les bibliothèques périphériques de certains fabricants n'implémentent pas toutes les capacités des unités périphériques. Surtout ce péché Micro Luminaire, qui ont ensuite été rachetés par TI. J'ai dû écrire l'initialisation de la périphérie manuellement.
  • Beaucoup de gens s'habituent à commencer la programmation MK en étudiant des exemples. Je pense que vous devez d'abord décider ce qui vous permet d'implémenter MK. Cela ne peut être compris qu'en lisant la documentation. Si quelque chose ne figure pas dans les exemples, cela ne signifie pas que le matériel ne le prend pas en charge. Le dernier exemple est le support matériel STM32 PTP. Sur le net, bien sûr, vous pouvez trouver quelque chose, mais cela n'est pas inclus dans l'ensemble standard du fabricant.
Ajouter des balises

Microcontrôleurs pour chatons

Tous les Miaous, les chats :)

Une fois qu'un chat m'a quitté: (Eh bien, et quoi manger de la valériane, j'ai décidé de faire des affaires, pour ainsi dire, "pour le bien de la patrie". vous comprenez, puis dors, puis avec un chat qui se promène sur les toits), et puis juste le temps est apparu. Bon, commençons ..)

Comme d'habitude, tout commence par un choix. Eh bien, il semble que le choix soit un petit PIC, oui AVR. Ce dernier m'aimait plus. j'avais aussi besoin programmateur USB faute d'autres ports sur l'ordinateur, du prix desquels ma queue a failli tomber. Il y a aussi un Arduino - un tel animal. Il peut être programmé via USB. Eh bien, je pense, "ce que le docteur a ordonné." Dans notre village, vous ne pouvez l'obtenir que via la boutique en ligne. J'ai trouvé là où c'était le plus rentable, j'ai failli l'acheter et... OPA ! Regarder - STM32VL-Découverte. Quel genre de bête est-ce ? Hmm, STM32 .. J'ai entendu quelque chose du coin de l'oreille .. Et des caractéristiques de la moustache à bout, honnêtement!

Et combien de pattes elle a !

Donc, dans l'ordre :

  • L'Arduino possède 14 ports E/S numériques et 6 entrées analogiques. Le STM32VL-Discovery dispose de 45 entrées/sorties numériques, dont 10 peuvent être converties en entrées analogiques à volonté.
  • L'Arduino dispose de 32 Ko pour le stockage du programme et de 2 Ko de RAM. Le STM32VL-Discovery dispose de 64 Ko pour le stockage du programme et de 8 Ko de RAM.
  • Arduino fréquence d'horloge 16 MHz pour STM32VL-Discovery correspond à 24 MHz.
  • Tout microcontrôleur STM32 peut être remplacé par un autre STM32, mais avec les meilleures caractéristiques, sans changer le schéma
  • STM32 peut être programmé sans programmeur via le port COM (nous en parlerons plus tard)
  • Le prix d'Arduino au moment d'écrire ces lignes est de ~ 1300 roubles, STM32VL-Discovery ~ 600 roubles. Et bien c'est plus de 2 fois moins cher !

Et après? Le STM32VL-Discovery a un programmeur/débogueur intégré qui peut programmer et déboguer (le débogage est une chose très utile, mais plus à ce sujet plus tard) des microcontrôleurs STM32 à l'extérieur de la carte avec un léger mouvement de la patte (en enlevant les cavaliers). Cela ne fonctionnera pas avec Arduino. Autrement dit, en utilisant STM32VL-Discovery, nous économisons de l'argent et obtenons plus de productivité et de liberté de créativité :)

Et les microcontrôleurs STM32 eux-mêmes semblent plus attrayants que les autres :

STM32F100C4T6B ATtiny24A-SSU PIC16F688-I / SL STM32F103RET6 ATmega1284P-PU PIC18F4550-I / TP
Prix ​​moyen, frotter 60 65 60 240 330 220
Fréquence d'horloge, MHz 24 20 20 72 20 48
Mémoire flash, Ko 16 2 4 512 128 16
RAM, octet 4096 128 256 65536 16384 2048
USART, pièces 2 0 0 5 2 0
SPI, pièces 1 1 0 3 1 1
CAN, pièces 16x12Bit 8x10Bit 8x10Bit 16x12Bit 8x10Bit 13x10Bit
CAD, pièces 1x12Bit 0 0 2x12Bit 0 0
Nombre de lignes d'entrée/sortie, pcs 37 12 12 51 32 35

Et STM32 est également 32 bits, ce qui signifie la possibilité de travailler avec des données 32 bits en un cycle. AVR et PIC ne s'en vantent pas.

Eh bien, les chats, convaincus ? Alors commençons le parcours d'un jeune soldat numérique !)

Comment ça marche? En quoi cela consiste? Qu'est-ce que ça peut faire?

Comme vous le savez, tous les chats sont très curieux, et surtout les chats radio !

Un microcontrôleur est un microcircuit qui combine les fonctions d'un processeur, de périphériques, de RAM et de mémoire flash. Comme un ordinateur, mais en plus petit !

Faisons une analogie : l'ordinateur contrôle système opérateur, et un microcontrôleur "firmware" que vous écrivez ; le système d'exploitation de l'ordinateur est stocké sur le disque dur, le « firmware » du microcontrôleur est dans sa mémoire flash ; les fonctions de la RAM sont similaires - stockage des données changeantes pendant l'exécution du programme. Et aussi le MK dispose de divers périphériques tels que l'ADC et le DAC par exemple.

MK communique avec le monde extérieur en utilisant des pattes sur son corps (pas comme celles des chats, bien sûr, mais celles en métal). Mais tous ne sont pas contrôlés par le programme, il y a des broches d'alimentation, une broche de réinitialisation, des broches d'alimentation périphériques et une broche d'alimentation de secours. Et ceux qui sont contrôlés par le programme sont divisés en groupes appelés "ports". Toutes ces broches contrôlables sont appelées 2 lettres et un nombre. Par exemple PA1 : P - port, A - port "A", 1 - numéro de broche de ce port.

Dans le programme, les ports sont configurés soit pour l'entrée, soit pour la sortie, comme vous le souhaitez.

Les broches du port configuré pour l'entrée peuvent être dans différents modes, pour chaque broche, elle peut être la sienne :

  • Entrée numérique - une entrée dont la valeur (logique 1 ou 0) peut être lue par le programme. Si la tension à l'entrée est 0, alors la valeur est 0, si la tension à l'entrée est égale à la tension d'alimentation, alors la valeur de l'entrée 1. La troisième n'est pas donnée. Peut être fait avec une résistance de rappel à l'alimentation ou à la terre
  • Entrée analogique - une entrée dont la valeur peut être lue par le programme, mais il peut y avoir de nombreuses valeurs - jusqu'à 4096. Ou, plus précisément, à partir de 0 si la tension à l'entrée est de 0 par rapport au moins du microcontrôleur alimentation à 4095, si la tension d'entrée est égale à la tension d'alimentation. Toutes ces transformations sont effectuées par un CAN - un convertisseur analogique-numérique, avec son aide, vous pouvez, par exemple, mesurer la tension aux bornes de la thermistance et connaître la température ou mesurer la tension sur la photorésistance et connaître la luminosité de la lumière qui tombe dessus ... Eh bien, vous pouvez penser à beaucoup de choses si vous avez de l'imagination :) Si vous alimentez le microcontrôleur à partir de 3V, alors 0V = 0 et 3V = 4096, ce qui signifie 3/4096 = 0,000732421, c'est-à-dire lorsque la tension à l'entrée passe à 0,000732421V, la valeur de l'entrée dans le programme passe à 1. Ce n'est pas si compliqué, non ? Passez
  • Entrée numérique en mode de fonctionnement alternatif - entrée pour travailler avec des périphériques. Par exemple, une entrée pour une minuterie ou une entrée pour une interface. La valeur de cette entrée ne peut pas être lue depuis le programme. Dans le programme, par exemple, vous pouvez lire les données reçues sur cette sortie par une interface.

Et le port configuré pour la sortie peut avoir des broches dans les modes suivants :

  • Sortir. Juste une sortie. Sortie numérique conventionnelle. A la sortie, soit la tension d'alimentation (logique 1), soit il n'y a pas de tension à la sortie (logique 0). C'est simple.
  • La sortie dans le mode de fonctionnement alternatif est une sortie commandée par périphérique. Cette sortie ne peut pas être contrôlée depuis le programme, mais le programme peut être fait pour contrôler cette sortie par exemple une interface.

Mais toutes les conclusions ne peuvent pas être attribuées « à votre guise ». Afin de savoir ce que vous pouvez et ne pouvez pas, vous devez consulter la documentation (tableau 4) ou utiliser le programme MicroXplorer.

Avant d'utiliser le port, vous devez d'abord le cadencer - lui appliquer des impulsions d'horloge, car ils ne sont pas initialement fournis pour économiser de l'énergie. Vous pouvez choisir une fréquence d'horloge différente - plus de fréquence - des entrées ou des sorties plus rapides de ce port, mais aussi plus de consommation d'énergie.

il y a encore des conclusions BOOT 0 et BOTTE 1... Ces broches ne sont pas liées aux ports, elles servent à contrôler le chargement du microcontrôleur. Si, lors de la mise sous tension, la broche BOOT 0 est à zéro logique (la broche est connectée à un point commun), alors le microcontrôleur exécute le programme chargé dans la mémoire flash, c'est-à-dire Votre firmware. Si, lors de la mise sous tension, la broche BOOT 0 est une unité logique (la broche est connectée à l'alimentation du microcontrôleur), et la broche BOOT 1 est un zéro logique, alors le microcontrôleur n'exécute pas votre firmware, mais le bootloader a enregistré à l'usine. Souviens-toi de ça ! Vous l'utiliserez beaucoup lorsque vous travaillerez avec des microcontrôleurs STM32 ! Parfois, le chargement d'un bootloader écrit en usine est le seul moyen d'écrire/modifier le firmware du microcontrôleur. Cela se produit, par exemple, lors de la configuration dans le firmware des sorties auxquelles le programmateur est connecté ou lors du flashage du microcontrôleur sans utiliser le programmateur. Donc recommande fortement lors de la conception d'une carte de circuit imprimé, ces broches (ou au moins BOOT 0) doivent être situées dans un endroit pratique.

Ici, nous l'avons compris :) Maintenant, nous savons ce qu'est un microcontrôleur, en quoi il consiste. Maintenant, nous allons en apprendre davantage sur la sagesse et passer à la chose la plus intéressante - la pratique !

Le programme dans le microcontrôleur est exécuté étape par étape. Un cycle de processeur correspond à une étape de programme.

Par exemple, laissez les voyants rouge et vert clignoter jusqu'à ce que vous appuyiez sur le bouton. La durée de chaque lampe est de 5 secondes. Voici l'algorithme :

  1. Vérifiez s'il y a de la tension à l'entrée avec le bouton ? (le bouton ferme la broche du microcontrôleur à + alimentation)
  2. S'il n'y a pas de tension, alors le voyant rouge s'allume pendant 5 secondes, le vert s'éteint, s'il y a de la tension, alors on recommence
  3. Revérifier
  4. S'il n'y a pas de tension, alors le voyant vert s'allume pendant 5 secondes, le rouge s'éteint, s'il y a de la tension, alors on recommence
  5. Recommençons

ARRÊTER! Que faire si j'appuie sur le bouton alors que la lumière est allumée ? Alors rien ne se passera ! Parce que le programme est exécuté pas à pas et que l'étape de vérification de l'appui sur le bouton est au moment de la commutation des lampes.
C'est pour de tels cas qu'il existe une chose telle que interruption

Les interruptions permettent d'interrompre l'exécution du programme principal. Cela peut se faire soit par un événement externe (appuyer sur un bouton, relâcher un bouton pour recevoir des données, etc.) Lorsque cette même interruption se produit, le sous-programme commence à s'exécuter. Les sous-programmes peuvent être différents pour différents types d'interruptions, ces sous-programmes sont appelés les gestionnaires d'interruption.

Lorsque ce gestionnaire d'interruptions termine son travail, le programme principal commence à s'exécuter à partir du point où il a été interrompu.

Lève-toi sur les pattes !

Eh bien, les chatons, il est temps de se mettre sur pattes ! J'espère que vous avez déjà une carte de débogage ? Ou au moins un microcontrôleur ? J'espère qu'il y en a :) Et sinon, alors on court au magasin ! (et de préférence pas pour le saucisson. quoique...) Quel genre d'enseignement est-ce sans pratique ?

C'est bien au début d'avoir une carte de débogage, par exemple, STM32VL-Discovery, mais si le crapaud s'étouffe ou manque encore de saucisse, alors vous pouvez vous en tirer avec un microcontrôleur et un convertisseur d'interface RS-232 -> UART (par exemple MAX3232) ou USB -> UART (par exemple FT232RL). Dans ce cas, 100 roubles peuvent être bien conservés, mais vous devez fabriquer une carte de circuit imprimé et souder au moins 48 broches de 0,3 mm de large avec un écart de 0,2 mm. J'ai prévenu.

Tout d'abord, vous devez naturellement attacher la carte de débogage ou le contrôleur à l'ordinateur.

Si vous avez une carte de débogage :

Avec une carte de débogage, bien sûr, c'est plus facile. Nous prenons la lanière Mini-USB et connectons la carte à l'ordinateur, tous les pilotes doivent être installés automatiquement. Voir Clé électronique STLink de STMicroelectronics dans le gestionnaire de périphériques, c'est bon signe ! Eh bien, si quelque chose ne va pas et que rien ne se passe - pas besoin de gratter le canapé, il vous suffit d'aller ici et d'installer Utilitaire STM32 ST-LINK.

Eh bien, si vous êtes l'heureux propriétaire d'un ordinateur sous Contrôle des fenêtres 8, puis avant d'effectuer les actions ci-dessus, vous devez procéder comme suit : Options -> Modifier les paramètres de l'ordinateur -> Général -> Options de téléchargement spéciales et sélectionnez le paramètre Désactiver la vérification de la signature du pilote.

Si vous avez un microcontrôleur :

Si vous avez un microcontrôleur, vous devriez avoir les jambes droites. Mais je ne doute pas de toi !

Avant de connecter le microcontrôleur à l'ordinateur, il doit être soudé à la carte de circuit imprimé. Pour cela, en plus du microcontrôleur et des pattes droites, au moins une carte de circuit imprimé est nécessaire. Et puis votre créativité.

Le minimum de travail dans le schéma ci-dessous :


Mais c'est un minimum inintéressant.

Ajoutez des LED et des boutons (n'oubliez pas les broches BOOT), comme ceci


Mais avec la soudure de cette puce, des problèmes peuvent survenir. Mais j'espère qu'ils ne le feront pas. J'ai commencé à le souder avec mon fer à souder soviétique préféré de 25 W avec une largeur de pointe de 3/4 de la largeur du contrôleur. J'ai plus de problèmes avec la fabrication d'un PCB ... eh bien, ici, chacun a sa propre technologie.

Et l'adaptateur doit être fabriqué sur l'UART conformément à la documentation du microcircuit que vous avez acheté.

Nous connectons les broches TxD et RxD sur la carte de circuit imprimé avec les broches RxD et TxD, respectivement, de l'adaptateur. N'oubliez pas le point commun et la nutrition de tout cela.


Sélection et installation du logiciel

Nous utiliserons l'environnement de développement CooCox IDE, mais ce n'est pas que ça, mais pour plusieurs raisons :

  • Tout d'abord, c'est un logiciel libre. Cela signifie que votre karma sera propre.
  • A mon avis (et pas seulement au mien), cet environnement de développement est plus pratique que le reste
  • Permet le débogage
  • De nombreux exemples pouvant être chargés dans l'environnement de développement (utile pour les chatons et pas seulement)

Un environnement de développement est un programme pour écrire du code, un compilateur, un débogueur en un. Idéalement :) Mais s'il est plus pratique pour un chat de Chelyabinsk sévère d'écrire du code (dans un cahier, par exemple), de le compiler et de le flasher avec différents programmes - cela ne me dérange pas, alors l'utilitaire STM32 ST-LINK sera utile pour chargement du firmware dans le microcontrôleur. Le propriétaire est un gentleman, comme on dit.

Cet environnement de développement est basé sur de nombreux Eclipse bien connus.

  1. Viens ici
  2. Poussée Télécharger via CoCenter (recommandé)
  3. Entrez l'adresse e-mail (vous pouvez depuis le bulldozer, c'est là "pour le spectacle")
  4. Après le téléchargement, installez ce très CoCentre
  5. Dans la première ligne où il est écrit CooCox CoIDE poussée Télécharger
  6. Une fois le téléchargement terminé, au lieu de Télécharger volonté Installer... Ici, nous appuyons
  7. Viens ici
  8. Colonne de droite Télécharger télécharger le fichier qui .EXE. Installez-le.
  9. Nous l'ouvrons nous-mêmes CooCox CoIDE, onglet Projet, Sélectionner le chemin de la chaîne d'outils.
  10. Spécifiez le chemin d'accès au fichier arm-none-eabi-gcc.exe (nous l'avons installé à l'étape 8, le chemin est approximativement le suivant : D : Program Files (x86) GNU Tools ARM Embedded4.7 2013q1bin)
  11. S'ouvrir à nouveau CoIDE, presse Vue -> Configuration, ouvrez l'onglet Débogueur et nous le faisons [photo]
  12. Nous sommes heureux car maintenant nous pouvons écrire un programme et le flasher dans le microcontrôleur ! Qu'allons nous faire.

Si vous avez une option sans carte de débogage/programmeur, alors pour télécharger le programme sur le MC, vous aurez besoin d'un programme Démonstrateur Flash Loader qui est situé

Trouve langage mutuel

Avant d'écrire votre premier programme, vous devez trouver un langage commun avec MK. Il est peu probable qu'il apprenne notre langue, il devra donc apprendre (ou peut-être juste se souvenir) de la langue dans laquelle nous communiquerons avec MK, c'est C. Nous n'avons besoin que des bases (composition du programme, fonctions, opérateurs). Si vous connaissez cette langue, alors vous pouvez aller directement à la rubrique "Premier programme", mais je présenterai ceux qui ne connaissent pas le cours.

Le projet se compose de fichiers avec des extensions .c et .h... Dans le premier il y a des fonctions, dans le second, les noms des fonctions utilisées et des constantes, par exemple. C'est juste comme ça. Le fichier le plus important qui contient le code du programme principal c... Pour utilisation différentes fonctions vous devez connecter des bibliothèques avec ces fonctions. Ils sont connectés par enregistrement #include "nom_bibliothèque" eh bien, les bibliothèques devraient naturellement être dans le projet. Connectez-les au tout début du fichier.

Les fonctions font en quelque sorte partie du programme. En général, un programme se compose d'une ou plusieurs fonctions. La fonction ressemble à :

return_variable_type function_name (variable_type)
{
Corps de fonction
}

Vous pouvez envoyer n'importe quelle variable à la fonction, la fonction la traitera et renverra une valeur. Il est très pratique d'utiliser une fonction pour des actions répétitives, plutôt que d'écrire le même morceau de code tout le temps, vous pouvez simplement envoyer une variable à la fonction et récupérer la valeur traitée.

Avant d'utiliser une fonction, elle doit être déclarée au tout début du fichier. Ils le font sous cette forme :

return_variable_type function_name (variable_type);

Ah oui, j'ai oublié le plus important ! Il doit y avoir un point virgule à la fin de chaque ligne !

Si la fonction ne retourne rien (par exemple, un délai, elle tire juste le chat par la queue pendant un moment), alors le type est indiqué annuler.

Au démarrage, la fonction est toujours exécutée en premier. principale ().

Eh bien, nous avons en quelque sorte compris les fonctions, la compréhension ne viendra qu'avec la pratique.

j'ai mentionné plus haut type de variable... Toutes les variables peuvent être de types différents, voici les principales :

  • INT - une variable de ce type ne peut être qu'un entier compris entre -2147483648 et 2147483647
  • FLOAT - une variable de ce type numéro avec une précision de 7 chiffres de ± 1,5 * 10-45 à ± 3,4 * 1033
  • DOUBLE - un nombre avec une précision de 16 chiffres de ± 5 * 10-324 à ± 1,7 * 10306
  • ULONG est aussi un entier, mais de 0 à 18446744073709551615
  • LONG est un entier compris entre -9223372036854775808 et 9223372036854775807
  • CHAR - un caractère
  • BOOL est une variable booléenne. Il ne peut avoir que 2 valeurs : vrai (vrai) ou faux (faux)

Une chaîne (mot, phrase) peut être représentée sous la forme d'un tableau de caractères. Par exemple:

caractère stroka = "Mot" ;

Ici, les crochets sont le nombre de caractères dans une ligne, "stroka" est le nom du tableau.

Avant d'utiliser une variable, elle doit être déclarée. (donnez juste le type et le nom de la variable)

  • + - une addition.
  • - - soustraction.
  • * - multiplier.
  • / - division.
  • = - affecter une valeur à une variable.

Par exemple l'expression a = b + c signifie affecter à une variable une la valeur de la somme des valeurs des variables b et c.

  • ++ - incrémenter. Augmenter la valeur d'une variable de 1
  • -- - décrémenter. Diminuer la valeur d'une variable de 1

Par exemple l'expression un ++ signifie augmenter la valeur de la variable une par 1 (comme a = a + 1)

  • == - comparaison, signe égal. (A NE PAS CONFONDRE AVEC L'AFFECTATION)
  • != - comparaison, signe différent.
  • < - comparaison, signe "moins".
  • <= - comparaison, signe "inférieur ou égal".
  • > - comparaison, signe "supérieur à".
  • >= - comparaison, signe "supérieur ou égal".

Par exemple l'expression une devient vrai si la valeur de la variable une inférieur à la valeur de la variable b et faux si les valeurs sont égales ou une Suite b... Expression a == b vrai si uneéquivaut à b et faux si une inégal b, MAIS expression a = b en vérité toujours car ce n'est pas une comparaison, c'est une affectation à une variable une valeurs variables b.

  • % - reste de la division

Par exemple si a = 5,b = 3, alors la valeur de l'expression un B sera égal à 2 (puisque 5/3 = 1 (reste 2))

  • << - décalage à gauche au niveau du bit. Sans entrer dans les détails le sens de l'expression une< en langage C sera égal à l'expression un * 2 b
  • >> - décalage au niveau du bit vers la droite. Expression a >> b dans le programme équivaut à l'expression a / 2b
  • & - logique ET.
  • | - logique OU.
  • ~ - inverser.

J'ai presque oublié de vous parler des cycles. De base:

tandis que (condition) (

corps de boucle

Le corps de la boucle (tout dans accolades) est exécuté lorsque la condition est vraie (jusqu'à ce que la condition devienne fausse).

for (start_value; loop_execute_to, step) (

corps de boucle

valeur_départ- la valeur initiale du compteur

Cycle_executed_before - jusqu'à quelle valeur le cycle est-il exécuté

Étape - avec quel pas le compteur compte

Par exemple

pour (i = 0; je<10, i++) {

corps de boucle

Voici la valeur initiale de la variable je est égal à 0, la boucle est exécutée tant que la valeur de la variable je inférieur à 10, chaque fois que la boucle est exécutée sur la variable je 1 est ajouté. Vous pouvez également modifier la valeur d'une variable directement dans la boucle.

si (état) (

corps 1

) autre (

corps 2

Dans une transition moustache, « body 1 » est exécuté si la condition est vraie et « body 2 » est exécuté si la condition est fausse. Il existe également une telle option:

si (condition 1) (

) sinon si (condition 2) (

Dans ce cas, "corps 1" est exécuté si "condition 1" est vraie, "corps 2" est exécuté si "condition 2" est vraie. Il peut y avoir n'importe quel nombre de telles conditions, il peut aussi y en avoir une autre.

Les conditions peuvent être simples et composées : simple - une expression logique et composée - plusieurs expressions logiques connectées par & (les conditions sont vraies lorsque toutes les conditions connectées par ce signe sont vraies) ou | (la condition est vraie si au moins une condition reliée par ce signe est vraie).

Les commentaires sont une autre chose utile. Ils vous aideront à comprendre un projet oublié :) ou juste pour que vous n'oubliiez rien. Vous pouvez commenter ou après les signes // et jusqu'à la fin de la ligne ou commencer par des caractères /* et fin */ , dans ce cas, le commentaire peut être n'importe quel nombre de lignes. Les commentaires n'affectent pas la taille du programme.

Eh bien, tout semble provenir du principal. Assez pour la première fois (jusqu'à ce que la prochaine partie de l'article soit écrite)

Premier programme

Ne dévions pas des traditions (sinon on ne sait jamais) et commençons par Hello World. Et en cours de route, nous continuerons à nous familiariser avec le microcontrôleur et, pour ainsi dire, à acquérir de l'expérience.

Ouvrez l'environnement de développement :


Pousser Parcourir dans le référentiel


Nous choisissons ST


Ensuite, nous verrons une liste de bibliothèques à inclure.


Pour notre programme simple, nous avons besoin de : Noyau CMSIS, Démarrage CMSIS, RCC, GPIO.

Bibliothèques Noyau CMSIS et Démarrage CMSIS - système, ils doivent être connectés

Une bibliothèque RCC travailler avec le système de pointage

Une bibliothèque GPIO pour travailler avec les ports d'E/S

Maintenant laissé dans la fenêtre Projet ouvrir le fichier principal c.


Tout d'abord, vous devez connecter nos bibliothèques (vous n'avez pas besoin de connecter CMSIS).

Nous allons au tout début du programme et ajoutons les lignes :

#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"

void Retard (int i) (
pour (; je! = 0; je--);
}

Donc. Ici, dans l'ordre, la fonction ne retourne rien, donc annuler, nom de la fonction Retard, on déclare immédiatement la variable je taper entier... En accolades, le corps de la fonction est une boucle pour... C'est sa notation en minuscules. Valeur initiale je nous ne changeons pas, la boucle s'exécute jusqu'à ce que je n'est pas nul (comme je devient égal à zéro, le cycle s'arrête, la fonction "s'éteint"). A chaque exécution du corps de la boucle (cycle d'horloge), la variable je diminue de 1. C'est-à-dire l'essence du cycle est juste de répéter le nombre de fois égal je... Pendant que le cycle est en cours, le temps s'écoule, il y a un retard.

Quel port est responsable de quelle sortie peut être vu dans la documentation MK :

Pour cadencer le port C, ajoutez la ligne :

RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOC, ACTIVER);


Ajoutez la ligne au programme :

GPIO_InitTypeDef GPIO_Init1;

Avec cette ligne, nous avons déclaré la structure GPIO_InitTypeDef- lui a donné un nom GPIO_Init pour une utilisation dans notre programme plus loin.

Quels paramètres peuvent être configurés dans cette structure et quelle forme ils ont, nous regardons tout de la même manière stm32f10x_gpio.h:


Maintenant, afin de configurer les paramètres des broches en utilisant la structure, vous devez écrire son nom, mettre un point et une fenêtre apparaîtra dans laquelle ces paramètres sont indiqués


Double-cliquez sur l'un d'eux, il apparaît dans la ligne, puis mettez = (attribuer) et écrire la valeur de stm32f10x_gpio.h

Nous faisons la même chose avec tous les paramètres. N'oubliez pas le point-virgule à la fin de chaque ligne !


GPIO_Init (GPIOC, & GPIO_Init);


Maintenant, clignez des yeux ! On va clignoter cycliquement, on va boucler en boucle tandis que. La condition du cycle sera 1. Un est toujours vrai, zéro est toujours faux .. c'est ce la vie ..

Pour appliquer du courant à la sortie, vous devez définir un bit ; pour désactiver la sortie, vous devez effacer le bit. Comment le faire - tout est pareil stm32f10x_gpio.h:


Nous faisons ceci :

tandis que (1) (

GPIO_SetBits (GPIOC, GPIO_Pin_9) ;

Retard (200000) ;

GPIO_ResetBits (GPIOC, GPIO_Pin_9) ;

Retard (200000) ;

1 est toujours vrai, donc la boucle sera bouclée.

GPIO_SetBits - fonction de réglage des bits

GPIO_ResetBits - fonction de réinitialisation des bits

Delay (200000) - sur cette ligne, l'exécution du programme entre dans la fonction Retard, dans celui où le cycle pour... Le nombre 200000 entre parenthèses est passé à cette fonction en tant que variable je... (rappelez-vous la ligne void Delay (int i)?) et la même boucle est exécutée dans cette fonction, toutes 200 000 fois. C'est rapide :) après la fin du cycle pour fonction relais termine son travail, tk. elle annuler, puis il ne renvoie rien et le programme continue de s'exécuter.

Parce que tandis que est en boucle, puis LED allumée, retard, LED éteinte, le retard sera exécuté de manière cyclique à l'infini. Jusqu'à ce que l'alimentation soit coupée ou qu'une interruption se produise (plus de détails dans le prochain article).

Eh bien, le premier programme est prêt. Appuyez maintenant sur F7, le programme est compilé.

Maintenant, si vous avez une carte de débogage, connectez-la à l'aide d'un câble USB et appuyez sur Télécharger le code pour flash... Nous nous réjouissons du travail accompli et des connaissances acquises :)

Et si vous n'avez pas de carte de débogage, connectez l'adaptateur fabriqué précédemment à votre carte et l'adaptateur au port COM de l'ordinateur. Ensuite, connectez la broche BOOT 0 c plus l'alimentation du microcontrôleur et allumer l'alimentation du microcontrôleur. Ainsi, le microcontrôleur entrera en mode firmware. En général, la procédure du firmware n'est pas compliquée. Il vous suffit de suivre les instructions de l'application Démonstrateur Flash Loader... Tout d'abord, nous indiquons le numéro du port COM via lequel votre microcontrôleur est connecté et la vitesse. Pour éviter les accidents, il est préférable de choisir une vitesse inférieure.

Si le programme voit votre microcontrôleur, une fenêtre apparaîtra dans laquelle il sera écrit combien de mémoire il a

Après avoir cliqué sur "Suivant", vous verrez une page avec l'adressage mémoire. Nous n'en aurons pas besoin.

La prochaine étape est la plus cruciale. Vous pouvez choisir d'effacer la mémoire ou de flasher

Pour le firmware, choisissez Télécharger sur l'appareil et sur le terrain Télécharger à partir du fichier sélectionnez le fichier .hex compilé qui se trouve dans le dossier CooCox -> CooIDE -> workspace -> project_name -> project_name -> Debug -> Bin... Puis cliquez à nouveau sur "Suivant".

Après avoir vu une telle fenêtre :

Coupez l'alimentation du microcontrôleur, fermez Démonstrateur Flash Loader, éteignez l'adaptateur et allumez le microcontrôleur en mode normal (lorsque lorsqu'il est allumé La broche BOOT 0 est connectée au moins de l'alimentation du microcontrôleur). Nous sommes heureux!

Donc, maintenant nous savons pourquoi les microcontrôleurs STM sont meilleurs que les autres, nous savons comment fonctionne un microcontrôleur, nous savons comment flasher un microcontrôleur dans une carte de débogage et dans notre propre carte, nous connaissons les bases du langage C, qui sont nécessaires pour programmation STM32, acquis de l'expérience avec un microcontrôleur (espérons-le positif) et, plus important encore, vous pouvez maintenant donner vie à vos idées d'appareils numériques (et en parler sur notre bien-aimé Radio Cat) ! Qu'ils soient encore sans prétention, mais tout se rattrape avec l'expérience. Et dans les prochains articles, j'essaierai de parler des ADC, des DAC, des interruptions, de l'utilisation du débogage et d'autres utilités.

2021 wisemotors.ru. Comment ça fonctionne. Le fer. Exploitation minière. Crypto-monnaie.