All posts by mjuneau

STM32 ADC de base

Cet article présente la configuration de base d’un ADC sur le STM32F446. Dans un premier exemple, l’ADC1 sera configuré sur le canal 0 pour une lecture démarrée dans l’interruption du timer 2. Dans un second exemple, la lecture sera démarrée automatiquement par l’événement CC2 (Capture/Compare canal2) du timer 2. Tous les exemples utiliseront l’interruption de fin de conversion. Le code complet se trouve à la fin de l’article.

Read More


USART2 avec Classe

Il est possible (et pratique) de faire de l’orienté objet sur les STM32. Cet article présente un exemple pour le USART2 du Nucléo-F446RE. Le code source complet est disponible sur sourceForge.

Voici le UML de la classe STM32F446RE_USART2 que nous allons réaliser.

Le contrôle des données en entrée et en sortie se fera via les interruptions, ce qui explique l’amitié pour le gestionnaire d’interruption. De plus, la classe implémentera le patron singleton afin de permettre le partage du périphérique entre différents éléments d’un programme.

Il est possible de configurer les périphériques des STM32 à l’aide de la librairie HAL ou des librairies standards. Je préfère configurer directement les registres à partir des informations disponibles dans le manuel de référence et la feuille de spécification.

Le USART2 du Nucléo est relié au lien USB qui présente un lien série virtuel sur l’ordinateur (pratique pour le débogage). La figure suivante montre que TX et RX du USART2 sont respectivement reliés à PA2 et PA3.

Le constructeur fera dans un premier temps la configuration des horloges, puis celle des broches E/S avant de terminer avec la configuration des registres spécifiques au USART2.

STM32F446RE_USART2::STM32F446RE_USART2()   
{
// Activer les horloges
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
RCC->APB1ENR |= RCC_APB1ENR_USART2EN;
// Configurer IO pour RX et TX
// PA2 et PA3 en Alternate fonction
GPIOA->MODER |= GPIO_MODER_MODER2_1 | GPIO_MODER_MODER3_1;
// PA2 et PA3 en High speed
GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR2;
GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR3 ;
GPIOA->AFR[0] |= GPIO_AF_USART2 << 8 ; //PA2 en TX = AF7
GPIOA->AFR[0] |= GPIO_AF_USART2 << 12 ; //PA3 en RX = AF7
// Pour réduire le bruit sur l'alimentation
SYSCFG->CMPCR |= SYSCFG_CMPCR_CMP_PD;
// Par default la configuration est 8N1
USART2->CR1 |= USART_CR1_RE | USART_CR1_TE;
// Active RX et TX
setBaudRate(9600);
// Active l'interruption pour USART2
NVIC_EnableIRQ(USART2_IRQn);
// Interruption de tx activée sur transmission
USART2->CR1 |= USART_CR1_RXNEIE;
USART2->CR1 |= USART_CR1_UE; // USART activé
}

Le calcul de la vitesse de transmission (baudrate) utilise la vitesse de l’horloge (ici 180MHz) afin de déterminer la valeur du registre BRR. Notez que pour les vitesse au delà de 2.8Mbps, il sera nécessaire de diminuer le sur-échantillonnent de 16 à 8.

void STM32F446RE_USART2::setBaudRate(uint32_t baudrate) 
{
USART2->BRR = (SystemCoreClock>>2) / baudrate;
}

La méthode getInstance appel le constructeur si l’instance n’est pas déjà créée, puis elle retourne l’adresse de l’instance.

STM32F446RE_USART2* STM32F446RE_USART2::getInstance() 
{
if (instance == 0)
instance = new STM32F446RE_USART2();
return instance;
}

La méthode dataAvailable retourne vrai lorsqu’il y a des données dans le tampon de réception.

bool STM32F446RE_USART2::dataAvailable() const
{
return !rxBuffer.isEmpty();
}

La méthode read retourne simplement un octet retiré de rxBuffer. BufferTemplate gère déjà les demandes lorsque la file est vide et retourne le dernier élément.

uint8_t STM32F446RE_USART2::read()
{
return rxBuffer.rem();
}

La méthode write reçoit un octet à transmettre. Elle ajoute donc l’octet au tampon de transmission et si le USART2 ne transmettait pas déjà, il active l’interruption pour le registre de transmission vide.

