Fórum témák

» Több friss téma
Fórum » AVR - Miértek hogyanok
 
Témaindító: pakibec, idő: Márc 11, 2006
Témakörök:
WinAVR / GCC alapszabályok:
1. Ha ISR-ben használsz globális változót, az legyen "volatile"
2. Soha ne érjen véget a main() függvény
3. UART/USART hibák 99,9% a rossz órajel miatt van
4. Kerüld el a -O0 optimalizációs beállítást minden áron
5. Ha nem jó a _delay időzítése, akkor túllépted a 65ms-et, vagy rossz az optimalizációs beállítás
6. Ha a PORTC-n nem működik valami, kapcsold ki a JTAG-et
Bővebben: AVR-libc FAQ
Lapozás: OK   600 / 837
(#) Sick-Bastard hozzászólása Ápr 20, 2014 /
 
Üdv!

Megint sikerült valami érdekesbe ütköznöm.
Írtam egy makrót, ami 2x szépen le is fut, de a 3. alkalommal mintha szimplán átugraná.
  1. #include <define.h>
  2.  
  3. // R1 Format
  4. #define         IDLE_STATE                      0x01
  5. #define         ERASE_RST                       0x02
  6. #define         ILLEGAL_CMD                     0x04
  7. #define         COM_CRC_ERR                     0x08
  8. #define         ERASE_SEQ_ERR           0x10
  9. #define         ADD_ERR                         0x20
  10. #define         PARAMETER_ERR           0x40
  11.  
  12. // R2 Format
  13. #define         LOCKED                          0x01
  14. #define         UN_LOCK_CMD_FAIL        0x02
  15. #define         ERROR                           0x04
  16. #define         CC_ERR                          0x08
  17. #define         ECC_FAIL                        0x10
  18. #define         WP_VIOLATION            0x20
  19. #define         ERASE_PARAM                     0x40
  20. #define         CSD_OVERWRITE           0x80
  21.  
  22. // Data Response Token
  23. #define         DATA_ACCEPTED           0x05
  24. #define         DATA_REJECT_CRC_ERR     0x0B
  25. #define         DATA_REJECT_WR_ERR      0x0D
  26.  
  27. #define         SD                                      PINB4
  28. #define         SD_EN()                         PORTB &=        ~(1<<SD);
  29. #define         SD_DIS()                        PORTB |=         (1<<SD);
  30.  
  31.  
  32. unsigned char R1, R1b, R2, R3, R7, data;
  33. unsigned char   OCR[4]  = {},
  34.                 CID[16] = {},
  35.                 RCA[2]  = {},
  36.                 DSR[2]  = {},
  37.                 CSD[16] = {},
  38.                 SCR[8]  = {};
  39.                
  40. unsigned char sd_buffer[512] = {};
  41.  
  42. void SD_CMD (unsigned char cmd, unsigned long arg, unsigned char crc)
  43. {
  44.         SPIWR(0x40+cmd);
  45.         SPIWR(arg>>24);
  46.         SPIWR(arg>>16);
  47.         SPIWR(arg>>8);
  48.         SPIWR(arg);
  49.         SPIWR(crc);
  50.        
  51.         SPIWR(0xFF);
  52. }
  53.  
  54. void print_R1(void)
  55. {
  56.         if(R1&0x00)
  57.         {
  58.                 USART0_TX_String("SD OK");
  59.                 USART0_TXD(9);
  60.         }
  61.         if(R1&IDLE_STATE)
  62.         {
  63.                 USART0_TX_String("IDLE_STATE");
  64.                 USART0_TXD(9);
  65.         }
  66.         if(R1&ERASE_RST)
  67.         {
  68.                 USART0_TX_String("ERASE_RST");
  69.                 USART0_TXD(9);
  70.         }
  71.         if(R1&ILLEGAL_CMD)
  72.         {
  73.                 USART0_TX_String("ILLEGAL_CMD");
  74.                 USART0_TXD(9);
  75.         }
  76.         if(R1&COM_CRC_ERR)
  77.         {
  78.                 USART0_TX_String("COM_CRC_ERR");
  79.                 USART0_TXD(9);
  80.         }
  81.         if(R1&ERASE_SEQ_ERR)
  82.         {
  83.                 USART0_TX_String("ERASE_SEQ_ERR");
  84.                 USART0_TXD(9);
  85.         }
  86.         if(R1&ADD_ERR)
  87.         {
  88.                 USART0_TX_String("ADD_ERR");
  89.                 USART0_TXD(9);
  90.         }
  91.         if(R1&PARAMETER_ERR)
  92.         {
  93.                 USART0_TX_String("PARAMETER_ERR");
  94.                 USART0_TXD(9);
  95.         }
  96.         USART0_TXD(10);
  97.         USART0_TXD(13);
  98. }
  99.  
  100. void SD_CMD_Loop(unsigned char cmd, unsigned long arg, unsigned char crc, unsigned char response)
  101. {
  102.         for(char i=0; i<10 && R1 != response; i++)
  103.         {
  104.                 SD_CMD(cmd,arg,crc);
  105.                
  106.                 R1 = 0xFF;
  107.                 R1 = SPIWRD(0xFF);
  108.                
  109.                 USART0_TX_String("CMD");
  110.                 itoa(cmd, StringA, 10);
  111.                 USART0_TX_String(StringA);
  112.                 USART0_TXD(9);
  113.                
  114.                 USART0_TX_String("i = ");
  115.                 itoa(i, StringA, 10);
  116.                 USART0_TX_String(StringA);
  117.                 USART0_TXD(9);
  118.                
  119.                 USART0_TX_String("R1 = ");
  120.                 itoa(R1, StringA, 10);
  121.                 USART0_TX_String(StringA);
  122.                 USART0_TXD(9);
  123.                
  124.                 print_R1();
  125.                
  126.                 _delay_ms(250);
  127.         }
  128. }
  129.  
  130. void SD_Init(void)
  131. {
  132.     SD_DIS();
  133.        
  134.     for(char i=0; i<10; i++)
  135.     {
  136.                 SPIWR(0xFF);
  137.         }
  138.         USART0_TX_String("80clk pulse done");
  139.         USART0_TXD(10);                                        
  140.         USART0_TXD(13);
  141.        
  142.         SD_EN();
  143.  
  144.         SD_CMD_Loop(0,0,0x95,1);
  145.  
  146.         USART0_TX_String("Next CMD");
  147.         USART0_TXD(10);                                        
  148.         USART0_TXD(13);
  149.        
  150.         SD_CMD_Loop(1,0,0xFF,0);
  151.  
  152.         SD_DIS();
  153.        
  154.         USART0_TX_String("SD_Init Completed");
  155.         USART0_TXD(10);                                        
  156.         USART0_TXD(13);
  157.        
  158.         _delay_ms(50);
  159.  
  160. }
  161.  
  162. int main(void)
  163. {
  164. _delay_ms(2000);
  165. USART0_Init(12);
  166. USART0_TX_String("USART Ready");
  167. USART0_TXD(10);                                        
  168. USART0_TXD(13);
  169.  
  170. SPI_Init();
  171. PORTB ^= 1<<PINB0;
  172. USART0_TX_String("SPI Ready");
  173. USART0_TXD(10);                                        
  174. USART0_TXD(13);
  175.  
  176. sei();
  177. PORTB ^= 1<<PINB0;
  178. USART0_TX_String("Int Enabled");
  179. USART0_TXD(10);                                        
  180. USART0_TXD(13);
  181.  
  182. for(unsigned int i = 0; i<10; i++)
  183. {
  184.         PORTB ^= 1<<PINB0;                                     
  185.         _delay_ms(100);
  186. }
  187.  
  188. SD_Init();
  189.  
  190.         while(1)
  191.         {
  192.                 SD_EN();
  193.                 SPIWR(0xFF);
  194.                 SD_CMD_Loop(18,0,0xFF,0);
  195.                
  196.                 USART0_TX_String("Waiting for 0xFE");
  197.                 USART0_TXD(10);                                        
  198.                 USART0_TXD(13);
  199.                
  200.                 while(R1 != 0xFE)
  201.                 {
  202.                         R1 = SPIWRD(0xFF);
  203.                         itoa(R1, StringA, 16);
  204.                         USART0_TX_String(StringA);
  205.                         USART0_TXD(9);
  206.                 }
  207.                
  208.                 USART0_TXD(10);                                        
  209.                 USART0_TXD(13);
  210.                 USART0_TX_String("Valid Data:");
  211.                 USART0_TXD(10);                                        
  212.                 USART0_TXD(13);
  213.                
  214.                 for(unsigned char i=0;i<64;i++)
  215.                 {
  216.                         for(unsigned char i=0;i<8;i++)
  217.                         {
  218.                                 R1 = SPIWRD(0xFF);
  219.                                 itoa(R1, StringA, 16);
  220.                                 USART0_TX_String(StringA);
  221.                                 USART0_TXD(9);
  222.                                 _delay_ms(250);
  223.                         }
  224.                         USART0_TXD(10);                                        
  225.                         USART0_TXD(13);
  226.                 }
  227.                 SD_DIS();
  228.                 _delay_ms(250);
  229.         }
  230. }


A kód HyperTerminalban ezt írja ki:
Idézet:
„USART Ready
SPI Ready
Int Enabled
80clk pulse done
CMD0 i = 0 R1 = 1 IDLE_STATE
Next CMD
CMD1 i = 0 R1 = 1 IDLE_STATE
CMD1 i = 1 R1 = 0
SD_Init Completed
Waiting for 0xFE
ff ff ff ff ff ff ff ff ff ff f
f ff ff ff ff ff ff ff ff ff f
f ff ff ff...”


A kérdéses rész a while(1)-ban található SD_CMD_Loop(18,0,0xFF,0); sor.
Mintha teljesen átugraná.

SB
(#) fecus válasza kapu48 hozzászólására (») Ápr 20, 2014 /
 
Köszi. Ez nem az amit kerestem. A PWM megy. Az a metódus érdekel ami kiegyenlíti a környezeti megvilágítás változását. Talán PID szabályzónak hívják? No, majd így keresem.
Azért letöltöttem.
A hozzászólás módosítva: Ápr 20, 2014
(#) Sick-Bastard válasza Sick-Bastard hozzászólására (») Ápr 20, 2014 /
 
Megvan a hiba.

  1. void SD_CMD_Loop(unsigned char cmd, unsigned long arg, unsigned char crc, unsigned char response)
  2. {
  3.         [b]R1 = 0xFF;[/b]
  4.         for(char i=0; i<10 && R1 != response; i++)
  5.         {
  6.                 SD_CMD(cmd,arg,crc);
  7.  
  8.                 [u][off]R1 = 0xFF;[/off][/u]
  9.                 R1 = SPIWRD(0xFF);
  10.                
  11.                 USART0_TX_String("CMD");
  12.                 itoa(cmd, StringA, 10);
  13.                 USART0_TX_String(StringA);
  14.                 USART0_TXD(9); ...


Rossz helyen volt az R1 újradefiniálása.
(#) killbill válasza Sick-Bastard hozzászólására (») Ápr 20, 2014 /
 
Azert van itt meg hiba. Legfokepp a makrok definialasanal.

A pontosvesszo a makrodefinico vegen nem kell, viszont neha meglepo dolgokat eredmenyez. Pl a kovetkezo kodreszlet hibaval fog fordulni:

  1. #define SETOUT()  PORTB |= 1;
  2. #define CLROUT() PORTB &= ~1;
  3.  
  4. if(valami)
  5.  SETOUT();
  6. else
  7.  CLROUT();


A masik, hogy jobb ha megszokod, hogy minden ilyen jellegu makrot bezarojelezel. Ha pl. azt irod egy makroba, hogy:
#define VALAMI 2 + 3
Aztan kesobb a programban azt irod, hogy valtozo = VALAMI * 3;
akkor a varttal ellentetben nem 5*3, hanem 11 lesz a valtozo erteke.
(#) killbill válasza Sick-Bastard hozzászólására (») Ápr 20, 2014 /
 
USART0_TX_String("PARAMETER_ERR");
USART0_TXD(9);

helyett irhatsz:

USART0_TX_String("PARAMETER_ERR\t");

10 es 13 kikuldesere a USART0_TX_String("\n\r");
Persze a szoveg vegen nem kell kulon irni, irhatod egybe is:
USART0_TX_String("Ennek a szovegnek a vegen lesz egy CR LF\r\n");
A hozzászólás módosítva: Ápr 20, 2014
(#) 06smici hozzászólása Ápr 21, 2014 /
 
Köszönöm az eddigi segítséget, valóban a CKDIV8-at felejtettem el kipipálni.

Én naívan meg azt hittem, hogy innét kezdve minden probléma megoldódott. De most meg USART-tal szívok már egy ideje. SN75176-ot raktam RS485 buszmeghajtónak rá és programból adnám ki neki a busz írásának engedéylezését.
  1. void USART_Transmit(unsigned char data)
  2.         {
  3.                 // vár amíg kiürül a küldő buffer. Majd a küldés
  4.                 // idejére engedélyezi az RS485 busz írását
  5.                 while(!(UCSR1A & (1 << UDRE1)));
  6.                 PORTD |= (1 << 0);
  7.                 _delay_us(1);
  8.                 UDR1 = data;
  9.                 while(!(UCSR1A & (1 << TXC1)));
  10.                 PORTD &= ~(1 << 0);
  11.                 _delay_us(1);
  12.         }

Ahogy a képen is látszik az AVR Tx lábán ott a kiküldött adat, de a TXC1 bit egyből jelzi,hogy végzett az adat küldésével és így az engedélyező lábon csak egy tüske jelenik meg. A busz túloldalán meg semmi az Rx vonalon.

Ezek szerint a shift regiszter kiürülése nem egyszerre történne a frame létrehozása? Mert akkor se a TXCn sem pedig az UDREn bit nem használható fel a tényleges adatküldés befejezésének észlelésére.
(#) killbill válasza 06smici hozzászólására (») Ápr 21, 2014 /
 
Nem lehet, hogy az a baj, hogy nem torlod a TXC1 bitet? Egyszer bebillen es utana ugy is marad, amig nem fut le a Transmit Complete interrupt, vagy amig le nem torlod.

Torles: UCSR1A = (1 << TXC1);
(#) 06smici válasza killbill hozzászólására (») Ápr 21, 2014 /
 
De az könnyen előfordulhat. Bíztam benne hogy ez is olyan bit ami kiolvasáskor törlődik.

A megszakítást meg pl egyáltalán nem sikerült életre keltenem. TXIE be van állítva SEI() is megvolt de egyszerűen nem hívódik meg a megszakítás vektor. Adatlapban mintha olvastam volna valamit, hogy TXC bit kell ahhoz is de az akkor nem automatikusan generálódik?
(#) killbill válasza 06smici hozzászólására (») Ápr 21, 2014 /
 
Az adatlap szerint a global interrupt-ot kell engedelyezned es a TXCIE bitet a UCSRxB-ben. Ezek utan jonnie kell a megszakitasnak, ha kikuldte a byte-ot.
(#) geri12 hozzászólása Ápr 22, 2014 /
 
Szisztok!

AVR-es szenzorpárosítás kérdés. Remélem megállja itt a helyét. Ha nem, előre is elnézést.

Van egy nyomás mérő szenzor, amit AVR-el párosítottam. A szenzor tápfeszültsége 2,2 és 3,6V között lehet. Ez rendben is van, mert 3V-os stab ic-n keresztül táplálom. Az AVR ugyanakkor 5V-ról megy. Kommunikáció i2c-n keresztül, felhúzó ellenállás 5V-on. A kérdésem az hogy a későbbiekben okozhat gondot a szenzornak hogy az SDA és SCA lábakon 5V van? (jelenleg szépen megy, nem okoz neki gondot) Vagy alkalmazzak mindenképp feszültségosztást? Köszi a választ előre is.
A hozzászólás módosítva: Ápr 22, 2014
(#) TavIR-AVR válasza geri12 hozzászólására (») Ápr 22, 2014 /
 
A 3V-os chip belső védődiódáját használod fesz. illesztésre. Nem egészséges. Ezen névlegesen 0.1mA mehet (ökölszabály). A SCL/SDA-ra meg a 10k felhúzó halovány lenne....

Szintillesztő kellene....
(#) geri12 válasza TavIR-AVR hozzászólására (») Ápr 22, 2014 /
 
Még jó hogy megkérdeztem. Valahogy éreztem hogy nem oké így, még ha jelenleg szépen is megy. Akkor csinálok egy szintillesztőt. Egyelőre úgy is csak breadboardon raktam össze, gyorsan meg is tudom hozzá csinálni.

Köszi a választ!
(#) killbill válasza geri12 hozzászólására (») Ápr 23, 2014 /
 
Olvasd el a szenzor adatlapjat! Abban le kell legyen irva a valasz. Ha nincs benne, akkor en nem engednek ra 5V-ot. Van egy egyszeru szintilleszto, azzal viszont megoldhato a dolog. Két FET (FDV301) es plusz ket ellenallas a mar meglevo ket felhuzo mellett.
(#) H2opok hozzászólása Ápr 23, 2014 /
 
Üdv
Igaz már kérdeztem,de sajna segitség nem jött.
Lehet valaki hozzáértő elsiklott felette.
Egy működő programban kellene módositani,. Ha valaki meg tudná oldani ,hálás lennék.
Itt a link,a leirás végén letölthető a program.
Bővebben: Link

Annyit kellene módositani ,hogy a másodperc visszafelé léptessen, 60 tól vissza 0 ig. Persze a perc a 0 után lépne előre.
Köszi
(#) zotyaka hozzászólása Ápr 23, 2014 /
 
Üdv!

Lenne egy elég különleges problémám amire remélem valakinek van egy épkézláb ötlete megoldásként.
Atmega32 és 24lc512 eeprom i2c-n keresztül kommunikál. Az i2c library-ban nem lehet gond (ds1307 RTC írható és olvasható ezzel a library-val) mégis egy érdekes hibám van.
Az eeprom írását követő i2c stop alatt vagy inkább után megfagy az egész mikrokontroller. Azért mondtam hogy a stop után inkább mert ha nincs benne a stop-ban a twsto figyelése. Tehát csak beállítom a stop-hoz a megfelelő regisztereket az lefut viszont nem ír az eeprom-ba. Ugyebár itt jönne az a pár ms-os várakozás az írási folyamat befejezésére vagy a twsto figyelése. Ha ez benne van akkor írás után megfagy. Ha kiveszem az írást a programból akkor az eeprom-ból visszaolvasva látható hogy beírta. (és olvasásnál sőt más egyéb i2c kommunikációnál nincs gond a stop-al). Egyedül eeprom írásnál fagy meg de maga az írás lefut tökéletesen. Viszont így ilyen formában használhatatlan.
Cseréltem mcu-t, eepromot, felhúzó ellenállást, kipróbáltam szoftveresen is scl órajel állítást, f_cpu felüldefiniálást stb. ha valamiért gondja lenne (bár ezen kívül minden tökéletesen megy) ezért vagyok elbizonytalanodva hogy mi lehet a gond hogy csak és kizárólag az eeprom írásnál fagy meg de tulajdonképpen az is végrehajtódik.
(Sajnos más típusú eeprom nincs itthon próbálni.)

Valakinek ötlet esetleg erre hogy mi okozhatja ezt a fennakadást a működésben?
Köszönöm előre is!
(#) oszlopos hozzászólása Ápr 23, 2014 /
 
Sziasztok!
Én itt új vagyok, és remélem jó helyen kopogtatok.
Van több projekt fájlom is avr studióhoz tiny 23-al, meg 25-tel, és nem értek mindent rendesen, emiatt lehet hogy nem is csinálom jól a dolgokat. Szóval ha valamelyikőtöknek volna ideje, hogy egy néhány email váltással megosszam a konkrét problémát, és van türelme egy lámához, kérem írjon nekem.
Az emailcímem publikus.
Üdv:
Szilárd
(#) geri12 válasza killbill hozzászólására (») Ápr 23, 2014 /
 
Üdv!

Épp ezért kérdeztem meg, mert nem volt benne az adatlapban, csak a tápfeszültség értékekre tért ki. A kommunikációnál csak annyit írnak hogy mennyi a max adatátviteli sebesség. Amugy nem kisérletnek szántam hogy szintillesztő nélkül kötöttem be, csak a próbapaneles szerelés közben először LCD nélkül teszteltem a szenzort, és akkor elég volt 3,3V-t az AVR-nek. Aztán jött a 2X16-os LCD, és 5V-ra kellett emelnem, és az i2c-s adatvonalat véletlen nem piszkáltam meg. Akkor szembesültem hogy így is működik, aztán tanácstalan lettem (pláne hogy adatlapban erre nem tértek ki), és utána itt megkérdeztem. A szintillesztőnél az általad megírt fet-es megoldást alkalmazom már jóideje, tehát itt sem lett másképp.
(#) Szabi1 hozzászólása Ápr 23, 2014 /
 
Sziasztok! Egy USB explrorert szerettem volna építeni, felprogramozás után nem működött.
Felraktam a fórumba rakott firmware-jét ahol először 5x vált ledet 1 sec alatt. Miután bedugom a gépbe nem ismerte fel a ledek villogtak rendesen.
Gondoltam valami fuse bit hiba lesz, és azt hiszem sikerült external clock-ra állítsam. Hogyan hozhatom vissza?
(#) Szabi1 válasza (Felhasználó 15355) hozzászólására (») Ápr 23, 2014 /
 
Van egy ilyen kapcsolásom készen ez nemjó? Bővebben: Link PWM strobi vezérlő, de azt hiszem 12V rol megyen.
A hozzászólás módosítva: Ápr 23, 2014
(#) Szabi1 válasza (Felhasználó 15355) hozzászólására (») Ápr 23, 2014 /
 
ATTINY2313 CKSEL0=0 CKSEL1,2,3=1 CKDIV8=0 SUT0=0, SUT1=0
(#) Szabi1 válasza Szabi1 hozzászólására (») Ápr 23, 2014 /
 
Jelenleg fel nem használva attiny 13A van itthon, holnap csinálok egy foglalatos panelt neki próbanyákon összedobva, irok valami PWM generátort és elvilgeg feléled a 2313 ugye?
Melyik lábára kell a 2313 nak a PWM?
Ha külső 12Mhz kristályt használnák, akkor mire kell állítani a fuse biteket?
A hozzászólás módosítva: Ápr 23, 2014
(#) Szabi1 válasza (Felhasználó 15355) hozzászólására (») Ápr 23, 2014 /
 
Hogy pontosan érthető legyen: CKSEL0=0,CKSEL1=1,CKSEL2=1,CKSEL3=1 szóval igen, most úgy van
(#) Szabi1 válasza (Felhasználó 15355) hozzászólására (») Ápr 23, 2014 /
 
Most 12Mhz es van attól függetlenűl mehet a 8 mhz helyette?
(#) Szabi1 válasza (Felhasználó 15355) hozzászólására (») Ápr 23, 2014 /
 
Másik AVR rel nem lehet helyrehozni? Mert ilyen IC-t nemigen tudok beszerezni, csak rendelni, és az hosszú idő míg lejön postán, és minél hamarabb kellene a kütyü
(#) kapu48 válasza zotyaka hozzászólására (») Ápr 23, 2014 /
 
Hi zotyaka!

Nem látjuk a kódodat! Ezért nem is tudjuk mi a hiba oka!

Viszont az adatlapot nézegetve:
512K I2C™ Serial EEPROM
10. old. 6.1 Byte Write és FIGURE 6-1: BYTE WRITE
Leírtak szerint próbálod begyömöszölni a BYTE-ket?
(#) zotyaka válasza kapu48 hozzászólására (») Ápr 24, 2014 /
 
Köszönöm a választ kapu48!

Nos kísérletezgetést követően már annyit elértem hogy 99% esélyt adok arra hogy a write-protection szól bele a dologba.
Elméletileg ha lehúzzuk a földre fixen akkor nincs írásvédelem azonban ez nem teljesen igaz legalábbis az én speciális esetemben. Tehát az írás végrehajtódik azonban befagy az egész.
Ha az írásvédelem aktiválva van akkor semmi gond, írni nem tudok de úgy olvas mint a kis angyal.
Az írásvédelem tehát betette a keresztet most a szakdolgozatomnak olyan formában hogy egyenlőre hanyagolom a külső eeprom-ot és használom a belső 1K eepromot, RFID tag tárolásra az is megteszi, beléptető rendszer eseményeit pedig tárolom egy változóban az atmega-n mind1 csak legyen kész. 1,5 napot tököltem el az eeprom írási gonddal. 100% hogy valamit én rontottam el de hogy mit?

Az írás maga:
  1. _24lc512_start(EEPROM_ID+I2C_WRITE);
  2. _24lc512_write(0x00);
  3. _24lc512_write(0xA0);
  4. _24lc512_write(0x54);
  5. _24lc512_stop();
  6. _delay_ms(10);


Tehát ez az adatlap alapján való gyömöszölésnek felel meg.
Az I2C kommunikációhoz Peter Fleury I2C library-ját használtam, azonban elkészítettem egy totál fapados verziót is ami csak a minimum igényeket szolgálja ki. Egyikkel sem ment az írás. Mind kifagyott az írás után.
Adatlapban azt láttam hogy ez az írásvédelem miatt fordulhat elő, már csak annyi a gond hogy földre van húzva így a WP tiltva van, tehát elméletileg nem szólhat bele.
(#) kapu48 válasza zotyaka hozzászólására (») Ápr 24, 2014 /
 
Az is lehet, hogy túl magas az SCL frekvenciája?

Ha a I2c_Stop-nál akad meg?
Próbálj beletenni 1 kiléptető számlálót, hogy ne álljon ott végtelenségig!
Valahogy így:
  1. void i2c_stop(void)
  2. {
  3.  
  4.     /* send stop condition */
  5.                 uint8_t   counter;
  6.                 counter = 1;
  7.                
  8.         TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
  9.  
  10.         // wait until stop condition is executed and bus released
  11.  
  12.         while((TWCR & (1<<TWSTO)) | !counter++);
  13.  
  14. }/* i2c_stop */


Ha jól gondolom, ez Counter =0-nál kiléptet.

Aztán próbálhatsz valami ellenőrző hibakeresést futtatni.

Különben működni e kellene.
A hozzászólás módosítva: Ápr 24, 2014
(#) kapu48 válasza zotyaka hozzászólására (») Ápr 24, 2014 /
 
Mivel a Te EEPROMod LC típus szerintem a Max FCLK 400Khz lehet!

Adatlap: TABLE 1-2: AC CHARACTERISTICS szerint!

Nálad ez menyire van belőve?:

  1. /*************************************************************************
  2.  
  3.  Initialization of the I2C bus interface. Need to be called only once
  4.  
  5. *************************************************************************/
  6. #define F_CPU 8000000UL /* ???? */
  7.  
  8. /* I2C clock in Hz */
  9.  
  10. #define SCL_CLOCK  100000L  /* ??? */
  11.  
  12. void i2c_init(void)
  13. {
  14.   /* initialize TWI clock: 100 kHz clock, TWPS = 0 => prescaler = 1 */
  15.  
  16.  
  17.   TWSR = 0;                         /* no prescaler */
  18.  
  19.   TWBR = ((F_CPU/SCL_CLOCK)-16)/2;  /* must be > 10 for stable operation */
  20.  
  21. }/* i2c_init */
A hozzászólás módosítva: Ápr 24, 2014
(#) killbill válasza zotyaka hozzászólására (») Ápr 24, 2014 /
 
Szia!
Iras utan ki kell adni a stop-ot, mert kulonben az EEPROM el sem kezd irni belul. De a TWSTO bitnek ehhez semmi koze. Azt, hogy mikor vegzett az EEPROM az irassal, azt onnan tudod, hogy kikuldesz egy START-ot majd az EEPROM Slave address-et, es ha erre nem kapsz ACK-ot az EEPROM-tol, akkor meg varnod kell. Ezt ismetelgeted addig, amig az EEPROM visszaadja az ACK-ot.
(#) killbill válasza kapu48 hozzászólására (») Ápr 24, 2014 /
 
Nem leptet ki counter=0-nal. Sot. ami azt illeti akkor sem mindig lept ki, ha a TWSTO bit mar torlodott, mert aritmetikai vagy kapcsolat van a ketto kozott. Inkabb igy:
  1. counter = 0;
  2. while((TWCR & (1<<TWSTO)) && ++counter != 255);


Csak ennek a modszernek van egy irto nagy hibaja, megpedig az, hogy fogalmunk sincs rola, hogy mennyi ido utan fog kilepni, hiszen csak azt tudjuk, hogy hanyszor fog a ciklus lefutni, de, hogy az mennyi ido, az rengeteg mindentol fugg. Viszont, ha a while()-ba beteszunk egy ismert ideju hivast (pl: _delay_us(10)), vagy hasonlot, akkor rendben leszunk. De lehet egy globalis timer erteket is figyelni a counter++ helyett, es akkor nem kell kulon varakozo fuggvenyt hivogatni.

--

Fuggetlenul ettol, az en emlekeimben ugy el a dolog, hogy a TWSTO bitet soha nem kellett nezni, a STOP ki fog menni, hacsak valaki le nem foldeli az SCL vonalat. Nemreg irtam LPC11xx mikrokontrollerre i2c master/slave driver-t, es abban pontosan ugyanaz az i2c blokk van, mint az AVR-ekben. A STOP kikuldeset nem kell megvarni, interruptot sem ker az i2c logika, amikor kikuldte a STOP-ot.
Következő: »»   600 / 837
Bejelentkezés

Belépés

Hirdetés
Lapoda.hu     XDT.hu     HEStore.hu
Az oldalon sütiket használunk a helyes működéshez. Bővebb információt az adatvédelmi szabályzatban olvashatsz. Megértettem