Basée sur STM32CubeMX et keil, la communication SPI est utilisée pour implémenter le mode d'interrogation pour lire et écrire W25Q128 afin d'obtenir l'ID de l'appareil.

Préface

Récemment, la communication a été beaucoup utilisée, notamment UART, I2C, SPI, DMA, etc. Ce blog explique principalement le SPI utilisé dans les projets récents et le combine avec la puce Puzhong STM32F407ZET6 et la puce W25Q128 et les circuits de modules correspondants.
Il explique principalement les principes et processus de base de la communication SPI, le diagramme schématique du W325Q128 et la lecture du manuel de la puce.


1. Communication SPI

1.1 Interface matérielle et câblage SPI

La communication SPI utilise généralement quatre interfaces, qui sont MOSI,MISO,CLK,NSS
MOSI: :sortie maître, entrée esclaveEntrée esclave de sortie maître, signal de sortie de l'appareil maître/signal d'entrée de l'appareil esclave, le signal sur l'appareil esclave est généralement abrégé en SI. MOSI est la sortie de données série du périphérique maître, SI est l'entrée de données série du périphérique esclave, et les deux signaux du périphérique maître et du périphérique esclave sont connectés.

MISOentrée maître, sortie esclave. Entrée maître sortie esclave, signal d'entrée de l'appareil maître/signal de sortie de l'appareil esclave, le signal sur l'appareil esclave est généralement abrégé en SO. MISO est l'entrée de données série du périphérique maître, SO est la sortie de données série du périphérique esclave, et les deux signaux du périphérique maître et du périphérique esclave sont liés.
CLK:horloge. L'horloge est donnée par le maître en communication SPI, et l'esclave n'a pas de CLK.
NSS:Sélection de puce. Dans la communication SPI, dans le cas d'un maître et de plusieurs esclaves, d'une manière générale, ce n'est que lorsque la broche de sélection de la puce est réglée au niveau bas que l'esclave correspondant est valide. Certains jetons sont actifs à un niveau élevé.

Le schéma de connexion pour un maître et plusieurs esclaves est à peu près le suivant :

Insérer la description de l'image ici

1.2 Protocole de transmission SPI

La communication SPI effectue une transmission série pilotée par CLK. Le protocole de transmission SPI définit le signal de début, le signal de fin, la validité des données et la synchronisation de l'horloge SPI.
La longueur de la trame de données de chaque transmission SPI est de 8 bits ou 16 bits.
Il existe quatre modes de synchronisation pour la communication SPI. Les quatre modes de synchronisation sont liés aux deux paramètres CPOL et CPHA. La première est la polarité de l'horloge (Clock Polarity) et la seconde est la phase de l'horloge (Clock Phase).

CPOL:Polarité de l'horloge. Le niveau lorsque l’horloge est au repos. Si CPOL=0, CLK est au niveau bas au repos ; si CPOL=1, CLK est au niveau haut au repos.
CPHA:phase d'horloge. Si CPHA=0, les données sont échantillonnées sur le premier bord de SCK ; si CPHA-1, les données sont échantillonnées sur le deuxième bord de SCK.

Les quatre modes de synchronisation sont visibles dans le tableau suivant :

Mode chronométrage CPOL LAVER illustrer
0 0 0 L'horloge inactive est faible et les premières données de front de transition de SCK sont échantillonnées.
1 0 1 L'horloge inactive est faible et les données du deuxième front de transition du SCK sont échantillonnées.
2 1 0 L'horloge inactive est élevée et les premières données de front de transition de SCK sont échantillonnées.
3 1 1 L'horloge inactive est élevée et les données du deuxième front de transition du SCK sont échantillonnées.

La figure ci-dessous montre le chronogramme correspondant à CPHA=0, CPOL=1 et CPOL=0. Si vous comprenez cela, vous devriez connaître le principe du SPI.
Insérer la description de l'image ici

Soyez particulièrement attentif lorsque vous utilisez la communication SPI.La synchronisation SPI des appareils maître et esclave doit être cohérente.En fait, cela est similaire à la méthode d'analyse des données maître-esclave. Si mon maître transmet en mode de synchronisation 0 et que l'esclave reçoit en mode de synchronisation 3, alors les données reçues par l'esclave seront incohérentes avec les données envoyées par le maître. Portez une attention particulière à cela.


1.3 Transmission de données SPI

Il existe trois manières de transmettre des données via SPI : le blocage, l'interruption et le DMA.
Présentons brièvement chacun séparément. Ce blog utilisera l'envoi de blocage le plus simple pour vérification.
1. Type de blocage.
Généralement, la fonction utilisée dans l'envoi de type de blocage est :HAL_SPI_Transmit() , cette fonction signifie que le type de blocage envoie des données dans un tampon.
La définition complète est la suivante :
HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)