void STM32F446RE_USART2::write(uint8_t data)
{
txBuffer.add(data);
if(!isTransmitting)
{
isTransmitting = true;
USART2->CR1 |= USART_CR1_TXEIE; // active l'interruption.
}
}

Finalement, le gestionnaire d’interruption pour le USART2 traite la réception et la transmission des octets. Le fait qu’il soit ami avec USART2 lui permet un accès plus direct et donc plus rapide vers les tampons. Notez que pour améliorer les performances, vous pourriez utiliser des tableaux de données plutôt que la classe BufferTemplate, ou encore la DMA selon l’application visée.

extern "C" 
{
void USART2_IRQHandler(void)
{
volatile unsigned int isr;
isr = USART2->SR;
// RX Data
if (isr & USART_SR_RXNE)
{
USART2->SR &= ~USART_SR_RXNE;
STM32F446RE_USART2::instance->rxBuffer.add(USART2->DR);
}
// TX Done
if ((isr & USART_SR_TXE))
{
USART2->SR &= ~USART_SR_TXE;
if(STM32F446RE_USART2::instance->txBuffer.isEmpty())
{
STM32F446RE_USART2::instance->isTransmitting = false;
USART2->CR1 &= (~USART_CR1_TXEIE);
}
else
{
USART2->DR = STM32F446RE_USART2::instance->txBuffer.rem();
STM32F446RE_USART2::instance->isTransmitting = true;
}
}
}
}

Documents


System Workbench (STM32)

ST supporte officiellement 3 IDE:

Plusieurs autres IDE sont disponibles, dont celle de Atollic (maintenant propriété de ST) mais je recommande d’utiliser System Workbench car c’est celui priorisé par ST et il est gratuit. Keil a une version gratuite limitée et IAR n’est commercial.

Installation

Pour télécharger System Workbench , allez sur le site OpenSTM32. Vous devez créer un compte (c’est gratuit) et ensuite télécharger l’installeur qui convient à votre système d’exploitation.


AVR SPI avec un Arduino UNO

Cet article explique comment utiliser le port SPI présent sur le Atmega328p du Arduino UNO.

Dans cet article, nous utiliserons une boucle pour l’écriture. Cette méthode est simple mais elle limite les performances du microcontrôleur. Je ferai un autre article qui expliquera comment faire cette opération en interruption, ce qui est recommandé afin de libérer le programme principal.

Étape 1 : Initialisation du port SPI

Le port SPI utilise 3 liens pour transmettre et recevoir les données en plus d’un signal pour sélectionner l’esclave visé.

Signal Broche (port) Description
SCLK 13 (PB5) Horloge
MISO 12 (PB4) Données de l’esclave vers le maître
MOSI 11 (PB3) Données du maître vers l’esclave
CS 10 (PB2) Sélection de l’esclave

Les signaux SCLK, MOSI, CS sont donc des sorties pour l’Arduino et le signal MISO est une entrée. La ligne suivante configure les broches requises en sorties.

DDRB |= (1<<2) | (1<<3) | (1<<5) ;

La configuration par défaut correspond à la majorité des situations.  L’horloge principale est divisée par 4 (ce qui donne 4Mhz pour le Arduino UNO), le signal SCLK est à 0 lorsque le SPI est inactif, les données débutent par le MSB. Le registre de contrôle est le SPCR.

La ligne suivante active le SPI et place le SPI en mode maître :

SPCR = (1<<SPE) | (1<<MSTR);

Étape 2 : Utilisation du port SPI 

Après son initialisation, le port SPI est prêt pour envoyer des données. Avant toute communication, il faut sélectionner l’esclave en abaissant le signal CS correspondant. Il suffit ensuite d’écrire dans le registre SPDR l’octet à transmettre. Après chaque écriture, il faut lire le bit d’état SPIF du registre d’état SPSR. Ce dernier devient 1 lorsque la transmission est terminée. Voici une fonction d’écriture qui regroupe ces lignes :

uint8_t spiWrite(uint8_t data)
{
  SPDR = data;
  while(!(SPSR & (1<<SPIF)));
  return SPDR;
}

La fonction retourne le contenu de SPDR, qui contient alors l’octet reçu via le lien MISO simultanément à l’écriture sur MOSI.

