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   567 / 840
(#) csabeszq válasza adamtui_93 hozzászólására (») Szept 30, 2013 /
 
Hát, itt csatolok egy kódot, ami szoftverből programozza az AVR-t.

Ha megvan a lelkesedés és van fusebit doctorod, amivel korrigálod a szoftverhibákat, akkor rajta. Kezdetben mondjuk csak a signature-t olvasd ki, azzal kisebb valószínűséggel pusztítod szét az IC-t, mintha elsőre fuse-biteket írogatnál SPI-vel.

A hozzászólás módosítva: Szept 30, 2013
(#) zsuscsinyo válasza csabeszq hozzászólására (») Szept 30, 2013 /
 
Ezt hogyan tölti fel?

adamtui_93: Mindjárt megnézem a kódot.
(#) csabeszq válasza zsuscsinyo hozzászólására (») Szept 30, 2013 /
 
Ez az Arduino ISP programozójának forrása. A hogyan tölti fel, az egyáltalán nem érdekes, kizárólag ha szeretsz horrorsztorikat olvasni. A lényeg viszont szépen kivehető, hogy mit küldj az SPI-n a fuse bitek megváltoztatásához.
(#) adamtui_93 válasza csabeszq hozzászólására (») Szept 30, 2013 /
 
Rendeltem időközben egy másik tiny13-at. De arra gondoltam hogyha figyelem egy másik avr-el a MISO lábát az új tinynek programozás közben és azt az adatot ráküldöm erre csak lassabb akkor elméletileg működni-e kell nem?
(#) csabeszq válasza adamtui_93 hozzászólására (») Okt 1, 2013 /
 
SPI-n nincs késleltetés. Az I2C-n tudod lassítani a kommunikációt azzal, hogy az SCK lábat alacsonyban tartod, de SPI-n nem.

SPI alatt a mester (programozó) adja az órajelet. Kiküldi, hogy mit akar, ezzel _egyidőben_ beolvassa a választ.

Magyarul a programozó kiküld 4 byte-ot, az utolsó 3 byte-ot pedig egyidőben a küldéssel olvassa.

  1. /*
  2.  * Functions specific to ISP programming of an AVR
  3.  */
  4. uint16_t spi_transaction (uint8_t a, uint8_t b, uint8_t c, uint8_t d) {
  5.   uint8_t n, m;
  6.   SPI.transfer(a);
  7.   n = SPI.transfer(b);
  8.   //if (n != a) error = -1;
  9.   m = SPI.transfer(c);
  10.   return 0xFFFFFF & ((n<<16)+(m<<8) + SPI.transfer(d));
  11. }
  12.  
  13. byte SPIClass::transfer(byte _data) {
  14.   SPDR = _data;
  15.   while (!(SPSR & _BV(SPIF)))
  16.     ;
  17.   return SPDR;
  18. }
A hozzászólás módosítva: Okt 1, 2013
(#) csabeszq válasza adamtui_93 hozzászólására (») Okt 1, 2013 /
 
Bár számomra továbbra sem tiszta, hogy miért nem avrdude alatt programozod fel -b19200-zal.

Letöltöd az avrdude-t, az avr8-burn-o-mat-ot és az additional options-ök közé beírod a -b19200-at.
(#) 06smici hozzászólása Okt 1, 2013 /
 
Sziasztok. Most kezdenék komolyabban foglalkozni AVR-rekkel és nagy kérdés, hogy vegyek-e Tbird-öt (ezt használjuk egyetemen) vagy elég a Topi féle AVR dopper is. Ahogy eddig néztem Jtag előnye hogy lehet vele debugolni de az ISP-s programozó meg több avr-hez használható. Szerintetek melyiket érné meg jobban? Árban kb ugyan annyira jönnék ki ha magam építem.
(#) Massawa válasza 06smici hozzászólására (») Okt 1, 2013 / 2
 
Én a Dragont használom a legnagyobb megelégedés mellett. Csak ajánlani tudom.
(#) TavIR-AVR válasza 06smici hozzászólására (») Okt 2, 2013 /
 
TBIRD-et en elfelejteném.
Inkább Dragon, mert azon ott az ISP, HVPP/HVSP, JTAG és dW is...
És valami egyszerű M128-as panelt mellé...

Doper meg felejtős, az emulált USB miatt (+driver+firmware+AVRStudio 6.1 támogatásának korlátai miatt)

A Doper és a TBird azért nem egy árkategória....
(#) 06smici válasza TavIR-AVR hozzászólására (») Okt 2, 2013 /
 
Jó, kicsit túloztam. A doper kijön 2-3000ből +még egy mega128-as panel, ami tudja azt mint a Tbird és máris 8k körül van azért ez is

Ez a Dragon jól néz ki meg minden, csak hát az árát is elkérik elég rendesen
A Doper tényleg ennyire használhatatlan? Elég sokan írták hogy megépítették. A driveres problémák AVRStudio4-nél is vannak?
Esetleg egy STK500 vagy a TavIR AVRisp (ez nem ugyan az mint a doper ) jobb lenne?
(#) TavIR-AVR válasza 06smici hozzászólására (») Okt 2, 2013 /
 
STK500 - hardware usb-soros átalakító + egy AVR chip ami _hardware_ alapon kezel mindent.
TavIR AVRisp: A klasszikus AVR910-es hardware programozó. Csak nem RS232 sorosport, hanem FT232 USB-soros átjáróchippel.
Ugyanitt van JTAGICE is...

Tanulni akarsz? Játszadozni? Suliba kell, csak drága a TBird?
Mi a cél pontosan?


Dopernél az _emulált_ USB okoz problémát. De semmi jónak nem vagyok elrontója, mindenki a saját kárán tanul (én is így jártam... ).
(#) 06smici válasza TavIR-AVR hozzászólására (») Okt 2, 2013 /
 
Igazából mind a három a cél egyszerre. Suliba most Tbird-öt használunk de nekem nem tetszik se az ára se maga a kivitele ezekkel a szalagkábeles csatlakozókkal (már meg is van tervezve egy saját próbapanel). De szeretnék komolyabban is foglalkozni vele, nem csak amit vizsgára elvárnak.
(#) TavIR-AVR válasza 06smici hozzászólására (») Okt 2, 2013 /
 
Tipp:
TBird-et próbálj meg használtan begyűjteni - hamár a suliban alapelvárás. Sok szívástól véded meg magadat (felesleges körök).

És én debugos programozóra a Dragont tippelném - bár amennyi debug kellett az elmúlt 6 év alatt . Sima sorosport sokszor elég + a JTAGICE (ami a TBird-en van). És persze saját áramkörök - Arduino alapon.
De az induláskor használt az egyenpanelt, amit mindenki a suliban... (javaslat).

Ha kinövöd:
1, sajátot tervezel úgyis
2, TBird-et meg elpasszolod - az ára visszajön.
(#) szdani hozzászólása Okt 5, 2013 /
 
Sziasztok!
ATmega168-ra kötöttem egy DS18B20-at, és egy kijelzőre szeretném kiírni az értékét. Amit kiír nekem folyamatosan +127.9375 C. Megtudja nekem valaki mondani hogy mit rontottam el?
  1. /*
  2.  * lcdmenu.c
  3.  *
  4.  * Created: 2013.07.11. 16:03:42
  5.  *  Author: Pézsma
  6.  */
  7.  
  8.  
  9. #include <avr/io.h>
  10. #include <avr/eeprom.h>
  11. #include <avr/pgmspace.h>
  12. #include <avr/interrupt.h>
  13. #include <util/delay.h>
  14. #include <inttypes.h>
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <string.h>
  18. #include "lcd.h"
  19.  
  20.  
  21. #define F_CPU 8000000UL
  22. /* Thermometer Connections (At your choice) */
  23. #define THERM_PORT PORTC
  24. #define THERM_DDR DDRC
  25. #define THERM_PIN PINC
  26. #define THERM_DQ PC0
  27. #define THERM_INPUT_MODE() THERM_DDR&=~(1<<THERM_DQ)
  28. #define THERM_OUTPUT_MODE() THERM_DDR|=(1<<THERM_DQ)
  29. #define THERM_LOW() THERM_PORT&=~(1<<THERM_DQ)
  30. #define THERM_HIGH() THERM_PORT|=(1<<THERM_DQ)
  31. #define THERM_CMD_CONVERTTEMP 0x44
  32. #define THERM_CMD_RSCRATCHPAD 0xbe
  33. #define THERM_CMD_WSCRATCHPAD 0x4e
  34. #define THERM_CMD_CPYSCRATCHPAD 0x48
  35. #define THERM_CMD_RECEEPROM 0xb8
  36. #define THERM_CMD_RPWRSUPPLY 0xb4
  37. #define THERM_CMD_SEARCHROM 0xf0
  38. #define THERM_CMD_READROM 0x33
  39. #define THERM_CMD_MATCHROM 0x55
  40. #define THERM_CMD_SKIPROM 0xcc
  41. #define THERM_CMD_ALARMSEARCH 0xec
  42. #define THERM_DECIMAL_STEPS_12BIT 625 //.0625
  43.  
  44. uint8_t therm_reset(){
  45.         uint8_t i;
  46. //Pull line low and wait for 480uS
  47. THERM_LOW();
  48. THERM_OUTPUT_MODE();
  49. _delay_us(480);
  50. //Release line and wait for 60uS
  51. THERM_INPUT_MODE();
  52. _delay_us(60);
  53. //Store line value and wait until the completion of 480uS period
  54. i=(THERM_PIN & (1<<THERM_DQ));
  55. _delay_us(420);
  56. //Return the value read from the presence pulse (0=OK, 1=WRONG)
  57. return i;
  58. }
  59.  
  60. void therm_write_bit(uint8_t bit){
  61.         //Pull line low for 1uS
  62.         THERM_LOW();
  63.         THERM_OUTPUT_MODE();
  64.         _delay_us(1);
  65.         //If we want to write 1, release the line (if not will keep low)
  66.         if(bit) THERM_INPUT_MODE();
  67.         //Wait for 60uS and release the line
  68.         _delay_us(60);
  69.         THERM_INPUT_MODE();
  70. }
  71.  
  72. uint8_t therm_read_bit(void){
  73.         uint8_t bit=0;
  74.         //Pull line low for 1uS
  75.         THERM_LOW();
  76.         THERM_OUTPUT_MODE();
  77.         _delay_us(1);
  78.         //Release line and wait for 14uS
  79.         THERM_INPUT_MODE();
  80.         _delay_us(14);
  81.         //Read line value
  82.         if(THERM_PIN&(1<<THERM_DQ)) bit=1;
  83.         //Wait for 45uS to end and return read value
  84.         _delay_us(45);
  85.         return bit;
  86. }
  87.  
  88. uint8_t therm_read_byte(void){
  89.         uint8_t i=8, n=0;
  90.         while(i--){
  91.                 //Shift one position right and store read value
  92.                 n>>=1;
  93.                 n|=(therm_read_bit()<<7);
  94.         }
  95.         return n;
  96. }
  97. void therm_write_byte(uint8_t byte){
  98.         uint8_t i=8;
  99.         while(i--){
  100.                 //Write actual bit and shift one position right to make the next bit ready
  101.                 therm_write_bit(byte&1);
  102.                 byte>>=1;
  103.         }
  104. }
  105.        
  106.         void therm_read_temperature(char *buffer){
  107.                 // Buffer length must be at least 12bytes long! ["+XXX.XXXX C"]
  108.                 uint8_t temperature[2];
  109.                 int8_t digit;
  110.                 uint16_t decimal;
  111.                 //Reset, skip ROM and start temperature conversion
  112.                 therm_reset();
  113.                 therm_write_byte(THERM_CMD_SKIPROM);
  114.                 therm_write_byte(THERM_CMD_CONVERTTEMP);
  115.                 //Wait until conversion is complete
  116.                 while(!therm_read_bit());
  117.                 //Reset, skip ROM and send command to read Scratchpad
  118.                 therm_reset();
  119.                 therm_write_byte(THERM_CMD_SKIPROM);
  120.                 therm_write_byte(THERM_CMD_RSCRATCHPAD);
  121.                 //Read Scratchpad (only 2 first bytes)
  122.                 temperature[0]=therm_read_byte();
  123.                 temperature[1]=therm_read_byte();
  124.                 therm_reset();
  125.                 //Store temperature integer digits and decimal digits
  126.                 digit=temperature[0]>>4;
  127.                 digit|=(temperature[1]&0x7)<<4;
  128.                 //Store decimal digits
  129.                 decimal=temperature[0]&0xf;
  130.                 decimal*=THERM_DECIMAL_STEPS_12BIT;
  131.                 //Format temperature into a string [+XXX.XXXX C]
  132.                 sprintf(buffer, "%+d.%04u C", digit, decimal);
  133.    
  134.         }
  135.        
  136.  
  137. int main(void)
  138. {
  139.  
  140.         lcd_init(); // kijelző beállítása
  141.         _delay_ms(100);
  142.         lcd_contrast(0x20); // pixel erősség beállítása
  143.         PORTD |=0b11111111; // felhúzzuk a gombokat tápra
  144.  
  145.     while(1)   {
  146.                 char x[10] = {0};
  147.                 therm_read_temperature(x);
  148.                 lcd_clear();
  149.                 lcd_goto_xy(1,1);
  150.                 lcd_str(x);
  151.                 _delay_ms(1000);
  152.  
  153.        
  154.        
  155.         } //end while
  156.  
  157. } //end main
A hozzászólás módosítva: Okt 5, 2013
(#) blackdog válasza szdani hozzászólására (») Okt 5, 2013 / 1
 
Ezzel a kóddal én is próbálkoztam: Bővebben: Link
Aztán sajátba kezdtem: Bővebben: Link
Olvasd el azt is amit írtak hozzá. Most már "jól" működik.
(#) szdani válasza blackdog hozzászólására (») Okt 5, 2013 /
 
Köszönöm szépen, megpróbálom.
(#) zsozsoX hozzászólása Okt 5, 2013 /
 
Sziasztok!
PT100-at kötnék avr ADC bemenetre egyszerű feszültség osztóval jó vagy keresek más megoldást?
(#) vzoole válasza zsozsoX hozzászólására (») Okt 5, 2013 /
 
Szia!

Nem lesz ilyen egyszerű.
Max csak 1mA folyhat rajta keresztül.
Ha 5V a tápod, akkor kb 5,1k ellenállást kell vele sorbakötnöd.

20°C - 107,79 Ohm sorba kötve az 5,1k ellenállással 103,5mV kimenet.
30°C - 111,67 Ohm sorba kötve az 5,1k ellenállással 107,1mV kimenet.

Azaz 10°C változásra 3,6mV változásod lesz.

Az ADC felbontása 5V referencia esetén kb. 4,9mV.
Tehát 14°C változás fog 1 ADC érték változást eredményezni.

Megoldás az, hogy ezt a feszültséget felerősíted.
(#) csabeszq válasza TavIR-AVR hozzászólására (») Okt 7, 2013 /
 
Ez az emulált USB szerintem meg sem született volna soha, ha lenne DIP-es USB-s AVR IC.

Igazából én gondolkozom, hogy érdemes-e PIC-es mikrokontrollert használni USB-re, mert a Microchipnek vannak ilyen IC-i. Ha valakinek van tapasztalata velük, érdekelne.
(#) szdani válasza csabeszq hozzászólására (») Okt 7, 2013 /
 
Én vennék az AVR-hez próbapanelt és raknék rá tüskesort, és akkor az is kiépíthető. Nekem egy elektromérnök azt mondta hogy komoly eszközökben nem célszerű PIC-et használni mert szerinte nem megbízható. Az én iparágamban csak Philips vagy Atmel kontrollerekkel találkoztam. Van olyan gép hogy ha rádugod a pendrive-ot akkor az USB-s AVR újraírja a többit.
(#) matheattila válasza szdani hozzászólására (») Okt 7, 2013 /
 
Idézet:
„...komoly eszközökben nem célszerű PIC-et használni mert szerinte nem megbízható.”
Nem tudom ezt honnan veszi az a mérnök, mivel az AVR is pont olyan mikrovezérlő, mint a PIC, sőt a PIC-ek még sokkal hamarabb is megjelentek mint az AVR-ek.
Szerintem pedig a PIC-ek jobbak, meg amúgy is eddig több eszközben találkoztam velük, mint AVR-el. A másik előnye a PIC-eknek, hogy sokkal nagyobb a választék a mikrovezérlők terén.
(#) zombee válasza szdani hozzászólására (») Okt 7, 2013 /
 
-1
Ez nettó hülyeség. Valószínű hogy az illető AVR-ekhez sem ért. Ha már ipari cucc:
868MHz-es rádió paneleket (is) gyártunk. Az adóban AVR van, a vevőben PIC.
Annyi biztos hogy az AVR sleep módban nagyon keveset eszik az elemes adóáramkörben,
míg a vevőben lévő PIC állandóan ketyeg, de nem gond mert hálózatról megy...
(#) csabeszq hozzászólása Okt 8, 2013 /
 
Egy védődiódás kérdésem lenne.

A P-csatornás MOSFET alapból úgy készül el, hogy D->S a kapcsolható rész, S->D az dióda.

(IRF9Z34, Continuous Source-Drain Diode Current -18A)

Ha mondjuk 12V-on motort kapcsolgatok (12V -> pfet -> motor -> 0V), akkor kihasználható-e az, hogy úgyis ott van a MOSFET ellentétes irányú diódája, egy kicsit megugrik a feszültség 12.7V-ra, de az mind befolyik a VDD-re.

Kell-e védődióda, ha a MOSFET-ben egyébként is benne van? (nem egy kellene, hanem 32, ezért ha lehet kihagynám)
A hozzászólás módosítva: Okt 8, 2013
(#) killbill válasza csabeszq hozzászólására (») Okt 8, 2013 /
 
A motorbol a VDD fele hasznalhatod, persze. De az ellen semmi nem ved, amikor a motor minuszba megy el (akár csak egy impulzusnyi idore), azaz a FET-ed drain-jet leviszi minusz akarhany voltra. Ha azt a feszultseget hozzaadaod a VDD-hez, akkor megkapod, hogy mennyi van a D es S kozott. Annak nem kellene atlepni a 60 voltot. Szoval a motorral parhuzamosan egy forditott dioda hasznos lehet.
(#) kapu48 válasza csabeszq hozzászólására (») Okt 8, 2013 /
 
Kihagyhatod?

De akkor úgy tervezd meg, hogy roncsolás nélkül tudjál Feteket cserélni!
Mert az egész áramkört cserélni drága kísérlett lesz!
(#) csabeszq válasza killbill hozzászólására (») Okt 8, 2013 /
 
A kérdés H bridge-re vonatkozott, csak kissé ügyetlenül tettem fel:

A diódák eleve benne vannak a fet-ekben, akkor a külső dióda (1N4004) mennyi pluszt tesz hozzá az áramkörhöz?
A hozzászólás módosítva: Okt 8, 2013
(#) killbill válasza csabeszq hozzászólására (») Okt 8, 2013 /
 
Az 1N4004 pár grammot, de azon kivul semmit, mert aramban kisebb es szerintem lassabb is, mint a FET body diodaja. Szoval, ha ilyen H-Bridge-ed van, akkor szerintem a kulso 1N4004 teljesen felesleges. Olyat mar lattam (digitalis vegfokokban), hogy Schottky dioda volt parhuzamosan a FET-tel, mert eleve kisebb a nyitofeszultsege, es iszonyu gyors, tehat a tuskek ellen megvedi a FET-et.
A hozzászólás módosítva: Okt 8, 2013
(#) palomatE hozzászólása Okt 8, 2013 /
 
Sziasztok!
Adott egy tbird2 (Bővebben: Link) és a hozzá tartozó kiegészítő panel (Bővebben: Link).

Szeretnék olyan programot írni C-ben, amely a teljes processzoridő felhasználása nélkül a 4db 7 szegmenses kijelzőkön tart bizonyos értékeket, miközben más feladat is végrehajtódhat.
Az A port ilyen formában értelmezi a bináris adatot: XYYYZZZZ, ahol X az engedélyezés, Y a 4 kijelző valamelyikének címe, a Z pedig a tényleges számadat
Jelenleg az alábbi kód végzi a dolgát:
  1. void szegmBIN(unsigned int z)
  2. {    int k; unsigned char x[4],i,j=25; //j-szer gyújtjuk ki mind a 4 szegmenst
  3.     //integer számjegyeit tömb elemeibe teszem.
  4.     for(i=0,k=1;i<4;i++,k=k*10) x[i]=(z/k)%10; // 4 db számjegy
  5.    
  6.      //4 digit kijelzése j alkalommal (j*20 msec)  
  7.      while(j--)     // a kijelzés 25*5*4=500 msec
  8.      {    for(i=0;i<4;i++)
  9.          {   PORTA=128+(i<<4)+x[i];  //digitek kijelzése
  10.              _delay_ms(5);
  11.          }      
  12.      }
  13. }
  14.  
  15. int main()
  16. {
  17.         unsigned int x=1111;
  18.  DDRA=0xFF;
  19.  while (1) szegmBIN(x); //folyamatosan kiírja: 1111
  20.  return 0;
  21. }

A 7 szegmenses kijelzőkön olvasható adat csak alkalmanként szorulna frissítésre, addig pedig folyamatosan meg kell jelenjen.
Hogyan tudnám hatékonyabbá tenni a kódot?

edit: linkek
A hozzászólás módosítva: Okt 8, 2013
(#) benjami válasza palomatE hozzászólására (») Okt 8, 2013 /
 
Használni kell az időzítő megszakítását. Pl:
  1. // órajel forrás frekvencia (most 16MHz)
  2. #define  TimerSrcClock (1UL*16000000)
  3.  
  4. // 200 megszakítás/sec (5msec)
  5. #define  TIMECLK    200
  6.  
  7. #include <avr/io.h>
  8. #include <avr/interrupt.h>
  9. #include <string.h>
  10. #include <stdlib.h>
  11.  
  12. volatile unsigned char x[4];  // ez kerül a kijelzőre
  13.  
  14. ISR (TIMER1_COMPA_vect)
  15. {
  16.   static unsigned char y = 0; // aktuális karakter (0..3)
  17.   PORTA &= ~(1 << 7);         // kijelzés ki
  18.   PORTA = (y << 4) + x[y};    // karakter cím és érték ki
  19.   PORTA |=  (1 << 7);         // kijelzés be
  20.   y++;
  21.   if (y > 3) y = 0;
  22. }
  23.  
  24. void timerinit(void)
  25. {
  26.   // időzítő inicializálása
  27.   #define  TIMEDIV ((TimerSrcClock+TIMECLK/2)/TIMECLK-1)
  28.   #if TIMEDIV < 65536
  29.   #define TMCLKDIV         1
  30.   #define TMCLKSEL         1
  31.   #elif TIMEDIV < (65536*8)
  32.   #define TMCLKDIV         8
  33.   #define TMCLKSEL         2
  34.   #elif TIMEDIV < (65536*64)
  35.   #define TMCLKDIV        64
  36.   #define TMCLKSEL         3
  37.   #elif TIMEDIV < (65536*256)
  38.   #define TMCLKDIV       256
  39.   #define TMCLKSEL         4
  40.   #elif TIMEDIV < (65536*1024)
  41.   #define TMCLKDIV      1024
  42.   #define TMCLKSEL         5
  43.   #endif // TIMEDIV
  44.   #define TMCOMP (((TimerSrcClock/TMCLKDIV)+TIMECLK/2)/TIMECLK-1)
  45.   OCR1AH = TMCOMP >> 8;                 // comparator HI
  46.   OCR1AL = (unsigned char)TMCOMP;       // comparator LO
  47.   TCCR1A = (0<<WGM10);                  // mode4 (CTC)
  48.   TCCR1B = (1<<WGM12)|(TMCLKSEL<<CS10); // mode4, Clk = ClkIO/1..8..64..256..1024
  49.   #ifdef TIMSK1
  50.   TIMSK1 = (1<<OCIE1A);
  51.   #else  // TIMSK1
  52.   TIMSK |= (1<<OCIE1A);
  53.   #endif // TIMSK1
  54.   sei();
  55. }
  56.  
  57. int main(void)
  58. {
  59.   int k; unsigned char i;
  60.   unsigned int z = 1111;
  61.   for(i=0,k=1;i<4;i++,k=k*10) x[i]=(z/k)%10; // 4 db számjegy
  62.   DDRA=0xFF;
  63.   timerinit();
  64.   while (1)
  65.   {
  66.         // ide mehet bármi, a megszakításból folyamatosan frissül a kijelző
  67.   }
  68. }
A hozzászólás módosítva: Okt 8, 2013
(#) Suncorgo hozzászólása Okt 9, 2013 /
 
Sziasztok!

Legalább egy napom már ráment az Atmel által publikált TWI driverek működésre bírásával.
Lassan kívülről fújom a doksit is és a kódot is. Miért nem működik? Mit nézek el?

Adó:
  1. #define F_CPU 16000000UL
  2. #include <avr/io.h>
  3. #include <avr/interrupt.h>
  4. #include <util/delay.h>
  5. #include "TWI_Master.h"
  6.  
  7. #define TWI_GEN_CALL         0x00  // The General Call address is 0
  8.  
  9. // Sample TWI transmission commands
  10. #define TWI_CMD_MASTER_WRITE 0x10
  11. #define TWI_CMD_MASTER_READ  0x20
  12.  
  13. // Sample TWI transmission states, used in the main application.
  14. #define SEND_DATA             0x01
  15. #define REQUEST_DATA          0x02
  16. #define READ_DATA_FROM_BUFFER 0x03
  17.  
  18. unsigned char TWI_Act_On_Failure_In_Last_Transmission ( unsigned char TWIerrorMsg )
  19. {
  20.         // A failure has occurred, use TWIerrorMsg to determine the nature of the failure
  21.         // and take appropriate actions.
  22.         // Se header file for a list of possible failures messages.
  23.        
  24.         // Here is a simple sample, where if received a NACK on the slave address,
  25.         // then a retransmission will be initiated.
  26.        
  27.         if ( (TWIerrorMsg == TWI_MTX_ADR_NACK) | (TWIerrorMsg == TWI_MRX_ADR_NACK) )
  28.         TWI_Start_Transceiver();
  29.        
  30.         return TWIerrorMsg;
  31. }
  32.  
  33. #define SW1  !(PINB & (1<<PINB0))
  34.  
  35. void PortIrany()
  36. {
  37.         PORTB |= (1<<PB0); //felhúzóellenállás be
  38. }
  39.  
  40. int main(void)
  41. {
  42.         PortIrany();
  43.        
  44.         unsigned char messageBuf[TWI_BUFFER_SIZE];
  45.         unsigned char TWI_targetSlaveAddress   = 0x10
  46.         unsigned char TWI_operation=0;
  47.        
  48.         TWI_Master_Initialise();
  49.         sei();
  50.        
  51.     while(1)
  52.     {
  53.         if(SW1)
  54.                 {
  55.                         messageBuf[0] = (TWI_targetSlaveAddress<<TWI_ADR_BITS) | (FALSE<<TWI_READ_BIT);
  56.                         messageBuf[1] = 0;
  57.                         TWI_Start_Transceiver_With_Data( messageBuf, 2 );
  58.                         _delay_ms(500);
  59.                        
  60.                         messageBuf[0] = (TWI_targetSlaveAddress<<TWI_ADR_BITS) | (FALSE<<TWI_READ_BIT);
  61.                         messageBuf[1] = 1;
  62.                         TWI_Start_Transceiver_With_Data( messageBuf, 2 );
  63.                         _delay_ms(500);
  64.                 }
  65.                
  66.                 if ( ! TWI_Transceiver_Busy() )
  67.                 {
  68.                         // Check if the last operation was successful
  69.                         if ( TWI_statusReg.lastTransOK )
  70.                         {
  71.                                 if ( TWI_operation ) // Section for follow-up operations.
  72.                                 {
  73.                                         // Determine what action to take now
  74.                                         if (TWI_operation == REQUEST_DATA)
  75.                                         { // Request/collect the data from the Slave
  76.                                                 messageBuf[0] = (TWI_targetSlaveAddress<<TWI_ADR_BITS) | (TRUE<<TWI_READ_BIT); // The first byte must always consit of General Call code or the TWI slave address.
  77.                                                 TWI_Start_Transceiver_With_Data( messageBuf, 2 );
  78.                                                 TWI_operation = READ_DATA_FROM_BUFFER; // Set next operation
  79.                                         }
  80.                                         else if (TWI_operation == READ_DATA_FROM_BUFFER)
  81.                                         { // Get the received data from the transceiver buffer
  82.                                                 TWI_Get_Data_From_Transceiver( messageBuf, 2 );
  83.                                                 //PORTB = messageBuf[1];        // Store data on PORTB.
  84.                                                 TWI_operation = FALSE;        // Set next operation
  85.                                         }
  86.                                 }
  87.                         }
  88.                         else // Got an error during the last transmission
  89.                         {
  90.                                 // Use TWI status information to detemine cause of failure and take appropriate actions.
  91.                                 TWI_Act_On_Failure_In_Last_Transmission( TWI_Get_State_Info( ) );
  92.                         }
  93.                 }
  94.     }
  95. }


Vevő:
  1. #include <avr/io.h>
  2. #include <avr/interrupt.h>
  3. #include "TWI_slave.h"
  4.  
  5. // Sample TWI transmission commands
  6. #define TWI_CMD_MASTER_WRITE 0x10
  7. #define TWI_CMD_MASTER_READ  0x20
  8.  
  9. //Led
  10. #define LedBe   PORTB |= (1<<PB0)
  11. #define LedKi   PORTB &= ~(1<<PB0)
  12.  
  13. unsigned char TWI_Act_On_Failure_In_Last_Transmission ( unsigned char TWIerrorMsg )
  14. {
  15.         // A failure has occurred, use TWIerrorMsg to determine the nature of the failure
  16.         // and take appropriate actions.
  17.         // Se header file for a list of possible failures messages.
  18.        
  19.         // This very simple example puts the error code on PORTB and restarts the transceiver with
  20.         // all the same data in the transmission buffers.
  21.         PORTB = TWIerrorMsg;
  22.         TWI_Start_Transceiver();
  23.        
  24.         return TWIerrorMsg;
  25. }
  26.  
  27. int main(void)
  28. {
  29.         DDRB |= (1<<PB0); //PB0 kimenet
  30.        
  31.         uint8_t TWI_slaveAddress = 0x10;
  32.         uint8_t messageBuf[1];
  33.        
  34.         TWI_Slave_Initialise( (unsigned char)((TWI_slaveAddress<<TWI_ADR_BITS) | (FALSE<<TWI_GEN_BIT) ));//TWI indítás (slave cím megadás és általános hívás fogadásának engedélyezése)
  35.         sei();
  36.        
  37.        
  38.         // Start the TWI transceiver to enable reception of the first command from the TWI Master.
  39.         TWI_Start_Transceiver();
  40.        
  41.        
  42.        
  43.     while(1)
  44.     {
  45.         if ( ! TWI_Transceiver_Busy() )
  46.         {
  47.                 if ( TWI_statusReg.RxDataInBuf )
  48.                 {
  49.                         TWI_Get_Data_From_Transceiver(messageBuf, 1);
  50.                        
  51.                                 if(messageBuf[0]==1)
  52.                                 {
  53.                                         LedBe;
  54.                                 }
  55.                                
  56.                                 if(messageBuf[0]==0)
  57.                                 {
  58.                                         LedKi;
  59.                                 }
  60.                 }
  61.         }
  62.     }
  63. }


Mit nézek el?

kapcsolódó doksik:
AVR315: Using the TWI module as I2C master - Atmel Corporation Bővebben: Link

AVR311: Using the TWI module as I2C slave - Atmel Corporation Bővebben: Link
A hozzászólás módosítva: Okt 9, 2013
Következő: »»   567 / 840
Bejelentkezés

Belépés

Hirdetés
XDT.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