Généralement, la fonction utilisée pour bloquer la réception est : HAL_SPI_Receive(), cette fonction signifie bloquer la réception de données d'une longueur spécifiée et les enregistrer dans le tampon.
La définition complète est la suivante :
HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)

La signification des quatre paramètres formels des fonctions d'envoi et de réception :

hspiIl s'agit du pointeur d'objet périphérique SPI, indiquant quel pointeur SPI est utilisé.
pDataLe pointeur représentant le tampon de données envoyées/reçues
Sizeindique la longueur des données du tampon envoyé/reçu
Timeoutet indique le temps d'attente. L'unité est le nombre de battements du signal de tick du système. Par défaut, il s'agit de ms.

En plus des fonctions d'envoi et de réception distinctes ci-dessus, il existe également une fonction d'envoi et de réception intégrée HAL_SPI_TransmitReceive(). Cette fonction représente une méthode de blocage pour l'envoi et la réception de données d'une certaine longueur en même temps.
La définition complète est la suivante :
HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size,uint32_t Timeout)

Les significations de plusieurs paramètres de cette fonction sont similaires à celles ci-dessus, mais les pointeurs d'envoi et de réception de données sont séparés, c'est-à-dire qu'un pointeur d'envoi et de réception est transformé en pointeur d'envoi et en pointeur de réception.
Divisez pData en pTxData et pRxData. Je n'expliquerai pas les autres paramètres ici.


2.
Type d'interruption Correspondant au type de blocage ci-dessus, il existe trois fonctions pour l'envoi et la réception de données de type interruption. Ce sont : HAL_SPI_Transmit_IT(), , HAL_SPI_Receive_IT()et HAL_SPI_TransmitReceive_IT()
la définition complète est la suivante :

HAL_StatusTypeDef HAL_SPI_Transmit_IT (SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t taille)
HAL_StatusTypeDef HAL_SPI_Receive_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t taille) HAL_StatusTypeDef HAL_SPI_TransmitReceive _IT (SPI_HandleTypeDef
*hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t taille)

Nous comparons les envois bloquants et constatons que leurs paramètres sont en fait les mêmes, sauf qu'il manque un paramètre de délai d'attente. Je n’expliquerai donc pas les parties communes. La différence est qu'il y a un IT après le nom de la fonction, qui signifie Interruption.
Ces trois fonctions représentent toutes l'envoi/réception de données de manière interruption, et les événements d'interruption seront générés une fois leur exécution terminée.
Le mode d'envoi d'interruption générera SPI_IT_TXE et la fonction de rappel sera appelée : HAL_SPI_TxCpltCallback()
Le mode de réception d'interruption générera SPI_IT_RXNE et la fonction de rappel sera appelée : HAL_SPI_RxCpltCallback()
Le mode d'envoi et de réception d'interruption générera SPI_IT_TXE, SPI_IT_RXNE et la fonction de rappel sera appelé:HAL_SPI_TxRxCpltCallback()

Concernant les fonctions de rappel et autres, elles sont en fait similaires à mon blog sur les interruptions externes et ne seront pas détaillées ici.


3. Le type DMA
DMA a trois fonctions pour l'envoi et la réception de données,
à savoir : HAL_SPI_Transmit_DMA(), HAL_SPI_Receive_DMA(), et HAL_SPI_TransmitReceive_DMA()
la définition complète est la suivante :

HAL_StatusTypeDef HAL_SPI_Transmit_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Taille)
HAL_StatusTypeDef HAL_SPI_Receive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Taille) HAL_StatusTypeDef HAL_SPI_TransmitRe ceive_DMA (SPI_HandleTypeDef *hspi,
uint8_t *pTxData, uint8_t *pRxData, uint16_t taille)

DMA générera également des interruptions, mais il existe deux types d'interruptions, à savoir le transfert terminé et le transfert à moitié terminé.

Fonction du mode DMA fonction fonction Événement d'interruption de flux DMA Fonction de rappel correspondante
HAL_SPI_Transmit_DMA Envoyer des données en mode DMA Transfert DMA terminé/transfert DMA à moitié terminé HAL_SPI_TxCpltCallback() /HAL_SPI_TxHalfCpltCallback()
HAL_SPI_Receive_DMA Envoyer des données en mode DMA Transfert DMA terminé/transfert DMA à moitié terminé HAL_SPI_TxCpltCallback() /HAL_SPI_TxHalfCpltCallback()
HAL_SPI_TransmitReceive_DMA Envoyer/recevoir des données en mode DMA Transfert DMA terminé/transfert DMA à moitié terminé HAL_SPI_TxRxCpltCallback() /HAL_SPI_TxRxHalfCpltCallback()

