Nous commençons à étudier les microcontrôleurs en utilisant l'exemple de STM32F030f4p6



0. Avant de lire l'article


Cet article a les objectifs suivants:

  1. montrer comment travailler spécifiquement avec ce forum;
  2. montrer l'approche par laquelle vous pouvez écrire un programme LED clignotant, en vous appuyant uniquement sur la documentation et la logique;
  3. présenter le matériel dans un langage compréhensible pour une personne peu familière avec les microcontrôleurs.

Le code se révélera minimaliste en termes d'utilisation de fichiers supplémentaires - nous n'inclurons pas un seul fichier, à l'exception de ceux qui sont nécessaires pour construire un firmware vide, mais valide. C'est-à-dire basé sur le code du firmware, qui fonctionne, mais ne fait rien d'utile.

Nous aurons besoin de la documentation suivante:

  1. Fiche technique STM32F030x4 (j'utilise le document de janvier 2017 DocID024849 Rev 3);
  2. RM0360 Manuel de référence STM32F030x4 / x6 / x8 / xC (j'utilise le document d'avril 2017 DocID025023 Rev 4);
  3. carte de circuit imprimé.

Vous pouvez télécharger ces documents depuis le cloud .
La minuterie de l'article ne sera pas prise en compte et ne sera pas impliquée dans le code.
Le programmeur ST-LINK n'a pas été utilisé. Pour travailler avec la carte, un adaptateur USB-COM (RS232 basé sur PL2303HX) a été utilisé, qui émule un port COM.

Adaptateur photo

Tout a été collecté sur une machine virtuelle Windows XP Professionnel 2002 SP3 exécutée via VirtualBox version 5.2.22r126460 sur un hôte Windows X.

1. Installation du pilote pour l'adaptateur USB-COM


Windows n'est pas une aide, téléchargez à partir du site officiel Prolific (le premier lien vers la requête "prolific driver" dans Google) USB vers UART / Serial / Printer PL2303 Windows Driver (vous avez besoin de celui qui pilote Standard ). Ou vous pouvez télécharger depuis mon cloud .

Installez le pilote, redémarrez et voyez le nouveau port COM.

Capture d'écran avec le nom du programme d'installation et le nouveau port COM

Les paramètres de port sont restés standard. Vous pouvez modifier le numéro de port COM à votre discrétion. D'après mon expérience, une seule fois dans ma vie, j'ai vu un programme ne voir que les 4 premiers ports COM, si je ne me trompe pas, c'était une sorte de terminal Bluetooth sous Windows.

Paramètres du port COM


2. Remplissage du firmware sur et hors de la carte


2.0 Utilitaire de téléchargement pour travailler avec la carte


Nous téléchargeons l' utilitaire FLASHER-STM32 à partir du site Web de la STM (dans la description, il s'agit du démonstrateur de chargeur Flash STM32 (UM0462)), vous devrez vous inscrire pour cela, mais ce n'est pas effrayant - au final, nous déposerons l'archive zip avec le programme d'installation; Suivant-> Suivant-> Suivant ... et tout est installé. Pour plus de commodité, je crée un raccourci vers cette application dans le dossier de travail.

Voici l'utilitaire (capture d'écran du site)


Par défaut, le chemin d'accès à l'utilitaire C: Program Files \ STMicroelectronics \ Software \ Flash Loader Demo \ STMFlashLoader Demo.exe .

2.1 Nuance BOOT


Il y a un cavalier BOOT sur la carte.

  • Lorsque le cavalier est fermé , le microcontrôleur charge les instructions de sa mémoire (c'est-à-dire un programme écrit par un programmeur).
  • Lorsque le cavalier est ouvert , le microcontrôleur reçoit des informations sur les lignes RX et TX, c'est-à-dire Il sera flashé depuis le port COM (depuis l'adaptateur dans mon cas).

2.2 Configuration de l'utilitaire