Voici un exemple de code qui initialise le port SPI puis envoie 0x40 suivi de 0x05 vers un esclave.

// Dans cet exemple, CS est sur le bit 2 du port B
// Initialisation du SPI
DDRB |= (1<<2) | (1<<3) | (1<<5) ; 
SPCR = (1<<SPE) | (1<<MSTR);
// Transmission vers un esclave
PORTB &= ~(1<<2);   // mise à zéro de CS
spiWrite(0x40);
spiWrite(0x05);
PORTB |= (1<<2);   // mise à un de CS

 


Comment utiliser le port série virtuel du Nucléo

Lorsque le Nucléo est relié au PC à l’aide du port USB, il créé un port série virtuel qui permet d’échanger des données (ou messages). Pour voir le nom du port série dans Windows, il suffit d’aller dans Périphériques et imprimantes. Vous verrez alors un périphérique du nom de STM32 STlink.

Dans les propriétés de ce périphérique, vous verrez l’ensemble des fonctions de ce dernier, dont Virtual COM Port. Sur mon ordinateur, il apparaît sur le COM6.

Comme pour le Arduino, c’est le UART qui est relié à D0 et D1 qui est utilisé. Dans le cas du Nucléo F446RE, c’est le UART2 avec les pins A2 et A3 qu’il faut utiliser.

Pour utiliser des périphériques du microcontrôleur, il faut d’abord activer l’horloge. Nous allons donc débuter par activer l’horloge sur UART2 et le port A.

 /* Active le clock sur UART2 et GPIOA */
 RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

Ensuite, nous allons configurer A2 et A3 qui sont respectivement TX et RX pour le UART2. Cette assignation est une fonction alternative de A2 et A3. Nous allons donc spécifier qu’ils utilisent une fonction alternative (AF) puis nous allons spécifier que la fonction alternative est UART2.

  /* Configuration des GPIO*/
 GPIO_InitTypeDef GPIO_InitStructure;
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3; 
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
 GPIO_Init(GPIOA, &GPIO_InitStructure);
 GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);
 GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2);

La prochaine étape consiste à configurer UART2. Dans cette exemple, la configuration sera 115200 bauds, 8 bits de données, aucune parité et 1 stop bit. La dernière ligne active le UART2.

 /* Configuration du UART2 */
 USART_InitTypeDef USART_InitStructure;
 USART_InitStructure.USART_BaudRate = 115200;
 USART_InitStructure.USART_WordLength = USART_WordLength_8b;
 USART_InitStructure.USART_StopBits = USART_StopBits_1;
 USART_InitStructure.USART_Parity = USART_Parity_No;
 USART_InitStructure.USART_HardwareFlowControl =          USART_HardwareFlowControl_None;
 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
 USART_Init(USART2, &USART_InitStructure);
 USART_Cmd(USART2, ENABLE);

Afin de vérifier le fonctionnement du programme, voici une fonction qui affiche envoie une chaîne de caractères. La boucle vérifie que le caractère courant est différent de zéro (le caractère de fin). Elle attend ensuite que le transmetteur soit libre, puis elle envoie un caractère et repositionne le curseur pour le prochain caractère.

void uart2Puts(char *s)
{
 while(*s)
 {
 while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
 USART_SendData(USART2, *s++);
 }
}

Le programme suivant envoie le message « Bonjour le mode » puis il retourne en écho les caractères qu’il reçoit. La fonction uart2Init() regroupe l’ensemble du code d’initialisation présenté au début de cet article.

int main(void)
{
 uart2Init();
 uart2Puts("Bonjour le monde \r\n");
 while(1) // Faire un écho à l'infini
 {
   uint16_t rxData;
   while(USART_GetFlagStatus(USART2, USART_FLAG_RXNE) == RESET);
   rxData = USART_ReceiveData(USART2);
   while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
   USART_SendData(USART2, rxData);
 }
}

AVR USART avec un Arduino UNO

Cet article explique comment utiliser le lien série asynchrone (lire USART) présent sur le Atmega328p du Arduino UNO.

Dans cet article, nous utiliserons une boucle pour la transmission et la réception des octets. Je ferai un autre article qui expliquera comment faire avec les interruptions, ce qui est recommandé afin de libérer le programme principal.

Étape 1 : Initialisation du USART