2. W25Q128

J'ai vu de nombreuses cartes de développement STM32, et elles utilisent toutes cette puce comme exemple de puce pour la communication SPI. La configuration de base et les principes de la communication SPI ne sont pas difficiles. Lorsque j'ai commencé à apprendre, j'ai trouvé cela difficile. Il est très probable que vous ayez besoin de lire le manuel de la puce pour communiquer avec la puce que vous utilisez. Dans cette section, je vais écrivez sur l'utilisation de la puce pour la communication SPI. Lisez le manuel détaillé de la puce. J'écrirai un article et le publierai plus tard.

2.1 Sélection des films

Notre SPI dispose de broches de transmission de données, d'horloges et de sélections de puces.
Généralement, le signal de sélection de la puce de signal est tiré vers le bas pour être valide, comme le montre l'introduction dans le manuel de la puce et le diagramme de synchronisation.
L'image ci-dessous est le schéma de principe de la partie W25Q128 de la carte de développement Puzhong F407ZET6. Nous pouvons voir que la sélection de puce/CS est active à bas niveau. Il y a une barre dessus, ce qui signifie qu'il est actif à faible niveau.

Insérer la description de l'image ici
Ce qui suit est une introduction de base à la sélection des puces tirée du manuel des puces.
Insérer la description de l'image ici

Traduisez l'élément clé en mots humains :
/CS est tiré vers le haut, indiquant que le périphérique n'est pas sélectionné et que la broche de sortie série est dans un état à haute impédance. Lorsqu'elle n'est pas sélectionnée, la puce est en mode veille et ne fait rien d'autre que des cycles internes d'effacement, de programmation ou d'écriture du registre d'état.
/CS est abaissé et le périphérique est sélectionné. Lorsque la puce est activée, les programmeurs peuvent y écrire des instructions de contrôle et des données.

Pour parler franchement, tirer vers le bas est efficace, mais tirer vers le haut est inefficace.


2.2 Instructions de contrôle

Le but de ce blog est d'obtenir l'ID de l'appareil, nous devons donc découvrir comment obtenir l'ID de l'appareil après avoir confirmé que la sélection de puce est faible.
Consultez la fiche technique et retrouvez une partie des informations dans l'image ci-dessous.
Ce tableau nous indique que nous utilisons l'instruction de commande 90h, ce qui signifie saisir le mot de contrôle 0x90h sur la puce. Ce qui suit dummyne signifie pas stupide. Dans l'industrie électronique, cela signifie un mannequin, c'est-à-dire une unité invalide, juste pour remplir ou répondre à certaines exigences ou Pour des contraintes, nous donnons généralement juste 00h.
Insérer la description de l'image ici

Voici un rappel : après avoir donné la commande pour obtenir l'ID de l'appareil, celui-ci continuera à être envoyé jusqu'à ce que la sélection de puce soit élevée.
Insérer la description de l'image ici

Au moment où j’écris ces lignes, c’est encore un peu brumeux. Pourquoi la puce m'envoie-t-elle des données d'identification lorsque j'envoie cette commande ? Comment puis-je savoir quand la puce est envoyée et quand j'envoie les données ? Cela a quelque chose à voir avec le chronogramme. Analysons maintenant le chronogramme.

2.3 Analyse du chronogramme

Insérer la description de l'image ici

L'image ci-dessus est connectée, mais elle est superposée en raison de la largeur de la page. Afin de faciliter la visualisation, j'ai légèrement organisé les captures d'écran pour qu'elles paraissent plus complètes.
Insérer la description de l'image ici

Ce que nous avons ici est une communication SPI. Regardez d'abord la sélection de la puce, puis regardez l'horloge pour déterminer le mode, puis regardez la direction de transmission des données.

Tout d’abord, la sélection de films est réduite. Nous pouvons voir que la partie transmission de données ne se produira que lorsque la sélection de puce est abaissée. Une fois qu'elle est abaissée, toutes les transmissions de données ultérieures existeront. Cela montre que la sélection de films est efficace pour faire baisser le prix (je l'ai dit plusieurs fois, ce qui est un peu verbeux)

