Microchip kirjoitti tästä sovellusselosteita:
- AN734 I2C-orjan käyttöönotosta
- AN735 toteutuksesta I2C-isäntä
- Verkkoprotokollan asettamiseen ympäristöseurantaa varten on myös teoreettisempi AN736, mutta sitä ei tarvita tässä projektissa.
Sovellushuomautukset toimivat ASM: n kanssa, mutta ne voidaan helposti siirtää C: hen.
Microchipin ilmaisilla C18- ja XC8-kääntäjillä on I2C-toiminnot. Voit lukea lisää niistä kääntäjän kirjastojen ohjeista, osiosta 2.4. Tässä on pikaohjeita:
Asennus
Sinulla on jo Microchipin C18- tai XC8-kääntäjä. Molemmissa on sisäänrakennetut I2C-toiminnot. Jos haluat käyttää niitä, sinun on sisällytettävä i2c.h
:
#include i2c.h
Jos haluat katsomalla lähdekoodia löydät sen täältä:
- C18-otsikko:
installation_path
/ v
x.xx
/h/i2c.h
- C18-lähde:
Installation_path
/ v
x.xx
/ src / pmc_common / i2c /
- XC8-otsikko:
installation_path
/v
x.xx
/ include / plib / i2c.h
- XC8-lähde:
installation_path
/v
x.xx
/ sources / pic18 / plib / i2c /
Ohjeista löydät mistä tiedostosta / i2c /
-kansio, jossa toiminto sijaitsee.
Yhteyden avaaminen
Jos olet perehtynyt Microchipin MSSP-moduuleihin, tiedät ne ensin on alustettava. Voit avata I2C-yhteyden MSSP-portissa käyttämällä OpenI2C
-toimintoa. Näin se määritellään:
void OpenI2C (allekirjoittamaton char sync_mode, allekirjoittamaton char slew);
Kohdassa sync_mode
voit valita, onko laite isäntä tai orja, ja jos se on orja, pitäisikö sen käyttää 10- tai 7-bittistä osoitetta. Suurimman osan ajasta käytetään 7-bittistä, erityisesti pienissä sovelluksissa. sync_mode
-vaihtoehdot ovat:
-
SLAVE_7
- Slave-tila, 7-bittinen osoite -
SLAVE_10
- Slave-tila, 10-bittinen osoite -
MASTER
- Master-tila
Kanssa tapettu
, voit valita, pitäisikö laitteen käyttää kääntötaajuutta. Lisätietoja siitä, mitä se on täällä: Mikä on I2C: n tappiotaajuus?
Kaksi MSSP-moduulia
Kahdella MSSP-moduulilla varustetuissa laitteissa on jotain erityistä, kuten PIC18F46K22. Heillä on kaksi toimintosarjaa, yksi moduulille 1 ja toinen moduulille 2. Esimerkiksi OpenI2C ()
: n sijaan heillä on OpenI2C1 ()
ja openI2C2 ()
.
Okei, joten olet määrittänyt kaiken ja avannut yhteyden. Tehdään nyt joitain esimerkkejä:
Esimerkkejä
Master-kirjoitusesimerkki
Jos tunnet I2C-protokollan, tiedät tyypillisen master-kirjoitussarjan näyttää tältä:
Master: START | ADDR + W | | TIEDOT | | TIEDOT | | ... | TIEDOT | | STOP-orja: | | ACK | | ACK | | ACK | ... | | ACK |
Aluksi lähetämme START-ehdon. Harkitse tätä puhelimen nostamista. Sitten osoite kirjoitusbitillä - numeron valitseminen. Tässä vaiheessa orja, jolla on lähetetty osoite, tietää, että häntä kutsutaan. Hän lähettää kiitoksen ("Hei"). Nyt päälaite voi lähettää tietoja - hän alkaa puhua. Hän lähettää minkä tahansa määrän tavuja. Jokaisen tavun jälkeen orjan tulisi ACK vastaanottaa tiedot ("kyllä, kuulen sinut"). Kun päälaite on lopettanut puhumisen, hän lopettaa STOP-ehdon.
C: ssä päällikön kirjoitussarja näyttäisi tälle isännälle:
IdleI2C ( ); // Odota, kunnes bussi on tyhjäkäynnillä
StartI2C (); // Lähetä START conditionIdleI2C (); // Odota START-ehdon loppuaWriteI2C (orjaosoite & 0xfe); // Lähetä osoite, kun R / W on tyhjennetty kirjoitusIdleI2C (): lle; // Odota ACKWriteI2C (data [0]); // Kirjoita dataIdleI2C () ensimmäinen tavu; // Odota ACK: ta ... ... WriteI2C (data [n]); // Kirjoita dataIdleI2C (): n n. Tavu; // Odota ACKStopI2C (); // Katkaise puhelu, lähetä STOP-ehto
Master Read -esimerkki
Master-lukusarja eroaa hieman kirjoitusjärjestyksestä:
Master: START | ADDR + R | | | ACK | | ACK | ... | | NACK | STOP-orja: | | ACK | TIEDOT | | TIEDOT | | ... | TIEDOT | |
Isäntä taas aloittaa puhelun ja soittaa numeroon. Hän haluaa kuitenkin nyt saada tietoa. Orja vastaa ensin puheluun ja alkaa sitten puhua (lähettää tietoja). Päällikkö tunnistaa jokaisen tavun, kunnes hänellä on tarpeeksi tietoa. Sitten hän lähettää Not-ACK: n ja katkaisee STOP-ehdon.
C: ssä tämä näyttää pääosalta tältä:
IdleI2C (); // Odota, kunnes väylä on tyhjäkäynnilläStartI2C (); // Lähetä START conditionIdleI2C (); // Odota START-ehdon loppuaWriteI2C (orjaosoite | 0x01); // Lähetä osoite R / W-asetuksella readIdleI2C (): lle; // Odota ACKdataa [0] = ReadI2C (); // Lue dataAckI2C () ensimmäinen tavu; // Lähetä ACK // ... data [n] = ReadI2C (); // Lue dataNotAckI2C () n. Tavu; // Lähetä NACKStopI2C (); // Katkaise puhelu, lähetä STOP-ehto
Orjakoodi
Orjalle on parasta käyttää keskeytyspalvelurutiinia tai ISR: ää. Voit määrittää mikrokontrollerin vastaanottamaan keskeytyksen, kun osoitteesi kutsutaan. Näin sinun ei tarvitse tarkistaa bussia jatkuvasti.
Aloitetaan ensin keskeytysten perusteet. Sinun on otettava keskeytykset käyttöön ja lisättävä ISR. On tärkeää, että PIC18: lla on kaksi keskeytystasoa: korkea ja matala. Aiomme asettaa I2C: n tärkeäksi keskeytykseksi, koska I2C-puheluun vastaaminen on erittäin tärkeää. Aiomme tehdä seuraavaa:
- Kirjoita SSP ISR, kun keskeytys on SSP-keskeytys (eikä uusi keskeytys)
- Kirjoita yleinen korkean prioriteetin ISR, kun keskeytys on tärkeä prioriteetti. Tämän toiminnon on tarkistettava, millainen keskeytys käynnistettiin, ja kutsuttava oikea ali-ISR (esimerkiksi SSP ISR).
- Lisää
GOTO
-ohje yleiseen ISR: ään korkean prioriteetin keskeytysvektori. Emme voi laittaa yleistä ISR: ää suoraan vektoriin, koska se on monissa tapauksissa liian suuri.
Tässä on esimerkki koodista:
// Funktion prototyypit korkean prioriteetin ISR: lle välttää highPriorityISR (mitätön); // Toiminnon prototyyppi SSP: lle } #pragma code // Todellinen korkean prioriteetin ISR # pragma keskeytä highPriorityISRvoid highPriorityISR () {if (PIR1bits.SSPIF) {// Tarkista SSP keskeytys SSPISR (); // Se on SSP-keskeytys, kutsu SSP ISR PIR1bits.SSPIF = 0; // Tyhjennä keskeytyslippu} return;} // Tämä on todellinen SSP ISRvoid SSPISR (void) {// Lisäämme koodin myöhemmin}
Seuraava tehtävä on Ota korkean prioriteetin keskeytys käyttöön sirun alustuksen yhteydessä. Tämä voidaan tehdä yksinkertaisilla rekisterin manipulaatioilla:
RCONbits.IPEN = 1; // Ota keskeytysprioriteetit käyttöön
INTCON & = 0x3f; // Ota keskeytykset globaalisti käyttöön PIE1bits.SSPIE = 1; // Ota SSP keskeytys käyttöön IPR1bits.SSPIP = 1; // Aseta SSP-keskeytysprioriteetiksi korkea
Nyt keskeytykset toimivat. Jos toteutat tämän, tarkistan sen nyt. Kirjoita perus SSPISR ()
, jotta LED-merkkivalo vilkkuu, kun SSP-keskeytys tapahtuu.
Okei, joten keskeytyksesi toimivat. Kirjoita nyt oikea koodi SSPISR ()
-funktiolle. Mutta ensin teoria. Erotamme viisi erilaista I2C-keskeytystyyppiä:
- Master kirjoittaa, viimeinen tavu oli osoite
- Master kirjoittaa, viimeinen tavu oli data
- Master lukee, viimeinen tavu oli osoite
- Master lukee, viimeinen tavu oli tietoja
- NACK: lähetyksen loppu
Voit tarkistaa missä tilassa olet tarkistamalla bitit SSPSTAT
-rekisterissä. Tämä rekisteri on seuraava I2C-tilassa (käyttämättömät tai merkityksettömät bitit jätetään pois):
- Bitti 5: D / EI A: Data / Ei osoite: määritä, jos viimeinen tavu oli tietoja, tyhjennetty, jos viimeinen tavu oli osoite
- Bitti 4: P: Pysäytysbitti: aseta, jos STOP-ehto tapahtui viimeksi (ei ole aktiivista toimintaa)
- Bitti 3: S: Aloitusbitti: aseta jos START-ehto tapahtui viimeksi (aktiivinen toiminto)
- Bitti 2: R / EI W: Lue / ei kirjoita: määritä, jos operaatio on pääluku, tyhjennetään, jos operaatio on pääkirjoitus
- Bitti 0: BF: Puskuri täynnä: määritä, jos SSPBUFF-rekisterissä on tietoja, tyhjennetty, ellei ole
Näiden tietojen avulla on helppo nähdä, kuinka nähdä mikä tila I2C-moduuli on:
-tila | Käyttö | Viimeinen tavu | Bitti 5 | Bitti 4 | Bitti 3 | Bitti 2 | Bitti 0 ------ + ----------- + ----------- + ------- + ------- + - ------ + ------- + ------- 1 | M kirjoittaa | osoite | 0 | 0 | 1 | 0 | 12 | M kirjoittaa | tiedot | 1 | 0 | 1 | 0 | 13 | M lukenut | osoite | 0 | 0 | 1 | 1 | 0
4 | M lukenut | tiedot | 1 | 0 | 1 | 1 | 05 | ei mitään - | ? | ? | ? | ? | ?
Ohjelmistossa on parasta käyttää oletusasetuksena tilaa 5, joka oletetaan, kun muiden valtioiden vaatimukset eivät täyty. Tällä tavalla et vastaa, kun et tiedä mitä tapahtuu, koska orja ei vastaa NACKiin.
Katsotaanpa joka tapauksessa koodi:
void SSPISR (void) {allekirjoittamaton char temp, data; temp = SSPSTAT & 0x2d; if ((temp ^ 0x09) == 0x00) {// 1: kirjoitusoperaatio, viimeinen tavu oli osoitetiedot = ReadI2C (); // Tee jotain datalla tai palauta vain} muu, jos ((temp ^ 0x29) == 0x00) {// 2: kirjoitusoperaatio, viimeinen tavu oli data data = ReadI2C (); // Tee jotain datalla tai palauta vain} muu, jos ((temp ^ 0x0c) == 0x00) {// 3: lukuoperaatio, viimeinen tavu oli osoite // Tee jotain, kirjoita sitten jotain I2C WriteI2C (0x00); } else if ((temp ^ 0x2c) == 0x00) {// 4: lukuoperaatio, viimeinen tavu oli data // Tee jotain, kirjoita sitten jotain I2C: lle WriteI2C (0x00); } else {// 5: NACK nollasi orjalogiikan isännältä // Älä tee mitään, tyhjennä puskuri, palauta mikä tahansa}}
Näet kuinka voit tarkistaa SSPSTAT
-rekisteri (ensin ANDed 0x2d
-merkillä, jotta meillä olisi vain hyödyllisiä bittejä) bittimaskien avulla nähdäksesi, mikä keskeytystyyppi meillä on.
Se on työsi selvittää, mitä sinun on lähetettävä tai tehtävä, kun vastaat keskeytykseen: se riippuu sovelluksestasi.
Viitteet
Haluan jälleen mainita sovelluksen toteaa, että Microchip kirjoitti I2C: stä:
- AN734 I2C-orjan käyttöönotosta
- AN735 I2C-isännän toteuttamisesta
- AN736 verkkoprotokollan asettamisesta ympäristöseurantaa varten
Kääntäjäkirjastoille on dokumentaatio: Kääntäjäkirjastojen ohjeet
Kun asetat jotain itse, tarkista sirun tietolomakkeesta (M) SSP-osiosta I2C-viestintä. Käytin pääosassa PIC18F46K22 ja orjaosassa PIC18F4620.