Kysymys:
Alkaen I2C: stä PIC18: lla
user17592
2013-01-20 18:44:17 UTC
view on stackexchange narkive permalink

Projektille haluaisin, että kolme PIC: tä (kaksi orjaa PIC18F4620, yksi isäntä PIC18F46K22) kommunikoi I2C-väylän kautta. Myöhemmin orjia voidaan lisätä (kuten EEPROM, SRAM jne.). Kirjoitan näiden PIC-koodien koodin C: ssä C18-kääntäjän avulla. Olen katsonut paljon Internetissä, mutta en löytänyt kirjastoja (M) SSP-oheislaitteiden käsittelemiseksi. Olen lukenut molempien (M) SSP-oheislaitteiden PIC-tiedostojen tietolomakkeen I2C-tilassa, mutta en voinut selvittää väylän liittämistä.

Tarvitsen siis master ja orjakirjastot.

Mitä suosittelet? Onko sinulla jonkun kaltaista kirjastoa? Onko se sisäänrakennettu kääntäjässä ja jos kyllä, missä? Onko jossain netissä hyvä opetusohjelma?

Minulla oli samanlaisia ​​ongelmia muutama kuukausi sitten. Voit lukea niistä [täältä] (http://electronics.stackexchange.com/q/29609/1240). Tässä ovat C18: n kirjastot, jotka toimivat I ^ 2C: n kanssa, mutta puuttuu yksi iso asia: Sinun on asetettava väylän nopeus manuaalisesti kirjoittamalla asianmukaiseen rekisteriin, jota ei mainita missään kirjaston dokumentaatiossa.
Kiitos, se oli hyödyllistä! Se kuitenkin teki vain isäntäosan, ei orjaosan.
Joo, minun ei tarvinnut työskennellä orjan kanssa silloin, joten ei orjaesimerkkejä. Anteeksi.
Ei, se on hieno, se oli hyödyllinen master-osalle! :-)
poista analoginen käytöstä myös porteista ANSELC = 0;
Kolme vastused:
user17592
2013-01-20 21:48:51 UTC
view on stackexchange narkive permalink

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/vx.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ä:

  1. Master kirjoittaa, viimeinen tavu oli osoite
  2. Master kirjoittaa, viimeinen tavu oli data
  3. Master lukee, viimeinen tavu oli osoite
  4. Master lukee, viimeinen tavu oli tietoja
  5. 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.

Oli Glaser
2013-01-20 19:19:03 UTC
view on stackexchange narkive permalink

Ensinnäkin suosittelen vaihtamista XC8-kääntäjään yksinkertaisesti siksi, että se on uusin. Saatavana on oheiskirjastoja, mutta en ole koskaan käyttänyt niitä paljon. Tarkista yksityiskohdat ja asiakirjat mikrosirujen verkkosivustolta.

Okei, minulla on joitain hyvin vanhoja perusrutiineja I2C eeprom -tietokoneille, joita käytin kauan sitten PIC16F: n ja vanhan Microhip-keskikokoisen kääntäjän kanssa (se on saattanut olla Hi-Tech yksi), mutta mielestäni ne saattavat toimia kunnolla PIC18: n kanssa, koska mielestäni oheislaite on sama. Löydät joka tapauksessa hyvin nopeasti, jos kaikki on erilaista.
Ne olivat osa suurempaa tiedostoa, jota käytettiin lämpötilalokeriprojektin kanssa, joten repin kaikki muut etuyhteydettömät toiminnot ja tallensin alla olevina tiedostoina, joten se on mahdollista, olen tehnyt siitä vähän sotkua, mutta toivottavasti pystyt saamaan käsityksen siitä, mitä tarvitaan (se voi jopa toimia, et koskaan tiedä ;-))

Tarvitset varmistaaksesi, että pääotsikkotiedosto on oikea, ja tarkista / muuta nastat varmistaaksesi, että ne ovat oikeita I2C-oheisnastoja, ja rekisterinimet, jos ne ovat Hi-Tech-kääntäjältä, joka teki asiat rekisterissä hieman eri tavalla nimeämiskäytäntö.

I2C.c-tiedosto:

  #include "I2C.h" #include "delay.h" #include <pic.h> # define _XTAL_FREQ 20000000void write_ext_eeprom ( allekirjoittamaton int-osoite, allekirjoittamaton char-data) {unsigned char a0 = ((osoite & 0x8000) >> 14); allekirjoittamaton char msb = (osoite >> 8); allekirjoittamaton merkki lsb = (osoite & 0x00FF); i2c_start (); i2c_write (0xa0 | a0); i2c_write (msb); i2c_write (lsb); i2c_write (data); i2c_stop (); ViiveMs (11);} / ******************************************** ************************************************ / allekirjoittamaton merkki read_ext_eeprom (allekirjoittamaton int-osoite) {unsigned char a0 = ((osoite & 0x8000) >> 14); allekirjoittamattomat hiilitiedot;