Ensuite, regarde l'horloge. Dans ce chronogramme, CLK a les modes Mode3 et Mode0, et les CPOL et CPHA correspondants sont tous deux 0 et 1. La relation spécifique correspondante vient d'être notée, si vous l'oubliez, merci de vous y référer. Le maître et l'esclave dans ce mode doivent être cohérents. Ici, le W25Q128 ne prend en charge que le mode 0 et le mode 3, donc son effet d'horloge est répertorié dans le chronogramme du manuel de la puce.
Nous pouvons voir que les 8 premiers cycles d'horloge sont le cycle d'instructions de contrôle, et le cycle suivant du neuvième cycle (le nombre est 8, commençant à 0) jusqu'au 32ème cycle est le cycle d'adresse d'écriture. Les cycles d'horloge suivants jusqu'à ce que /CS soit élevé n'ont en réalité rien à voir avec l'entrée de l'hôte. Le chronogramme DI est suivi de XXX, qui sont des données invalides.

Regardons à nouveau la transmission de données. Lorsque l'hôte entre des instructions dans la puce, nous examinons la ligne DI et constatons que les données sont valides et que la ligne DO est dans un état à haute impédance. Combinées avec l'horloge, les données de l'hôte sont valides pendant les 32 premiers cycles d'horloge et invalides par la suite. Au début du cycle d'horloge 33, les données dans DI deviennent XXXX, ce qui n'est pas valide. À ce moment, les données sur la ligne DO sont valides, indiquant que la puce envoie des données à l'hôte. Et continuez à envoyer jusqu'à ce que la sélection de puce atteigne un niveau élevé.
La transmission continue des données ici est en fait introduite dans le manuel de la puce, xxxx peut être lu en continu.
En même temps, si notre adresse est partiellement 01, le résultat est d'abord l'ID de l'appareil, puis l'ID du fabricant, nous n'en discuterons donc pas trop ici.

Insérer la description de l'image ici


3.Configuration STM32CubeMX

3.1 Configuration des broches

Jetez un oeil au schéma de câblage
Insérer la description de l'image ici
Insérer la description de l'image ici

Insérer la description de l'image ici

Combiné avec le diagramme schématique, nous le configurons.

Insérer la description de l'image ici
Insérer la description de l'image ici

3.2 Configuration de l'horloge

Allumez l'oscillateur à cristal externe. J'ai déjà écrit qu'il n'est pas nécessaire de l'allumer. Tant que la fréquence souhaitée répond aux exigences requises et peut être obtenue par division de fréquence de l'oscillateur à cristal interne, vous n'avez pas besoin de Allumez l'oscillateur à cristal externe. Je l'allume habituellement, et cela n'affectera rien.
Insérer la description de l'image iciSPI1 est sur le bus APB2, donc le débit en bauds de la communication SPI est en fait calculé en fonction de la fréquence de PCLK2.
Insérer la description de l'image ici

3.3 Configuration SPI

Insérer la description de l'image ici

Expliquez la signification de ce champ :
Mode:mode de travail. Lorsque STM32 est utilisé comme hôte, il sélectionne généralement l'hôte full-duplex et l'esclave full-duplex. Le duplex intégral signifie que les lignes MISO et MOSI peuvent être utilisées pour recevoir et envoyer en même temps. Il existe également le mode semi-duplex, qui utilise une seule ligne de données pour envoyer et recevoir, mais ne peut avoir qu'une seule fonction à la fois.
Hardware NSS Signal:Signal matériel NSS. Il existe trois options : Désactiver signifie ne pas utiliser le signal matériel NSS ; Signal d'entrée matériel Nss signifie signal d'entrée matériel NSS. Sélectionnez cette option lorsque l'esclave SPI utilise le signal matériel NSS. Le signal de sortie Hardware Nss indique le signal de sortie matériel NSS. Sélectionnez ceci lorsque l'hôte SPI émet une sélection de puce. Cependant, nous utilisons un GPIO distinct comme signal de sélection de puce esclave, il est donc défini sur Désactiver ici.
Frame Format:Format du cadre. Il existe deux options : Motorola et TI. Mais généralement seul Motorola peut être sélectionné. Ce paramètre correspond au bit FRF du registre de contrôle SPI_CR2.
Data Size:Taille des données. Le nombre de bits dans la trame de données, 8/16 bits en option.
First Bit:Bits préférés pour la transmission. MSB First ou LSB First en option.
Prescaler(for Baud Rate):Coefficient de pré-échelle utilisé pour générer le débit en bauds. Prenez simplement la fréquence du bus de l'APBx correspondant à ce SPI et divisez-la par ce coefficient de division de fréquence, qui est le débit en bauds. Il s'agit d'APB2, donc 50 MHz divisé par 8, donc le débit en bauds est de 6,25 Mbits/s.
Je n’expliquerai pas le CPOL et l’ACSP, j’en ai déjà parlé au début.
CRC Calculation:CRC (Contrôle de redondance cyclique). Il s'agit principalement du résultat du calcul CRC d'un octet ajouté à la fin des données transmises. Lorsqu'une erreur CRC se produit, une interruption peut être générée. S'il n'est pas utilisé, il est par défaut du
NSS Signal Type:type de signal NSS désactivé. Ce paramètre est déterminé par le résultat de la sélection du signal matériel NSS ci-dessus. Lorsque le signal matériel NSS est désactivé, l'option de ce paramètre ne peut être que logiciel, ce qui signifie que le logiciel est utilisé pour générer le signal de sortie NSS, c'est-à-dire que cet exemple utilise le signal de sortie PB14 comme signal de sélection de puce de l'esclave.


