- Wat is het SPI-communicatieprotocol?
- Hoe werkt het SPI-protocol?
- Verschil tussen I2C en SPI-communicatie
- SPI met PIC16F877A met XC8 Compiler:
- Verklaring van SPI-headerbestand:
- Hoofdprogramma Toelichting:
- PIC simuleren met SPI-debugger:
PIC-microcontrollers zijn een krachtig platform dat wordt geleverd door microchip voor ingebedde projecten; zijn veelzijdige karakter heeft het mogelijk gemaakt om manieren te vinden voor veel toepassingen en er moet nog veel groeien. Als je onze PIC-tutorials hebt gevolgd, zou je hebben gemerkt dat we al een breed scala aan tutorials over PIC-microcontrollers hebben behandeld, beginnend bij de basis. In dezelfde stroom gaan we verder met het leren van de communicatieprotocollen die beschikbaar zijn met PIC en hoe deze te gebruiken. We hebben I2C al gedekt met PIC Microcontroller.
In het enorme systeem van embedded applicaties kan geen enkele microcontroller alle activiteiten zelf uitvoeren. Op een bepaald moment moet het communiceren met andere apparaten om informatie te delen, er zijn veel verschillende soorten communicatieprotocollen om deze informatie te delen, maar de meest gebruikte zijn USART, IIC, SPI en CAN. Elk communicatieprotocol heeft zijn eigen voor- en nadeel. Laten we ons voorlopig concentreren op het SPI-protocol, want dat is wat we in deze tutorial gaan leren.
Wat is het SPI-communicatieprotocol?
De term SPI staat voor " Serial Peripheral Interface ". Het is een algemeen communicatieprotocol dat wordt gebruikt om gegevens tussen twee microcontrollers te verzenden of om gegevens van een sensor naar een microcontroller te lezen / schrijven. Het wordt ook gebruikt om te communiceren met SD-kaarten, schuifregisters, displaycontrollers en nog veel meer.
Hoe werkt het SPI-protocol?
De SPI-communicatie is synchrone communicatie, wat betekent dat het werkt met behulp van een kloksignaal dat wordt gedeeld tussen de twee apparaten die de gegevens uitwisselen. Het is ook een full-duplex communicatie omdat het gegevens kan verzenden en ontvangen via een aparte bus. De SPI-communicatie vereist 5 draden om te werken. Een eenvoudig SPI-communicatiecircuit tussen een master en slave wordt hieronder weergegeven
De vijf draden die nodig zijn voor de communicatie zijn SCK (Serial Clock), MOSI (Master Out Slave In), MISO (Master In Slave Out) en SS (Slave Select). De SPI-communicatie vindt altijd alleen plaats tussen een meester en een slaaf. Een master kan meerdere slaves erop hebben aangesloten. De master is verantwoordelijk voor het genereren van de klokpuls en deze wordt gedeeld met alle slaves. Alle communicatie kan ook alleen worden gestart door de master.
De SCK-pin (ook bekend als SCL-seriële klok) deelt het kloksignaal dat door de master wordt gegenereerd met de slaves. De MOSI-pin (ook bekend als SDA –Serial Data Out) wordt gebruikt om de data van de master naar de zalf te sturen. De MISO-pin (ook bekend als SDI - Serial Data In) wordt gebruikt om de gegevens van de zalf naar de master te krijgen. U kunt ook de pijlmarkering in de bovenstaande afbeelding volgen om de beweging van gegevens / signalen te begrijpen. Ten slotte wordt de SS-pin (ook bekend als CS –Chip select) gebruikt als er meer dan één slavemodule op de master is aangesloten. Deze in kan worden gebruikt om de gewenste slave te selecteren. Een voorbeeldcircuit waarbij meer dan één slaaf is verbonden met de master voor SPI-communicatie, wordt weergegeven in het onderstaande circuit.
Verschil tussen I2C en SPI-communicatie
We hebben al I2C-communicatie met PIC geleerd en dus moeten we bekend zijn met hoe I2C werkt en waar we ze kunnen gebruiken, zoals I2C kan worden gebruikt om de RTC-module te koppelen. Maar waarom hebben we nu een SPI-protocol nodig als we al I2C hebben? De reden is dat zowel I2C- als SPI-communicatie voordelen zijn op hun eigen manieren en daarom toepassingsspecifiek zijn.
Tot op zekere hoogte kan de I2C-communicatie worden beschouwd als een aantal voordelen ten opzichte van SPI-communicatie omdat I2C minder aantal pinnen gebruikt en het erg handig wordt als er een groot aantal slaves op de bus is aangesloten. Maar het nadeel van I2C is dat het dezelfde bus heeft voor het verzenden en ontvangen van gegevens en daarom relatief traag is. Het is dus puur gebaseerd op de applicatie om te kiezen tussen het SPI- en I2C-protocol voor uw project.
SPI met PIC16F877A met XC8 Compiler:
Genoeg basisprincipes, laten we nu leren hoe we SPI-communicatie kunnen gebruiken op de PIC16F877A- microcontroller met behulp van de MPLABX IDE en XC8-compiler. Voordat we beginnen, maken we duidelijk dat deze tutorial alleen spreekt over SPI in PIC16F877a met behulp van de XC8-compiler. Het proces zal hetzelfde zijn voor andere microcontrollers, maar er kunnen kleine wijzigingen nodig zijn. Onthoud ook dat voor geavanceerde microcontrollers zoals de PIC18F-serie de compiler zelf misschien een ingebouwde bibliotheek heeft om de SPI-functies te gebruiken, maar voor PIC16F877A bestaat zoiets niet, dus laten we er zelf een bouwen. De bibliotheek die hier wordt uitgelegd, wordt onderaan weergegeven als een header-bestand om te downloaden, dat kan worden gebruikt voor PIC16F877A om te communiceren met andere SPI-apparaten.
In deze tutorial zullen we een klein programma schrijven dat SPI-communicatie gebruikt om gegevens van de SPI-bus te schrijven en te lezen. We zullen dan hetzelfde verifiëren met behulp van Proteus-simulatie. Alle code met betrekking tot SPI-registers wordt gemaakt in het headerbestand genaamd PIC16f877a_SPI.h. Op deze manier kunnen we dit header-bestand gebruiken in al onze aankomende projecten waarin SPI-communicatie vereist is. En binnen het hoofdprogramma zullen we gewoon de functies uit het header-bestand gebruiken. De volledige code samen met het header-bestand kan hier worden gedownload.
Verklaring van SPI-headerbestand:
In het header-bestand moeten we de SPI-communicatie voor PIC16F877a initialiseren. Zoals altijd is de beste plaats om te beginnen het PIC16F877A-gegevensblad. De registers die de SPI-communicatie voor PIC16F8777a regelen, zijn de SSPSTAT en het SSPCON- register. U kunt erover lezen op pagina 74 en 75 van de datasheet.
Er zijn veel parameteropties die moeten worden gekozen tijdens het initialiseren van de SPI-communicatie. De meest gebruikte optie is dat de klokfrequentie wordt ingesteld op Fosc / 4 en in het midden wordt gedaan en de klok in de ideale toestand als laag wordt ingesteld. We gebruiken dus ook dezelfde configuratie voor ons header-bestand, je kunt ze gemakkelijk wijzigen door de respectieve bits te wijzigen.
SPI_Initialize_Master ()
De SPI initialize Master-functie wordt gebruikt om de SPI-communicatie als de master te starten. Binnen deze functie stellen we de respectievelijke pinnen RC5 en RC3 in als output pinnen. Vervolgens configureren we de SSPTAT en het SSPCON-register om de SPI-communicatie in te schakelen
ongeldig SPI_Initialize_Master () { TRISC5 = 0; // SSPSTAT = 0b00000000; // pg 74/234 SSPCON = 0b00100000; // pg 75/234 TRISC3 = 0; // op Als uitgang voor slave }
SPI_Initialize_Slave ()
Deze functie wordt gebruikt om de microcontroller in slaafmodus te laten werken voor SPI-communicatie. Tijdens de slavemodus moet pin RC5 als output worden ingesteld en moet pin RC3 als input worden ingesteld. De SSPSTAT en de SSPCON worden op dezelfde manier ingesteld voor zowel de slave als de master.
ongeldig SPI_Initialize_Slave () { TRISC5 = 0; // SDO-pin moet worden aangegeven als output SSPSTAT = 0b00000000; // pg 74/234 SSPCON = 0b00100000; // pg 75/234 TRISC3 = 1; // Instellen als in out voor mastermodus }
SPI_Write (inkomend teken)
De SPI Write-functie wordt gebruikt om gegevens naar de SPI-bus te schrijven. Het krijgt de informatie van de gebruiker via de inkomende variabele en gebruikt deze vervolgens om naar het bufferregister te gaan. De SSPBUF wordt gewist in de opeenvolgende klokpuls en de gegevens worden bit voor bit naar de bus gestuurd.
void SPI_Write (inkomend teken) { SSPBUF = inkomend; // Schrijf de door de gebruiker gegeven gegevens in de buffer }
SPI_Ready2Read ()
De SPI ready to Read-functie wordt gebruikt om te controleren of de gegevens in de SPI-bus volledig ontvangen en gelezen kunnen worden. Het SSPSTAT-register heeft een bit genaamd BF die wordt ingesteld zodra de gegevens volledig zijn ontvangen, dus we controleren of dit bit is ingesteld als het niet is ingesteld, dan moeten we wachten tot het is ingesteld om iets van de SPI-bus te lezen.
unsigned SPI_Ready2Read () { if (SSPSTAT & 0b00000001) retourneren 1; anders retourneren 0; }
SPI_Read ()
De SPI Read wordt gebruikt om de gegevens van de SPI-bus in de microcontroller te lezen. De gegevens die aanwezig zijn in de SPI-bus worden opgeslagen in de SSPBUF, we moeten wachten tot de volledige gegevens in de buffer zijn opgeslagen en dan kunnen we deze in een variabele lezen. We controleren het BF-bit van het SSPSTAT-register voordat we de buffer lezen om er zeker van te zijn dat de gegevensontvangst is voltooid.
char SPI_Read () // Lees de ontvangen gegevens { while (! SSPSTATbits.BF); // Houd ingedrukt tot BF-bit is ingesteld, om er zeker van te zijn dat de volledige gegevens worden gelezen retour (SSPBUF); // retourneer de gelezen gegevens }
Hoofdprogramma Toelichting:
De functies die in de bovenstaande sectie worden uitgelegd, bevinden zich in het headerbestand en kunnen worden opgeroepen in het hoofdbestand c. Laten we dus een klein programma schrijven om te controleren of de SPI-communicatie werkt. We schrijven slechts een paar gegevens in de SPI-bus en gebruiken de proteus-simulatie om te controleren of dezelfde gegevens worden ontvangen in de SPI-debugger.
Begin zoals altijd met het programma door de configuratiebits in te stellen en dan is het erg belangrijk om het header-bestand dat we zojuist hebben uitgelegd aan het programma toe te voegen, zoals hieronder weergegeven
# omvatten
Als je het programma hebt geopend vanuit het zip-bestand dat hierboven is gedownload, zal het header-bestand standaard aanwezig zijn in de header-bestandsmap van je projectbestand. Anders moet u het header-bestand handmatig in uw project toevoegen, zodra u het hebt toegevoegd, zien uw projectbestanden er als volgt uit
In het hoofdbestand moeten we de PIC initialiseren als Master voor SPI-communicatie en vervolgens in een oneindige while-lus zullen we willekeurige drie hexadecimale waarden in de SPI-bus schrijven om te controleren of we hetzelfde ontvangen tijdens simulatie.
void main () { SPI_Initialize_Master (); while (1) { SPI_Write (0X0A); __delay_ms (100); SPI_Write (0X0F); __delay_ms (100); SPI_Write (0X15); __delay_ms (100); } }
Merk op dat de willekeurige waarden die in het programma worden gebruikt 0A, 0F en 15 zijn en dat het hexadecimale waarden zijn, dus we zouden hetzelfde moeten zien tijdens simulatie. Dat is het, de code is helemaal klaar, dit is slechts een voorbeeld, maar we kunnen dezelfde methodologie gebruiken om te communiceren met andere MCU's of met andere sensormodules die werken volgens het SPI-protocol.
PIC simuleren met SPI-debugger:
Nu ons programma klaar is, kunnen we het compileren en vervolgens doorgaan met simulatie. Proteus heeft een leuke handige functie genaamd SPI-debugger , die kan worden gebruikt om de gegevens via een SPI-bus te volgen. Dus we gebruiken hetzelfde en bouwen een circuit zoals hieronder getoond.
Aangezien er slechts één SPI-apparaat in de simulatie is, gebruiken we de SS-pin niet en wanneer deze niet wordt gebruikt, moet deze worden geaard zoals hierboven weergegeven. Laad gewoon het hex-bestand in de PIC16F877A-microcontroller en klik op de afspeelknop om ons programma te simuleren. Zodra de simulatie start, krijgt u een pop-upvenster waarin de gegevens in de SPI-bus worden weergegeven, zoals hieronder weergegeven
Laten we de binnenkomende gegevens eens nader bekijken en controleren of deze dezelfde zijn als degene die we in ons programma hebben geschreven.
De gegevens worden ontvangen in dezelfde volgorde die we in ons programma hebben geschreven en hetzelfde wordt voor u gemarkeerd. U kunt ook proberen een programma te simuleren om te communiceren met twee PIC-microcontrollers met behulp van het SPI- protocol. U moet de ene PIC als master programmeren en de andere als slave. Alle benodigde header-bestanden voor dit doel staan al in het header-bestand.
Dit is slechts een glimp van wat SPI kan doen, het kan ook gegevens lezen en schrijven naar meerdere apparaten. We zullen meer over SPI behandelen in onze komende tutorials door verschillende modules te koppelen die werken met het SPI-protocol.
Ik hoop dat je het project hebt begrepen en er iets nuttigs van hebt geleerd. Als je twijfels hebt, plaats ze dan in de commentaarsectie hieronder of gebruik de forums voor technische hulp.
De volledige hoofdcode is hieronder gegeven; u kunt hier header-bestanden met alle code downloaden