allekirjoittamaton char msb = (osoite >> 8); allekirjoittamaton merkki lsb = (osoite & 0x00FF); i2c_start (); i2c_write (0xa0 | a0); i2c_write (msb); i2c_write (lsb); i2c_repStart (); i2c_write (0xa1 | a0); data = i2c_read (0); i2c_stop (); return (data);} void i2c_init () {TRISC3 = 1; // aseta SCL- ja SDA-nastat tuloiksi TRISC4 = 1; SSPCON = 0x38; // aseta I2C-isäntätila SSPCON2 = 0x00; // SSPADD = 9; // 500 kHz väylä, jossa 20 MHz: n xtal SSPADD = 49; // 100 kHz: n väylä 20 MHz: n xtal CKE = 0; // käytä I2C-tasoja, jotka toimivat myös '0' SMP = 1: n kanssa; // poista taaksepäinohjaus käytöstä myös '0' PSPIF = 0; // tyhjennä SSPIF-keskeytyslippu BCLIF = 0; // tyhjennä väylän törmäyslippu} / ******************************************** ************************************************* / mitätön i2c_waitForIdle () {while ((SSPCON2 & 0x1F) | RW) {}; // odota joutokäyntiä eikä kirjoita} / ****************************************** *************************************************** / void i2c_start () {i2c_waitForIdle (); SEN = 1;} / ********************************************** ************************************ ***** ) {i2c_waitForIdle (); RSEN = 1;} / ********************************************** ************************************ ***** ) {i2c_waitForIdle (); PEN = 1;} / ********************************************** ************************************ ***** unsigned char ack) {allekirjoittamaton char i2cReadData; i2c_waitForIdle (); RCEN = 1; i2c_waitForIdle (); i2cReadData = SSPBUF; i2c_waitForIdle (); jos (ack) {ACKDT = 0; } muu {ACKDT = 1; } AKKEN = 1; // lähetä kuittaussekvenssin palautus (i2cReadData);} / *************************************** *************************************************** ** / allekirjoittamaton char i2c_write (allekirjoittamaton char i2cWriteData) {i2c_waitForIdle (); SSPBUF = i2cWriteData; // if (ACKSTAT) {// while (ACKSTAT);}
paluu (! ACKSTAT); // -funktio palauttaa arvon 1, jos lähetys kuitataan}  

I2C.h-otsikkotiedosto:

  extern void i2c_init (); extern void i2c_waitForIdle () ;; extern void i2c_start (); extern void i2c_repStart (); extern void i2c_stop (); extern int i2c_read (unsigned char ack); extern unsigned char i2c_write (unsigned char i2cWriteData);  
Kiitos, se on pääosa ja todellakin todennäköisesti sama kuin PIC18. Kiitos myös kääntäjän muistiinpanosta :-) Kysymys hieman antoi minulle joitain sovellustietoja, joten lisätään ne itse vastauksena.
Sinun kannattaa lisätä osa siirtonopeuden generaattorin määrittämisestä. Koodi näyttää tyypillisesti nimellä "SSP1ADD = ((_XTAL_FREQ / 100000) / 4) -1;" 1KHz: lle jne.
Chetan Bhargava
2013-01-22 11:48:53 UTC
view on stackexchange narkive permalink

XC8- ja XC16-kääntäjät sisältävät I2C-kirjastoja.

Tapasin ongelman, että dokumentaatio ei ole kovin hyvä! Jos käytät Microchip-dokumentaation esimerkkejä, sinulla ei ole onnea. Jopa mikrosirun tuki ei voi auttaa sinua. Olen ollut siellä itse.

Jokin aika sitten työskentelin PIC24EP512GP -sarjan mikrokontrollerin kanssa, eikä kirjasto toiminut minulle Microchipin dokumentoimalla tavalla.

Ah, se on sääli! Joten mitä teit?
Improvisoin omani valitettavasti.
Ovatko ne hyödyllisiä myös muille? Haluaisin nähdä heidät!


Tämä Q & A käännettiin automaattisesti englanniksi.Alkuperäinen sisältö on saatavilla stackexchange-palvelussa, jota kiitämme cc by-sa 3.0-lisenssistä, jolla sitä jaetaan.
Loading...