3.4 Configuration du projet

La configuration du projet varie d'une personne à l'autre, voici une référence

Insérer la description de l'image ici
Insérer la description de l'image ici


4. Écriture de codes

4.1 Fonction de lecture d'ID

Postez d'abord le code, puis expliquez-le en détail.

uint16_t Flash_ReadIDbywzy(void)
{
	uint16_t Temp = 0;
	uint8_t	byteData=0;
	uint8_t commandData=0x90;
	HAL_GPIO_WritePin(FLASH_CS_GPIO_Port, FLASH_CS_Pin, GPIO_PIN_RESET);//cs=0
	HAL_SPI_Transmit(&hspi1, &commandData, 1, 200);
	commandData=0x00;
	HAL_SPI_Transmit(&hspi1, &commandData, 1, 200);
	HAL_SPI_Transmit(&hspi1, &commandData, 1, 200);
	HAL_SPI_Transmit(&hspi1, &commandData, 1, 200);
	
	HAL_SPI_Receive(&hspi1, &byteData, 1, 200);
	Temp=byteData;
	Temp=Temp<<8;//Manufacturer ID
	
	HAL_SPI_Receive(&hspi1, &byteData, 1, 200);
	Temp|=byteData;	//Device ID
	
	HAL_GPIO_WritePin(FLASH_CS_GPIO_Port, FLASH_CS_Pin, GPIO_PIN_SET);

	return Temp;
}

Le flux du code :
définissez d'abord certaines variables pour la réception et l'envoi de données, puis le processus de communication SPI, activez la sélection de la puce et envoyez les instructions. Ce qui est envoyé ici est 0x90000000. Ensuite, commencez à lire les données, un octet de données à la fois, lire deux fois, lire Après avoir terminé les données, tirez la sélection de puce vers le haut pour terminer une transmission et renvoyer les données reçues.
Insérer la description de l'image ici

Pour la vérification du code, si vous n'avez aucun outil à portée de main (comme USB vers TTL, écran, etc.), interrompez le débogage et examinez les données.
Lorsque le point d'arrêt atteint le troisième, vous pouvez le voir en regardant la variable flashID. Les deux premiers chiffres correspondent à l'ID du fabricant et les deux derniers chiffres à l'ID de l'appareil.
Insérer la description de l'image ici
Insérer la description de l'image iciIl peut y avoir quelques bugs dans le débogage en une seule étape ici. Après avoir exécuté break pour la première fois, la valeur du flashID est FFFF. Appuyez ensuite sur RST, puis exécutez jusqu'au point d'arrêt de break, et il aura l'ID correct.

Le code principal est publié ici, et il y a certains détails que je n'écrirai pas ici, comme la définition des fonctions, l'ajout de fichiers d'en-tête, la gravure de configurations, etc. Les choses répétitives ont déjà été écrites, donc je n'entrerai pas dans les détails. ici, c'est la même chose, ça ne sert à rien d'écrire davantage.
J'ai téléchargé le code complet et l'ingénierie du projet sur les ressources correspondant au blog. A récupérer si besoin.


Résumer

Ce blog couvre tout, des principes de communication SPI à la lecture manuelle de la puce W25Q128, en passant par la lecture du chronogramme, la configuration STM32CubeMX et l'écriture de code. L'ensemble du projet est très complet et forme une boucle fermée. L’écriture est également très détaillée, je ne sais pas si elle est populaire ou non, mais je pense qu’elle est assez facile à comprendre.
Ce blog a effectivement été très long à rédiger, mais heureusement il a été très enrichissant.

Je suppose que tu aimes

Origine blog.csdn.net/Edwinwzy/article/details/131554538
conseillé
Classement