Exécutez cette application, c'est en fait la plus simple (contient un minimum de paramètres). Dans la première fenêtre, sélectionnez:

  1. interface (j'ai COM-3);
  2. la vitesse avec laquelle l'ordinateur et le microcontrôleur communiqueront (IMHO, 9600 valeur normale);
  3. le nombre de bits de données (pour une raison quelconque, cette fenêtre n'est pas disponible pour moi, mais jusqu'à présent, ce n'est pas important);
  4. parité (je n'ai pas de parité, c'est-à-dire aucune);
  5. écho (j'ai désactivé);
  6. temps d'attente (j'ai 10 secondes).

Cliquez sur Suivant, et si tout est en ordre, alors nous verrons un feu vert et "La cible est lisible"; si nous voyons une lumière rouge, l'ordinateur n'a pas pu se connecter.

La cible est lisible si le microcontrôleur est détecté avec succès


L'ordre des étapes qui aident toujours:

  1. Tout d'abord, vous devez vérifier si le cavalier BOOT de la carte est fermé.
  2. Deuxièmement, dans tous les cas, coupez l'alimentation du microcontrôleur et de préférence les lignes TX et RX provenant de l'adaptateur à la carte (vous ne pouvez pas déconnecter la masse).
  3. Troisièmement, dans le programme, appuyez sur Retour à la fin, c'est-à-dire à la première page, ou même la fermer et la redémarrer (en général, elle se bloque parfois). Il est important de toujours commencer à partir de la première page avant chaque connexion à la carte via ce programme.
  4. Quatrièmement, ramassez les fils de l'adaptateur à la carte et essayez de vous reconnecter dans le programme (assurez-vous dès la première page!).

Si tout le reste échoue, vous pouvez essayer de tout éteindre, redémarrer l'ordinateur et essayer de vous reconnecter à la carte.

Parce que Je travaille via une machine virtuelle, je dois reconnecter l'adaptateur USB-COM plusieurs fois pour qu'il soit détecté par la machine virtuelle, et la machine hôte n'a pas le temps d'installer des pilotes cassés.

Une autre option que j'ai trouvée utile en écrivant cet article est d'appuyer sur un bouton du tableau au lieu de tirer constamment sur les fils. Cependant, vous devrez dans tous les cas fermer et ouvrir le cavalier BOOT. Cette option fonctionne car le bouton est placé au pied de la réinitialisation NRST externe.

Dans la fenêtre suivante, sélectionnez le périphérique cible Cible. À propos, parfois ici, vous pouvez voir (peut-être un bug) le périphérique gauche en général, par exemple, au lieu de STM32 voir STM8 - quelque part il y a eu une sorte d'échec, la procédure de traitement est décrite ci-dessus. Par conséquent, à cette étape, vous ne pouvez pas vous précipiter pour cliquer sur Suivant, mais faites toujours attention au fait que le périphérique souhaité est sélectionné dans Target.

Sélection du périphérique cible


Comment déterminer quel appareil nous avons? - nous regardons la puce et réécrivons tout ce qui y est écrit. Nous ouvrons la fiche technique sur notre puce, la section Informations de commande décrit quelle lettre est responsable de quoi. Dans mon cas c'est:



Je sélectionne ma puce (16K) dans Target et je continue.


Un choix de 4 actions avec une puce est proposé:

  1. effacer la mémoire (entière ou sélectionner une zone spécifique);
  2. écrire le firmware sur l'appareil;
  3. lire le firmware de l'appareil;
  4. activer / désactiver la protection en écriture ou en lecture.

2.3 Lire le firmware depuis la carte


Lorsque j'ai connecté la carte pour la toute première fois, j'ai décidé de conserver le firmware d'origine, une sorte de sauvegarde - nous le ferons maintenant. Il sera nécessaire d'indiquer où sauvegarder ce firmware et quelles pages de mémoire sauvegarder, il est également proposé d'utiliser un format de fichier hex , bin ou s19 au choix .

Sélectionnez les pages mémoire à lire


Si vous téléchargez simplement le micrologiciel sur la carte ou lisez le micrologiciel à partir de la carte, il n'y a pas de différence entre ces formats de fichier. Ce qui suit est une page de progression, sur laquelle parfois le processus se bloque pendant 99% pendant longtemps (pas nécessairement 99), mais après quelques secondes, il se termine normalement avec succès - en fait, après cela, la carte n'a pas donné le comportement qui correspondrait au firmware chargé. Autrement dit, vous devez tout reconnecter et recharger le firmware, il n'y a rien de critique à ce sujet.

Le fichier du micrologiciel a été enregistré et, à l'avenir, il pourra être téléchargé sur la carte.

Cependant, si la protection en lecture est installée, le micrologiciel ne peut pas être lu.

Fenêtre de progression


2.4 Flasher le tableau


Remplissez maintenant le fichier du firmware dont l'écriture du code source est donnée ci-dessous. Pour l'avenir, je dirai que nous allons télécharger des fichiers bin et hex , car l'environnement de développement les délivrera. Les paramètres supplémentaires pour les fichiers s19 et hex sont identiques; contrairement à eux, dans le fichier bin , vous pouvez sélectionner l'adresse à partir de laquelle le firmware sera enregistré, par défaut dans l'utilitaire c'est 8000000 (adapté pour nous).

Préparation à l'enregistrement


Avant l'enregistrement, vous pouvez effacer la mémoire flash du microcontrôleur en choisissant l'une des trois options:

  • Effacer les pages nécessaires (effacer les sections de mémoire nécessaires);
  • Pas d'effacement (sans purification);
  • Effacement global (nettoyage complet).

En fait, le nettoyage est le processus d'écriture de zéros dans la mémoire.

Il y a encore des octets facultatifs, mais jusqu'à présent, vous ne pouvez pas les toucher. Cliquez sur Suivant, attendez la fin du processus et vous avez terminé.

Si vous souhaitez enregistrer mon firmware, vous pouvez le trouver dans le cloud, le fichier blink.bin . Lorsque vous utilisez ce micrologiciel, le voyant intégré clignotant du pied PA4 devrait clignoter.

3. Écriture de code


3.0 Installation de l'environnement de développement CooCox CoIDE


Vous pouvez télécharger l'IDE à partir du site Web SoftPedia.com , avant de pouvoir le télécharger à partir du site Web de la STM et du site Web IDE lui-même, mais depuis que les IDE ont cessé de prendre en charge, il est devenu impossible. Il n'y a rien de critique que l'IDE ne soit plus pris en charge, non, car pour écrire du code, l'essentiel est le compilateur. J'ai téléchargé les deux versions, mais j'utilise la version 1.7.8.
Le premier lancement de l'environnement est bien décrit ici , Suivant-> Suivant-> Suivant ... et rien de compliqué. J'ajouterai seulement qu'il est préférable de créer un projet, puis tout le reste.

Et pourtant, si vous avez perdu l'onglet Référentiel, vous pouvez le trouver dans le menu Affichage -> Référentiel .
Vous pouvez télécharger des outils (compilateur) pour l'environnement ici ou demander à Google "gnu tools for arm"; J'ai téléchargé une option contenant sha1.exe à la fin.

3.1 Cadre source


Donc, le projet a été créé, la puce a été sélectionnée, maintenant nous allons ajouter le minimum de sources au projet, sans lequel il ne pourra pas vivre du tout.

Voici à quoi devrait ressembler le projet à sa création, c'est-à-dire il n'y a que le fichier principal main.c et rien de plus


Sélectionnez CMSIS BOOT et l'environnement sélectionnera automatiquement M0 Cmsis Core , car les dépendances l'exigent.

Maintenant, nous obtenons l'ensemble minimum de sources


Assemblez le projet (icône Build ou touche F7). Pour des raisons que je ne connais pas, le fichier hexadécimal n'a pas été collecté (il y a un avertissement dans la console); J'ai réinstallé l'IDE et le compilateur plusieurs fois, recréé le projet, mais pour une raison quelconque, un tel résultat sur la machine virtuelle; sur un autre ordinateur (pas virtuel, mais réel), tout est en tête-à-tête et la sortie fonctionne en hexadécimal. Heureusement, il y a bin.

Le projet a été assemblé avec succès


Je vous conseille de faire attention à la taille du fichier, il peut être vu à la fin de la sortie dans la console, ou vous pouvez le voir par des moyens standard (ici, au fait, vous pouvez voir que l'hex est vide); En même temps, cette capture d'écran montre que les fichiers du firmware se trouvent dans le dossier du projet, puis Debug / bin /


Bien que le code ne fasse rien, je le télécharge sur la carte afin de m'assurer que vous pouvez le télécharger (ce qui, par exemple, l'utilitaire ne le rejette pas). Je conseille au lecteur de le faire. Si cela ne fonctionne pas, réessayez encore et écrivez des commentaires.

3.2 Algorithme de doigt


Pour commencer, nous décrivons un algorithme comment, d'un point de vue humain, le microcontrôleur clignotera une LED. Et pour cela un petit raisonnement.

Chaque équipement fonctionne en raison de l'énergie stockée, par exemple, certains moteurs peuvent fonctionner avec différents types de carburant, mais pour cela, le moteur doit être ajusté au type de carburant avec lequel nous allons le nourrir. De même, le microcontrôleur doit être ajusté (réglé) pour la source d'énergie - ce sera le premier bloc de l' algorithme.
Nous raisonnons plus loin. L'ordinateur de bureau a un moniteur, des haut-parleurs, un clavier, une souris ... et vous pouvez voir que certains appareils nous fournissent des informations, et avec l'aide d'autres, nous fournissons des informations à l'ordinateur, mais ils sont tous connectés à une boîte commune à tous (l'unité centrale). Vous pouvez deviner que le microcontrôleur peut recevoir et donner des informations, ce qui signifie que ses jambes peuvent recevoir un signal ou émettre un signal - ce sera le prochain bloc de l' algorithme.

Ensuite, le microcontrôleur doit allumer la LED, attendre un moment, éteindre la LED, attendre un moment et l'allumer-attendre-éteindre ...

En conséquence, l'algorithme ressemblera à ceci



Le but de cet organigramme est de montrer clairement ce que fait l'algorithme; Tout d'abord, le schéma est écrit pour vous-même, donc tout le monde est libre de l'écrire / le dessiner comme il veut (pour lui-même). Je crois que le schéma devrait viser à être aussi simple, lisible et intuitif que possible, à avoir un niveau d'abstraction élevé.

Conformément à cet algorithme, nous écrirons du code.

3.3 Travailler avec la documentation


Je recommande de lire cette partie de l'article avec le fichier ouvert stm32f0xx.h , qui se trouve dans le dossier cmsis_boot de notre projet, et la documentation ouverte.

3.3.1 Sélection d'une source d'horloge


Tout d'abord, vous devez alimenter le microcontrôleur. Le microcontrôleur reçoit 5 Volts de l'adaptateur (mesuré avec un multimètre), mais la question se pose de «à quelle fréquence le microcontrôleur travaille-t-il», car il est connu que l'électronique fonctionne à différentes fréquences. Tout d'abord, ouvrez la fiche technique , dans le contenu, vous pouvez voir deux sections pertinentes: Gestion de l'alimentation , Horloges et démarrage . Le premier concerne les modes de tension et de faible puissance. La deuxième section cache ce qui nous intéresse en ce moment. Déjà dans la toute première phrase, il est dit «l'oscillateur interne RC 8 MHz est sélectionné comme horloge CPU par défaut lors de la réinitialisation», ce qui signifie que par défaut après la réinitialisation du MC, la chaîne RC interne 8 MHz est sélectionnée comme source d'horloge principale .
Vient ensuite un schéma d'arbre d'horloge incompréhensible, que nous examinerons un peu plus tard.


Arbre d'horloge

À strictement parler, vous pouvez vous fier à l'expression "par défaut après réinitialisation du MK ..." et lire cette partie de l'article en diagonale.

Maintenant, vous devez vous laisser distraire par la carte et rechercher la LED interne. Je sais que les diodes dans les circuits sont désignées par D1 , D2 ..., c'est-à-dire D == diode , sur ma carte près de la résistance R7 se trouve la diode D1 .

Photo du tableau


Peut-être, après avoir soigneusement examiné la carte, vous pouvez déterminer à quelle jambe la diode est accrochée, mais je vais me tourner vers la carte de circuit imprimé. Malheureusement, les éléments de la carte ne correspondent pas exactement aux éléments du circuit à leur emplacement; mais je suis content d'avoir trouvé un tel schéma sur Internet (sinon je n'ai rien trouvé pendant longtemps).



Dans le diagramme, nous voyons que la cathode de la diode est connectée à la masse via le cavalier J2 , et l'anode est connectée à la broche PA4 via une résistance. PA4 signifie la 4ème sortie du port A , ce qui signifie que pour allumer et éteindre la LED, il sera nécessaire de fournir une tension à la sortie de PA4 .

Ensuite, vous devez déterminer comment appliquer une tension à cette sortie. Ce n'était pas du tout intuitif pour moi, et pendant longtemps j'ai parcouru la documentation dans le sens de la longueur et à travers jusqu'à ce que je tombe sur le diagramme dans la section Description au tout début de la fiche technique. Et dedans, j'ai vu la piste précieuse PA [15: 0] <=> Port GPIO A <=> Décodeur AHB <=> Matrice de bus <=> Cortex-M0 , c'est -à- dire Le port A est un port d'E / S à usage général et est connecté au bus AHB .

Schéma fonctionnel
(L'image est cliquable)


Je note qu'en électronique, il est habituel de casser les sorties du microcontrôleur en ports, et généralement le port a 16 sorties. Le diagramme montre que les ports A , B et C n'en ont que 16, mais les ports D et F en ont moins (moins de 16 broches peuvent l'être, plus - non).

Revenons au schéma de l' arbre d'horloge et trouvons la sortie signée par AHB . Nous déterminerons à quelle fréquence cette sortie fonctionne. Pour l' AHB est le signal HCLK , qui quitte le diviseur HPRE . Ce diviseur reçoit le signal SYSCLK du commutateur SW . Lequel des signaux à l'entrée SW sera utilisé car SYSCLK est défini par programme - nous le définirons ensuite dans le code. Le choix est offert:

  1. HSI - un signal provenant d'un générateur haute fréquence interne, il est produit par un résonateur à quartz de 8 MHz, que j'ai soudé avant de travailler avec cette carte;
  2. PLLCLK - signal provenant du multiplicateur de fréquence PLLMUL ;
  3. HSE - signal provenant d'un générateur haute fréquence externe.

Toute option convient à notre tâche, je suggère de choisir la plus simple et la plus abordable d'entre elles - HSI .

Nous allons entrer dans le manuel de référence et ouvrir la section 7 Réinitialisation et contrôle d'horloge (RCC) , en particulier 7.2.6 Sélection de l'horloge système , où une fois encore nous rencontrons un libellé similaire trouvé dans la fiche technique: "après une réinitialisation du système, l'oscillateur HSI est sélectionné comme système horloge "- c'est-à-dire nous n'avons même rien à faire, MK commencera sur HSI .

Pour m'assurer que MK fonctionnera vraiment à partir de cette source, je l'écrirai explicitement dans le programme; Faites défiler jusqu'aux registres responsables de la réinitialisation et de la synchronisation (section 7.4 Registres RCC ). Le premier registre décrit dans la documentation est le registre de contrôle d'horloge (RCC_CR) ; Voici une description des bits, qui est responsable de quoi.

Registre de contrôle d'horloge


Nous nous intéressons au bit zéro HSION , qui est responsable de la mise en marche du résonateur ( 0 - désactivé, 1 - activé ).

Ainsi, il sera nécessaire d'en écrire un dans le registre RCC_CR . (zéro bit est un, ou 2 0 = 1).

Maintenant, nous trouvons dans le fichier stm32f0xx.h la définition de RCC ( #define RCC ).

RCC-> RC


Comme vous pouvez le voir, il s'agit de la structure située à RCC_BASE ; adresse 0x40021000 , si vous développez tout définir , la même adresse peut être vue dans le manuel de référence dans la section 2.2.2 Carte mémoire et enregistrer les adresses de limite et dans la fiche technique dans la section 5 Cartographie mémoire (zone AHB ).

Pour écrire une unité pour activer HSI dans le registre CR du bloc RCC , vous avez besoin d'une ligne de code

RCC->CR |= 0x1; 

3.3.2 Réglage des jambes


L'envoi d'un signal à la jambe du microcontrôleur pour allumer la LED et arrêter le signal pour que la LED s'éteigne sont des actions simples, et donc cela se réfère aux fonctions GPIO (ports d'entrée-sortie à usage général).

Par défaut, les jambes MK ne sont pas connectées, c'est-à-dire la sortie est l'incertitude. Il est nécessaire de connecter un port, dont la jambe alimentera la LED. Plus tôt, nous avons déterminé que les ports GPIO sont connectés au bus AHB - vous devez prendre ce bus. En continuant à parcourir la section 7.4 Registres RCC ( registres de commande de contrôle et de réinitialisation), nous trouvons la section 7.4.6 Registre d'activation d'horloge périphérique AHB ( RCC_AHBENR , registre d'activation d'horloge de bus AHB ). Plus tôt, j'ai déterminé que ma LED est connectée à la jambe PA4 - en conséquence, j'ai besoin d'écrire une unité sur le 17e bit du registre afin de clouer le port A.

Registre d'activation de l'horloge périphérique AHB


En conséquence, le code devrait être

 RCC->AHBENR |= (1 << 17); 

ou, c'est la même chose

 RCC->AHBENR |= 0x20000; 

soit en utilisant le fichier #define stm32f0xx.h en écriture

 RCC->AHBENR |= RCC_AHBENR_GPIOAEN; 

RCC-> AHBENR


Nous avons alimenté le port A , nous devons maintenant informer MK que PA4 fonctionnera à la sortie - nous lirons la section 8 E / S à usage général (GPIO) ; l'introduction de la section dit déjà "Chaque port d'E / S à usage général a quatre registres de configuration 32 bits ( GPIOx_MODER , GPIOx_OTYPER , GPIOx_OSPEEDR et GPIOx_PUPDR ), deux registres de données 32 bits ( GPIOx_IDR et GPIOx_ODR ) ..." - pour chaque GPIO Il y a 4 registres de réglage et 2 registres de données dans le port - c'est ce dont nous avons besoin (configurer le port A , ou plutôt la sortie PA4 , et lui envoyer périodiquement 0 et 1 ). Pour une meilleure compréhension (théorie) de ce qui se passe, vous pouvez lire cette section, mais je fais défiler jusqu'à la section 8.4 Registres GPIO et configurer le port conformément aux descriptions.

  1. mode port - quitter. Conformément à la documentation, il est nécessaire d'écrire 01 dans la zone correspondante ( MODER4 ) du registre correspondant ( GPIOA_MODER ), c'est-à-dire bits 9 et 8 : dans le 9ème bit doit être nul, dans la 8ème unité:

     GPIOA->MODER |= (1 << 8); //  

     GPIOA->MODER |= 0x100; //  

     GPIOA->MODER |= GPIO_MODER_MODER4_0; 

    Registre du mode de port GPIO


    GPIOA-> MODER


  2. type de sortie. Honnêtement, je n'ai toujours pas complètement compris les circuits de cette affaire (je comprendrai, relirai les forums, etc.), mais étudier d'autres ressources sur la configuration de la sortie MK, ainsi que la logique et l'intuition, suggère qu'il devrait y avoir une poussée -pull et ensuite devrait être pull-up . Dans tous les cas, le code est écrit, tout fonctionne et rien ne brûle. Il existe un risque réel de brûlure si vous sélectionnez le type à drain ouvert et court-circuitez cette sortie avec un autre appareil, comme Il s'agit d'une sortie ouverte et n'est protégée par rien. De plus, nous avons une résistance de limitation de courant devant la diode - elle ne brûlera certainement pas ici.

    Suite à la documentation, il est nécessaire d'écrire zéro dans le 4ème bit; la documentation indique également qu'après la réinitialisation, il y aura zéro.

     GPIOA->OTYPER &= ~(1 << 4); //  

     GPIOA->OTYPER &= ~0x10; //  

     GPIOA->OTYPER &= ~GPIO_OTYPER_OT_4; 

    Registre du type de sortie du port GPIO


  3. vitesse de sortie. Dans notre cas, cela n'a pas d'importance, mais pour des raisons de fidélité, je vais écrire ici zéro.

     GPIOA->OSPEEDR &= ~(1 << 8); //  

     GPIOA->OSPEEDR &= ~0x100; //  

     GPIOA->OSPEEDR &= ~GPIO_OSPEEDER_OSPEEDR4_0; 

    Registre de vitesse de sortie du port GPIO


  4. un ascenseur . Parce que la sortie alimentera la LED, vous devez la tirer à la puissance, c'est-à-dire pull-up .

    Il est nécessaire de serrer la 4ème broche du port A ; la documentation indique que pour cela, il est nécessaire d'écrire respectivement zéro et un sur 9 et 8 bits.

     GPIOA->PUPDR |= (1 << 8); //  

     GPIOA->PUPDR |= 0x100; //  

     GPIOA->PUPDR |= GPIO_PUPDR_PUPDR4_0; 

    Registre pull-up / pull-down du port GPIO


    GPIOA-> PUPDR



3.3.3 LED on / off et retard


Plus tôt, nous lisons que chaque port a des registres, y compris des registres de données IDR et ODR - registres de données d'entrée et de sortie, respectivement. Zéros logiques et uns sur la jambe MK - ces données sont-elles? - oui, les données. Les données peuvent provenir de l'extérieur du microcontrôleur (être entrées ) et sortir du microcontrôleur et aller vers un autre appareil (être sorties ). L'unité sur la jambe MK est la présence d'un niveau de haute tension, c'est-à-dire si vous en apportez un à la sortie, alors il y aura de la tension, et cette LED peut alimenter notre LED. La sortie d'une unité vers le pied du microcontrôleur est autre chose que l'écriture de cette unité dans le registre de sortie ODR .

Registre de données de sortie du port GPIO


Selon la documentation, nous voyons que pour chaque port ( A , B , C , D , F ) il y a cependant un registre 32 bits. le port ne peut pas avoir plus de 16 broches, alors seuls les 16 premiers bits du registre sont utilisés. Chaque bit correspond à un numéro de port (broche). Pour sortir une unité sur la jambe PA4 , il faut écrire une unité sur le 4e bit, pour sortir un zéro - écrire un zéro sur le 4e bit, c'est-à-dire supprimer la tension de la sortie.



GPIOA-> ODR


Le code pour allumer la LED ressemblera à ceci

 GPIOA->ODR |= (1 << 4); //  

 GPIOA->ODR |= 0x10; //  

 GPIOA->ODR |= GPIO_ODR_4; 

Code pour éteindre la LED

 GPIOA->ODR &= ~(1 << 4); //  

 GPIOA->ODR &= ~0x10; //  

 GPIOA->ODR &= ~GPIO_ODR_4; 

Mais si vous écrivez la ligne pour éteindre la LED après la ligne pour l'allumer, la LED ne clignotera pas (si vous êtes intéressé par ce qui se passe - vous pouvez essayer; rien ne brûlera, cela a déjà été discuté ci-dessus) - alors vous devez faire un retard. Les minuteries sont utilisées pour le retard, mais les minuteries sont dignes d'un article séparé (en raison de la complexité), nous allons donc faire un retard de béquille: nous allons conduire le cycle de ralenti. Il y a un point: si l'optimisation du compilateur est activée , le compilateur coupera notre cycle d'inactivité et il n'y aura pas de retard. Assurez-vous que l'optimisation n'est pas activée. Pour ce faire, entrons dans la configuration du projet (clic droit sur le nom du projet dans l'arborescence du projet) et vérifions la ligne Compiler Control String dans l'onglet Compiler : elle doit avoir l'argument -O0 («environ zéro» signifie que l'optimisation est désactivée). Si vous avez tout collecté selon mes instructions, vous aurez probablement aussi -O0 , car c'était par défaut et je n'ai rien touché ici. Les arguments -O1 -O2 -O3 signifient que l'optimisation du niveau correspondant est activée.

Vérification de l'optimisation du compilateur


Un cycle inactif peut s'écrire comme ceci:

 int t = 4000000; while(t > 0) t--; 

Je n'ai pas défini la valeur de t en tant que telle, j'ai raisonné comme suit: si le microcontrôleur fonctionne à 8 MHz, il exécutera environ 8 000 000 d'instructions en une seconde, si vous exagérez profondément, puis pendant une demi-seconde, vous devrez exécuter le cycle 4 000 000 fois.
Le cycle de veille devra être exécuté après avoir allumé la LED et après l'avoir éteinte, et tout cela en boucle.

3.4 Écriture de code et exécution


Mettons ensemble toutes les lignes de code que nous avons écrites auparavant. Vous devez également inclure le fichier d'en-tête stm32f0xx.h , comme nous nous y sommes appuyés et en avons tiré des définitions des structures, des adresses et des valeurs. Le résultat devrait être:

 #include "stm32f0xx.h" int main(void) { int t; //  '' RCC->CR |= 0x1; //   HSI RCC->AHBENR |= RCC_AHBENR_GPIOAEN; //   A GPIOA->MODER |= GPIO_MODER_MODER4_0; // PA4   GPIOA->OTYPER &= ~GPIO_OTYPER_OT_4; //  push-pull  PA4 GPIOA->OSPEEDR &= ~GPIO_OSPEEDER_OSPEEDR4_0; //    PA4 GPIOA->PUPDR |= GPIO_PUPDR_PUPDR4_0; //  pull-up  PA4 while(1) { GPIOA->ODR |= GPIO_ODR_4; //    PA4 t = 4000000; while(t > 0) t--; //  GPIOA->ODR &= ~GPIO_ODR_4; //    PA4 t = 4000000; while(t > 0) t--; //  } } 

Cliquez sur Reconstruire et remplissez le code sur la carte via l'utilitaire.



Pour que la carte lance un nouveau firmware, n'oubliez pas de fermer le cavalier BOOT et de faire une réinitialisation (RESET).

4. Conclusion


Le code est écrit, tout fonctionne. Les forces ont dépensé sans mesure. Je suis heureux que sur la base de la documentation, il se soit avéré écrire du code de travail, principalement en raison du fait que STM dispose d'une documentation de haute qualité.

Les plans sont d'écrire un article sur la façon de tout assembler à la main, sans IDE, via la console, vrai oldschool , idéalement pour que tout cela puisse se faire sous Linux. Maintenant, je travaille sur PWM et ADC (également sur cette carte) - je vais aussi écrire un article dessus.

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


All Articles