Il faut d’abord établir les paramètres du port série. Dans le cas présent, nous allons configurer le port pour une des configurations les plus communes.

Vitesse 9600 bauds
Longueur des données 8 bits
Parité Aucune
Nombre de bit STOP 1

Les explications détaillées des registres utiles du Atmega328p sont disponibles dans la feuille de spécification suivante : ATMEGA328P

Le premier registre que nous allons configurer est en fait deux registres. C’est le UBRR qui est séparé en deux parties UBRR0L et UBRR0H. Ce registre configure la vitesse du port série. La valeur de UBRR dépend donc de l’horloge du microcontrôleur et la vitesse désirée. Dans notre cas, puisque nous utilisons le mode normal du USART. L’équation qui permet de déterminer UBRR est :

Screenshot_7

Où fosc est la fréquence d’opération du CPU et BAUD est la vitesse désirée.

Pour établir cet valeur, il est possible de calculer la valeur et d’utiliser un define ou vous pouvez utiliser une macro qui calculera automatiquement la valeur en fonction des paramètres. Dans le premier cas, avec nos paramètres le résultat serait 103 (le CPU du Arduino utilise un cristal externe de 16MHz). Cependant, je recommande plutôt la seconde manière, plus facile à maintenir. Voici le code de la macro en question :

#define BAUD_PRESCALE(fcpu,br) ((fcpu / 16 / br) - 1)

Les 8 bits les moins significatifs sont dans le registre UBBR0L et les 4 derniers bits dans UBBRoH. Voici la représentation des registres en question:

Screenshot_6

Pour UBRR0H, il faut simplement utiliser un décalage comme ceci :

 UBRR0H = (BAUD_PRESCALE(F_CPU,baudRate) >> 8); 
 UBRR0L = BAUD_PRESCALE(F_CPU,baudRate);

Un autre registre d’intérêt est le UCSR0C, qui permet de configurer le nombre de bits des données, le bit de polarité ainsi que le nombre de bits STOP.

Screenshot_8

UMSEL Détermine le mode du port
00 est le mode asynchrone
UPM Détermine la parité
00 est aucune parité
USBS Détermine le nombre de bit STOP
0 est 1 bit
UCSZ Est la longueur des données
011 est 8bits. (valeur par défaut)
Notez que UCSZ2 est dans un autre registre

Voici donc le code qui permet de configurer le registre selon la configuration désirée :

UCSR0C = (1<<UCSZ00)|(1<<UCSZ01);

Le dernier registre à configurer sera le UCSR0B, qui active les éléments du port série. Il contient également le dernier bit pour la configuration de la longueur des données (UCSZ2).

Screenshot_9

RXCIE Active l’interruption de fin de réception d’une donnée. Pas utilisé dans cet article.
TXCIE Active l’interruption de fin de transmission d’une donnée. Pas utilisé dans cet article.
RXEN Active la réception de donnée
TXEN Active la transmission de donnée

Voici donc le code de la fonction uartInit au complet (F_CPU est un define utilisé par la librairie delay.h. Il vaut 16000000UL dans le cas présent) :

