Egy olyan kérdéssel fordulok hozzátok hogy mikropascal-ban ha PIC16f877-re külső EEpromot teszek (RC.3, RC.4) a többi RC lábat digitális bementként akarom használni hogy kell megadni a TRISC utasítást.
Esetleg mit kell még beállítani hogy működjön az EEprom is és a bemenetek is.
Elméletileg hozzá sem kellene nyúlnod a TRISC regiszterhez, mivel reset után automatikusan bemenetként funkcionálnak a portok. Ekkor a TRISC értéke %11111111.
Ha mégis be akarod állítani:
TRISC:=%11111111;
TRISC:=255; // ugyanaz, csak decimálisan
illetve, ha figyelembe veszed az IIC vonalakat, akkor a 4-es bit legyen 0, de az IIC_init függvény úgyis beállítja ezt.
TRISC:=%11101111;
Ennek lényege az, hogy miután az IIC_init-et meghívtad, már ne változtass a TRISC regiszter 4-es bitjén.
A TRISC.3 bitet pedig a többi IIC függvény állítja be függően az adatiránytól.
Ismét egy kérdésel fordulok hozzátok, PIC16f877-nél az RA protokat akarom olvasni mint digitális bemenetet, de sajnos nem jön össze.
Minden RA portot szeretném olvasni, a példába csak az RA.0 írtam bele, nem tudom mi lehet a biba.
program xxx;
TRISA := 255;
ADCON1:=6;
Lcd_Init(PORTD);
begin
repeat
if porta.0=0 then Lcd_Out(2, 1,'semmi')
else Lcd_Out(2, 1,'jel van');
until 1=2;
end.
Sziasztok
EEprom problémám lenne próbáltam PIC16f877-el a mikropascal help alapján 24c08-as EEpromot írni-olvasni, de nem akar írni ha olvastatni próbálok vele akkor meg mindíg 162-es értékkel tér vissza.
Olvasás program:
program I2C;
VAR X:word;
y:byte;
txt,txt1 : string[2];
begin
Lcd_Init(PORTD);
I2C_init(100000);
lcd_out(1,1,'prg:');
delay_ms(200);
X:=0;
y:=0;
repeat
inc(x);
inttostr(y,txt);
lcd_out(2,5,txt); //olvasott érték kiírása
inttostr(x,txt1);
lcd_out(1,8,txt1); //ciklusszám
delay_ms(80);
I2C_Start; // Issue I2C start signal
I2C_Wr($A2); // Send byte via I2C
I2C_Wr(x); // Send byte(address for EEPROM)
I2C_Repeated_Start; // Issue I2C signal repeated start
I2C_Wr($A3); // Send byte (request data from EEPROM)
y := I2C_Rd(1); // Read the data
I2C_Stop; // Issue I2C stop signal
delay_ms(50);
until X=1000;
end.
Elméletileg nem okoz gondot, de a fenti eeprom címe csak 0, illetve 4 lehet, te pedig 2-nek címezed. ezért nincs értelme, ha az A0-t megemeled. Igazából címezni így kellene :
I2C_Start; // Issue I2C start signal
I2C_Wr($A0); // Send byte via I2C
I2C_Wr(x); // Send byte(address for EEPROM)
I2C_Repeated_Start; // Issue I2C signal repeated start
I2C_Wr($A1); // Send byte (request data from EEPROM)
y := I2C_Rd(1); // szerintem, mivel nem kell ACK : y := I2C_Rd(0);
I2C_Stop; // Issue I2C stop signal
illetve:
Felhúzó ellenállások OK? A cím jól van beállítva az A0,A1,A2 lábon?
Köszi a választ, de a legfőbb probléma a PIC-be volt nem működik az I2C rajta valamiért vettem másikat és azzal már jó volt, meg átírtam az I2C_rd(0)-ra. AZ I2C_Wr($A2) nálam működik, igaz nem próbáltam még az I2C_Wr($A0).
Egy kérdésem még lenne $A0, $A2, $A1 miből adódik? az EEprom címző lábak bekötéséből? Én a mikropascal Help alapján csináltam mindent.
Keress rá az eeprom adatlapjára a google-n.
A 0. bit -ha 0 akkor ír, egyábként olvas. 1-3 bit az eeprom címe, a felső 4 bit pedig az eeprom "kódja".
Jelen esetben %10100001- olvasás %10100000 - írás
Az IC-n lévő lábakat A0, A1, A2-nek nevezik, de ne keverd össze annyit tesz mint address0, address1 .... Semmi köze a kiküldendő byte-okhoz. Az IIC protokoll, mivel közös vonalat használ akár több eszköz is párhuzamosan köthető. (akár több eepromot is párhuzamosan köthetsz) így a címük által azonosíthatóak.
Egy kérés még!
egy 24c08-at próbáltam írni mind az 1024 helyet i2c_wr($a2)-vel, de csak 256-512-ig írta a memória helyeket a többivel nem foglakozott. Ha I2C_wr($a0)-val próbáltam akkor meg 0-256 -ig írta meg.
Miért csinálja ezt?
Bocsánat, én is figyelmetlen voltam! Az eeprom címének felső 2 bitje található a 1 és a 2. biten. a 0 bit tényleg az írás/olvasás bitje, az eszköz hardware-s beállításának címe a 3. bit.
Így: A felső 4 bit marad 1010 (=$a)
a 3 bit megfelel annak, hogy az eeprom A2 jelü lábát hova kötötted. Amennyiben testre ez az érték 0 ellenkező esetben 1.
A 2. és 1. bit pedig a memóriacím felső két bitje. Ezek alapján a megcímzendő memóriaérték csak 0..255 között értelmezhető (ami nálad az x változó).
Ennek ellenére az eeprom 16bites címet kér - érdekes...
var kontroll : byte;
// I2C init + egyebek
for x:=0 to 1023 do
begin
I2C_Start;
kontroll:=$A0 + ((x div $FF) shl 1);
I2C_Wr(kontroll);
I2C_Wr(x); // elméletileg ez kéne: I2C_Wr(0); I2C_Wr(x mod 256);
I2C_Repeated_Start;
I2C_Wr(kontroll or 1);
y := I2C_Rd(0);
I2C_Stop;
// kíírás ill. egyéb
end;
ÍRÁS
for x:=0 to 1023 do
begin
I2C_Start;
kontroll:=$A0 + ((x div $FF) shl 1);
I2C_Wr(kontroll);
I2C_Wr(x);
I2C_Wr(y); // y tartalmazza a kíírandó byte-ot
I2C_Stop;
// kíírás ill. egyéb
end;
A fentieket nem próbáltam, csak úgy fejből, de talán kipróbálásra alkalmas.
gondoltam hogy valami ilyesmi lehet, gyanus volt hogy csak 256-ig írt, vagy 256-512 között.
Holnap délután megpróbálom, és megírom hogy bevált-e.
(Bocs hogy ennyit kérdezek, de még külső EEpromot nem használtam)
Oda jó a Mikropascal-os mintaprogram, azzal a megkötéssel, hogy egy byte kiolvasásánál nem kell ACK
Magyarul:
y := I2C_Rd(0); // nulla legyen az ACK bit
( A mikropascal helpjében a mintaprogram szerintem hibás ennél a sornál, mi sem bizonyítja, hogy a software-s megoldásnál már az általam is írt sor szerepel)
Köszönöm a választ
Most rendeltem 24c64-et ha minden igaz hétfőn megkapom, és jelzem hogy működik-e!
Ha jól értekel akkor it nem csak 8bites címzés van hanem it elfogadja a 16bites címet is, minden trükközés nélkül.
Pl:
var
y:byte;
x:word;
begin
I2C_Start;
I2C_Wr($A0);
I2c_wr(x); //vagy pl: I2C_wr(4752);
I2C_Repeated_Start;
I2C_Wr($A1);
y := I2C_Rd(0);
I2C_Stop;
end;
Az lenne a kérdésem, hogy a mikropascal-ban hogyan tudom lekezelni a megszakításokat.
16F84-nek az RB0- lábán jön egy külső megszakítás, akkor csak az if...-el tudom megvizsgálni, hogy történt-e változás vagy létezik valamilyen beépített eljárás/függvény, ami megszakítás kéréskor lefut?
köszi a segítséget
Sziasztok
Egy olyan kérdésem lenne hogy egy PIC16f877A-nál az PORTE portot digitális inputként akarom használni, de nem tudommit kell beállítani. (mit mint ahogy az PORTA portnál az adcon1:=6);
Regiszterek:
- TRISE(4) PSPMODE bit =0
- TRISE(2:0) PORTE Data Direction Bits (1=Input)
- PORTE(2:0) PRTE Data
- ADCON1(3:0) PCFG bitek beállítása a táblázat szerint. (pld. 0010 : RE-pot Digital, RA-port analog, Ref=Vdd/Vss)
DS30292C 36. oldal 3.5 fejezet
DS30292C 112. oldal 11-2 fejezet
Mikropascal 6.02-t használok, és egy olyan problémám van hogy ha átfordítom a progit kiírja hogy túl nagy, pedig azt írja hogy a FREE ROM: 56%, FREE RAM: 71%. Nem tudom miért pedig a javító is rá van töltve, PIC16F877A-t programozok vele.
A hibaüzenet: 0:0 E-0 Linker error: Routine too large.
Ha egy sort kiszedek akkor szépen átfordította a következő üzenettel:
0:0 S-100 Success (Release build)
0:0 W-101 Used ROM: 2894 (35%) Used RAM: 84 (22%)
0:0 W-102 Free ROM: 5297 (65%) Free RAM: 284 (78%)