void usartInit(uint32_t baudRate)
{
 UBRR0L = BAUD_PRESCALE(F_CPU,baudRate);
 UBRR0H = (BAUD_PRESCALE(F_CPU,baudRate) >> 8); 
 UCSR0B = ((1<<TXEN0)|(1<<RXEN0);
 UCSR0C = (1<<UCSZ00)|(1<<UCSZ01);
}

Étape 2 : Envoyer une donnée

Envoyer une donnée est simple, il suffit d’écrire dans le registre UDR0 et la transmission débute automatiquement si la transmission est activée dans le registre UCSR0B. Avant d’écrire, il faut cependant s’assurer que le registre est vide, avec le bit UDRE0 du registre UCSR0A. Voici à quoi peut ressembler la fonction de transmission d’une donnée.

void usartSendByte(uint8_t data)
{
 while((UCSR0A & (1<<UDRE0)) == 0);
 UDR0 = data;
}

Étape 3 : Réception d’une donnée

Pour lire une donnée reçue, il suffit de lire le registre UDR0. Cependant, pour s’assurer que le contenu est bien une donnée reçue, il faut vérifier que le bit RXC0 est activé dans le registre UCSR0A. Pour éviter que le programme se bloque, il est préférable d’utiliser une fonction qui valide la présence d’une donnée avant de lancer la lecture.  Voici les deux fonctions recommandées pour cette étape :

bool usartDataAvailable()
{
 return (UCSR0A & (1<<RXC0));
}

uint8_t usartGetRxByte()
{
 // Option pour attendre la réception d'une donnée... risque de blocage
 // while (!usartDataAvailable());
 return UDR0;
}

Finalement, il restera à vérifier que l’on peut recevoir et envoyer des données à l’aide des fonctions. Je vous recommande HTerm  pour vérifier votre programme.

Voici un petit programme qui utilise les fonctions précédentes et valide le fonctionnement. Les fonctions sont mises dans un fichier usart.cpp et les déclarations de fonctions dans usart.h.

#include <avr/io.h>
  #ifndef F_CPU
    #define F_CPU 16000000UL
  #endif
#include <util/delay.h>
#include "usart.h"

void main(void)
{
  usartInit(19200);
  while(1)
  {
    if(usartDataAvailable())
      data = usartGetRxByte();
    usartSendByte(data);
    _delay_ms(1000);
  }
}

 

 


AVR ADC avec un Arduino UNO

Cet article explique comment utiliser le convertisseur analogique à numérique (ADC) présent sur le Atmega328p du Arduino UNO.

Dans cet article, nous utiliserons une boucle pour la lecture d’un canal. Je ferai un autre article qui expliquera comment faire cette lecture en interruption, ce qui est recommandé afin de libérer le programme principal.

Étape 1 : Initialisation du ADC

Dans l’initialisation, nous devons configurer le registre ADCSRA.

Screenshot_2

Le bit ADEN active le ADC alors que les bits ADPS0-ADPS3 sélectionnent la division de l’horloge du système qui établira la vitesse de l’horloge du ADC. Ce qui est important, c’est que l’horloge de l’ADC ne dépasse pas 200KHz lorsque les 10 bits de résolution sont nécessaires. Puisque nous avons une horloge de 16MHz sur le Arduino UNO, nous devons diviser par 80 ou plus. Selon la table 24-5 du datasheet, nous devrons donc utiliser le facteur de division 128.

Screenshot_3

Nous devons également configurer le registre ADMUX qui sélectionne la tension de référence utilisée par l’ADC.

Screenshot_3

Puisque la broche AREF du Arduino UNO n’est pas reliée, nous allons utiliser AVcc comme référence. La table 24-3 montre que le bit REFS0 doit être activé.

Screenshot_2

Voici à quoi le code de la fonction adcInit devrait ressembler :

void adcInit()
{
 ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) |(1<<ADPS0) ;
 ADMUX =  (1<<REFS0);
}

Étape 2 : Sélection du canal

Le Atmega328P utilisé par le Arduino UNO possède 6 canaux sur son ADC. Lorsqu’il n’y a qu’un canal utilisé, vous devez sélectionner le canal une seule fois. Sinon, vous devez sélectionner le bon canal avant chaque conversion. La sélection du canal s’effectue via le registre ADMUX avec les bits MUX3 à MUX0.

Screenshot_4

Voici à quoi la fonction adcSetCh devrait ressembler :

void adcSetCh(uint8_t ch)
{
 ADMUX &= 0xF0; 
 ADMUX |= (ch & 0x0F);
}

Étape 3 : Lecture de l’ADC dans une boucle

Il faut maintenant démarrer l’ADC. Cette opération s’effectue à l’aide du bit ADSC du registre ADCSRA. Lorsque ce bit est mis à 1, une conversion démarre. Le bit retourne à zéro lorsque la conversion est terminée.

Voici à quoi le code de la fonction adcRead devrait ressembler :

uint16_t adcRead(uint8_t ch)
{
 ADCSRA |= (1<<ADSC);
 while (ADCSRA & (1<<ADSC)); 
 return ADCW;
}

Exemple d’utilisation de l’ADC

Dans cet exemple, un potentiomètre est relié au canal 0 de l’ADC selon l’image suivante.

20171012_194317[1]

Le code fait la lecture de la broche aux 100ms puis il affiche le résultat sur le port série.

#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <stdlib.h>
#include "usart.h"
#include "adc.h"

uint16_t adcVal = 0;

int main(void)
{
  char strVal[6] = {0};
  usartInit(19200);
  adcInit();
  while (1) 
  {
    adcVal = adcRead(0);
    itoa(adcVal,strVal,10);
    usartSendStr(strVal);
    usartSendStr("\n\r");
    _delay_ms(100);
  }
}

Et voici le résultat observé, en variant de 0V à 5V le potentiomètre.

Screenshot_5


Utiliser AVRDUDE dans AVR Studio

Dans cet article, vous verrez comment télécharger votre programme dans votre Arduino sans utiliser de programmeur externe.

Une version vidéo de cette article est disponible sur mon canal Youtube à https://youtu.be/HB7oB3Bfg4k.

Les cartes Arduino sont livrées avec ce qu’on appel un bootloader. Il s’agit d’un petit programme qui demeure dans votre microcontrôleur et qui permet de charger le fichier hex via un port de communication. Dans le car du Arduino, il utilise le port série qui est relié au port USB de la carte.

La première étape consiste à ouvrir Arduino IDE et de charger un exemple simple, puis de le télécharger sur la carte. Après le chargement, trouvez dans la liste des commandes celles qui réfère à Avrdude.

etape1

Copiez ensuite la ligne complète dans un éditeur de texte.

Séparez la commande en deux partie.

Partie 1 (Commande)

C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avrdude

Vous devez ajouter .exe à la fin de cette commande, ce qui vous donnera ceci :

C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avrdude.exe

Partie 2 (Arguments)

-CC:\Program Files (x86)\Arduino\hardware\tools\avr/etc/avrdude.conf -v -patmega328p -carduino -PCOM47 -b115200 -D -Uflash:w:C:\Users\MARC~1.JUN\AppData\Local\Temp\arduino_build_327788/Blink.ino.hex:i

La première partie des arguments donne le chemin vers le fichier de configuration d’Avrdude. Vous devez ajouter des «  » à cette partie.

Ensuite, il faut modifier l’argument du port comme suit :
-PCOM47 deviendra -P\\.\COM47

Finalement, il faudra remplacer le chemin du fichier hex pour celui de votre projet. Sous AVR Studio, il y a des constantes de path qui simplifient cette tâche. L’argument « $(ProjectDir)Debug\$(TargetName).hex » pointera sur le hex de votre projet à moins que vous aillez changer ce chemin manuellement.

La ligne d’arguments devrait donc ressembler à ceci :

-C »C:\Program Files (x86)\Arduino\hardware\tools\avr/etc/avrdude.conf » -v -patmega328p -carduino -P\\.\COM47 -b115200 -D -Uflash:w: »$(ProjectDir)Debug\$(TargetName).hex »:i

Maintenant, ouvrez un nouveau projet dans AVR Studio pour le Atmega328p.

etape2

 

etape3

Faites un petit programme qui fait clignoter le LED du Arduino. Dans le cas du UNO Rev3 c’est PB5 qui contrôle la LED.
(Voici le schéma : Arduino_Uno_Rev3-schematic)

etape4

Compilez et vérifiez qu’il n’y a pas d’erreur.

etape7

Ajoutez AVRDude comme outil externe.

etape5

Copiez la ligne de commande et la ligne d’argument puis cliquez sur Apply.

epate6

Retournez dans le menu Tools et sélectionnez AVRDUDE.

etape8

Notez que vous pourriez avoir à changer l’argument du port si jamais ce dernier venait à changer lors d’une prochaine connexion du câble USB.


STM32 Nucleo F446RE : Blink de base

Comme premier code, nous allons commuter la LED2 du Nucleo afin de mesurer la performance des librairies.

Lors des tests, l’onde carré observée était d’environ 2.4MHz. Ce n’est pas la méthode la plus rapide, car les fonctions utilisées pour le changement d’état de la LED2 présentent une surcharge notable.

#include "stm32f4xx.h"
#include "system_stm32f4xx.h"
#include "stm32f4xx_hal_gpio.h"
#include "stm32f4xx_hal_rcc.h"

GPIO_InitTypeDef GPIO_InitStructure;

void main(void)
{
  HAL_Init();
  __GPIOA_CLK_ENABLE();
  GPIO_InitStructure.Pin = GPIO_PIN_5;
  GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStructure.Pull = GPIO_PULLUP;
  GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);

  while (1)
  {
     HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
     HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
  }
}