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   625 / 837
(#) nolex hozzászólása Okt 29, 2014 /
 
Sziasztok.

Egyszerűen nem jutok dűlőre. I2C-t élesztek egy atmega168-on 3,3v-os üzemfeszen. a célpont egy 24aa32a Bővebben: Link
EEPROM. De más I2C eszköz se megy.
Az itteni TWI cikkből indultam ki, az általa ajánlott drivert használom. Az alábbi linken eléritek a projekt fájlt: Kód
A helyzet a következő: a startjel + a cím kimegy, analóg szkópon szépen látom. Viszont nem jön ACK. Sehogy se jön.
A driver megakad az ACK várásba és folyamatosan küldi ki a címet(így látom az egész frame-et az analóg szkópon.).

Se MPU 6050, se ez a pofon egyszerű EEPROM. kizárt h hibás legyen, ma vettem.
A felhúzó ellenállás 2,2K, üzemfesz 3,3V stabilan.


3 napja ezzel szenvedek. MIÉRT?
Mit tudnék még megnézi?
Köszönöm!
(#) killbill válasza nolex hozzászólására (») Okt 30, 2014 /
 
Ha latod szkopon, hogy kimegy a START es a SLAVE address, es megsem jon ACK, akkor lehet, hogy egyszeruen rossz a slave address. Az A0..A2 labak hol vannak? Mit latni a szkopon, mi a kikuldott cim? Ja, es mennyi az orajel sebesseg?
(#) jimmi12 hozzászólása Okt 30, 2014 /
 
Sziasztok,

Egy kis segítségre lenne szükségem, nemrég kezdtem el Arduino-val foglakozni és már az első komolyabb feladatnál elakadtam. Készítettem egy egyszerű kis áramkört 4db bemenet 4db kimenet, soros port. A program lényege, hogy soros port-ról tudjam kapcsolni a reléket ill. lekérdezni a bemeneteket. A fejlesztéshez Arduino Uno-t használtam, a program működött rajta. Szerettem volna ezt a progit feltölteni a "valós" környezetébe, ugyanis készült hozzá egy nyák amin minden rajta van, többek között egy Attiny2313 vezérlő. Ekkor jött a feketeleves, a fordító szerint a 24. sorban van egy hiba "class Hardwareserial has no nember named readStringUntil" Több megoldást is próbáltam, de sajnos nemtudok rájönni a hiba okára. A másik gondd, hogy szerintem a program nemfog beleférni a prociba, amit nemigazán értek miért....

Üdv.: Imi

Relay_avr.ino
    
(#) zsolt58 válasza Jaedong hozzászólására (») Okt 30, 2014 /
 
Akkor ha atmega16-ot használok aakkor kevesebb tábfesz kell neki csak anyi a különbség?
(#) TavIR-AVR válasza jimmi12 hozzászólására (») Okt 30, 2014 /
 
Arduino minimum memóriaigény: 1k. ATTiny: 128 byte
Flash igény: 2...5k. Tinyben van 2k.
Arduino _NEM_ támogat más chipet: M8,168,328,32u4,1280,2560.
Azaz a Tinyre a fejlesztési irányod rossz.
(#) kapu48 válasza jimmi12 hozzászólására (») Okt 30, 2014 /
 
Az Arduino nem támogatja az Attiny2313-ast!
A leg kisseb lehetőség ATMega8-as. Használd azt.

Vagy írd meg a programod Asemblerben.
(#) sucuka hozzászólása Okt 30, 2014 /
 
Tisztelt fórumtársak!

Nem fejlesztek AVR-re, és egyelőre más mikrokontrollerre sem, a problémámra úgy érzem, mégis itt kaphatok segítséget:

Rendelkezésre áll egy lefordított hex-fájl, ami egy ATMEGA8-ra írt programot, és a hozzá tartozó eeprom-tartalmat "rejti". Ezt kellene felírnom egy ATMEGA8-ra, de nem a fejlesztőkörnyezetből, hanem egy XELTEK SUPERPRO programozóval, mely egy univerzális eszköz, azaz gyakorlatilag több, mint 30000-féle IC-t támogat, köztük természetesen az ATMEGA8-at is.

A problémát az okozza, hogy az említett .hex-fájl egyben tartalmazza magát a flash-részbe kerülő programot, és az eep-tartalmat is, nekem viszont a XELTEK kezelőprogramjába két külön bufferbe kell betöltenem a két memória tartalmát, majd felprogramozni azt.

Az tehát a kérdés, hogy lehetőség van-e valamilyen módon különválasztani a fájlból a két részt. Próbálok keresgélni, de persze ez időbe telik, így minden lehetséges segítséget szívesen fogadok.

Köszi!
(#) TavIR-AVR válasza sucuka hozzászólására (») Okt 31, 2014 /
 
A standard HEX az a szabvány szerint nem tartalmazza az EPP-t. 2 külön állomány adott ilyenkor:
HEX - programkód
EPP - EEprom file

A lefordítást mivel csinálták? Hátha az a program saját formátumát kaptad meg...
(#) sucuka válasza TavIR-AVR hozzászólására (») Okt 31, 2014 /
 
Köszi, így lehet, hogy tisztább a kép, ugyanis én csak egy fájlt kaptam, de annak ".eep" a kiterjesztése nem ".epp". Nem lehet, hogy te is azt akartad írni?

Az EEPROM-ba kerülő tartalom milyen formátumban kerül ki a fordítóból? Mert a mellékelt állomány szerint ez is HEX.
(#) tkovacs válasza sucuka hozzászólására (») Okt 31, 2014 /
 
Szia Sucuka!

Igen, minden bizonnyal TavIR is .EEP kiterjesztést szeretett volna írni.
A programkód (*.hex) és az EEPROM tartalom is (*.eep) jobbára Intel hexa formátumú fájlok.
Szövegszerkesztővel kimásolhatóak belőle egyes sorok, amelyeket lehet, hogy valami offset értékkel kell betölteni a külső programozód memóriájába. Ezeket a memória címeket a programozókból meg lehet tudni amikor kiválsztjuk a programozandó eszközt. Az én WELLON programozómnál is így van.
(#) zsolt58 válasza zsolt58 hozzászólására (») Okt 31, 2014 1 /
 
HAHO
Válaszolna valaki?
(#) killbill válasza zsolt58 hozzászólására (») Okt 31, 2014 /
 
Nem hiszem, hogy igy barki valaszolni fog...
(#) varttina válasza zsolt58 hozzászólására (») Okt 31, 2014 /
 
Mindkét AVR működik alacsonyabb tápfeszültségről is, viszont kisebb órajellel. Minden AVR adatlapján rajta van, hogy mekkora feszültség esetén mekkora a maximális órajel.
(#) Ricsi89 hozzászólása Okt 31, 2014 /
 
Sziasztok!
Van egy apró problémám. Van egy órám, egy rtc-ből olvasom az időt és vfd-n jeleníti meg. Ezzel nincs is gond. Viszont automatikus nyári-téli átállást csináltam bele, de nem működik. Minden érték jó, de nem hajtódik végre. Itt a kódrészlet, hátha valaki megtalálja a gondot.
  1. void atallit(){
  2.         datum();
  3.  
  4.                 if((idoszamitas==1) && (honap==3) && (nap>=25) && (hetnap==7) && (hour==2)){
  5.                         I2C_write(0x02, 0x03);
  6.                         idoszamitas = 2;
  7.                         EEPROM_write(0x01, 2);
  8.                 }
  9.  
  10.                 if((idoszamitas==2) && (honap==10) && (nap>=25) && (hetnap==7) && (hour==3)){
  11.                         I2C_write(0x02, 0x02);
  12.                         idoszamitas = 1;
  13.                         EEPROM_write(0x01, 1);
  14.                        
  15.                 }
  16.                
  17. }
A hozzászólás módosítva: Okt 31, 2014
(#) killbill válasza Ricsi89 hozzászólására (») Okt 31, 2014 /
 
Ennyi kodbol nehez megmondani. A honap, nap, ora, stb. nem BCD veletlenul? Mert akkor honap == 0x10 kellene. Meg nap >= 0x25. Az idoszamitas-t felolvassa EEPROM-bol? Jo az erteke?
(#) Ricsi89 válasza killbill hozzászólására (») Okt 31, 2014 /
 
Ebben lehet igazad van, hiszen bcd átalakító van hajtva az avr-ről plusz hexában van kiolvasva az érték is. Tudtam én, hogy valami apróságot nem veszek észre.
(#) k3gy3tl3n hozzászólása Nov 1, 2014 /
 
Sziasztok, atmega8 uC-el szeretnék egy pwm-es áram generátort építeni amivel tudom szabályozni egy DC motor áramát (kb 800mA) amit akkumulátorról (20V 1,5 Ah) szeretnék hajtani.Tudnátok kapcsolási rajzot mutatni/linkelni? Köszönöm előre is!
(#) wbt válasza k3gy3tl3n hozzászólására (») Nov 2, 2014 / 1
 
Szia! L293D még elbírja, L298 biztosan (ST gyárt 1 hidat is 6318 vagy mi, de azok drágábbak), L293E-nél ki van vezetve árammérő ellenállásnak a híd alsó fele, de irreálisan drága.
Ha nem kell forgásirány váltás, akkor egy IRFZxxx NFET, GND felé egy árammérő 0.3-0.6ohm.
(#) Droot hozzászólása Nov 2, 2014 /
 
Sziasztok!

KS0108 grafikus LCD-t szeretnék vezérelni. A jól bevált library-m most sajnos nem jó:
lcd.c
  1. #include <inttypes.h>
  2. #include <avr/io.h>
  3. #include <avr/pgmspace.h>
  4. #include "ks0108.h"
  5.  
  6. lcdCoord                        ks0108Coord;
  7. uint8_t                         ks0108Inverted=0;
  8. ks0108FontCallback      ks0108FontRead;
  9. uint8_t                         ks0108FontColor;
  10. const uint8_t*          ks0108Font;
  11.  
  12.  
  13. uint8_t Reverse( uint8_t x )
  14. {
  15.     x = ((x >> 1) & 0x55) | ((x << 1) & 0xaa);
  16.     x = ((x >> 2) & 0x33) | ((x << 2) & 0xcc);
  17.     x = ((x >> 4) & 0x0f) | ((x << 4) & 0xf0);
  18.     return x;    
  19. }
  20.  
  21. uint8_t ks0108ReadFontData(const uint8_t* ptr) {
  22.         return pgm_read_byte(ptr);
  23. }
  24.  
  25. void ks0108SelectFont(const char* font, ks0108FontCallback callback, uint8_t color) {
  26.         ks0108Font = font;
  27.         ks0108FontRead = callback;
  28.         ks0108FontColor = color;
  29. }
  30.  
  31. int ks0108PutChar(char c) {
  32.         uint8_t width = 0;
  33.         uint8_t height = ks0108FontRead(ks0108Font+FONT_HEIGHT);
  34.         uint8_t bytes = (height+7)/8;
  35.        
  36.         uint8_t firstChar = ks0108FontRead(ks0108Font+FONT_FIRST_CHAR);
  37.         uint8_t charCount = ks0108FontRead(ks0108Font+FONT_CHAR_COUNT);
  38.        
  39.         uint16_t index = 0;
  40.         uint8_t x = ks0108Coord.x, y = ks0108Coord.y;
  41.        
  42.         if(c < firstChar || c >= (firstChar+charCount)) {
  43.                 return 1;
  44.         }
  45.         c-= firstChar;
  46.        
  47.         // read width data, to get the index
  48.         for(uint8_t i=0; i<c; i++) {
  49.                 index += ks0108FontRead(ks0108Font+FONT_WIDTH_TABLE+i);
  50.         }
  51.         index = index*bytes+charCount+FONT_WIDTH_TABLE;
  52.         width = ks0108FontRead(ks0108Font+FONT_WIDTH_TABLE+c);
  53.        
  54.         // last but not least, draw the character
  55.         for(uint8_t i=0; i<bytes; i++) {
  56.                 uint8_t page = i*width;
  57.                 for(uint8_t j=0; j<width; j++) {
  58.                         uint8_t data = ks0108FontRead(ks0108Font+index+page+j);
  59.                        
  60.                         if(height < (i+1)*8) {
  61.                                 data >>= (i+1)*8-height;
  62.                         }
  63.                        
  64.                         if(ks0108FontColor == BLACK) {
  65.                                 ks0108WriteData(data);
  66.                         } else {
  67.                                 ks0108WriteData(~data);
  68.                         }
  69.                 }
  70.                 // 1px gap between chars
  71.                 if(ks0108FontColor == BLACK) {
  72.                         ks0108WriteData(0x00);
  73.                 } else {
  74.                         ks0108WriteData(0xFF);
  75.                 }
  76.                 ks0108GotoXY(x, ks0108Coord.y+8);
  77.         }
  78.         ks0108GotoXY(x+width+1, y);
  79.        
  80.         return 0;
  81. }
  82.  
  83. void ks0108Puts(char* str) {
  84.         int x = ks0108Coord.x;
  85.         while(*str != 0) {
  86.                 if(*str == '\n') {
  87.                         ks0108GotoXY(x, ks0108Coord.y+ks0108FontRead(ks0108Font+FONT_HEIGHT));
  88.                 } else {
  89.                         ks0108PutChar(*str);
  90.                 }
  91.                 str++;
  92.         }
  93. }
  94.  
  95. uint8_t ks0108CharWidth(char c) {
  96.         uint8_t width = 0;
  97.         uint8_t firstChar = ks0108FontRead(ks0108Font+FONT_FIRST_CHAR);
  98.         uint8_t charCount = ks0108FontRead(ks0108Font+FONT_CHAR_COUNT);
  99.        
  100.         // read width data
  101.         if(c >= firstChar && c < (firstChar+charCount)) {
  102.                 c -= firstChar;
  103.                 width = ks0108FontRead(ks0108Font+FONT_WIDTH_TABLE+c)+1;
  104.         }
  105.        
  106.         return width;
  107. }
  108.  
  109. uint16_t ks0108StringWidth(char* str) {
  110.         uint16_t width = 0;
  111.        
  112.         while(*str != 0) {
  113.                 width += ks0108CharWidth(*str++);
  114.         }
  115.        
  116.         return width;
  117. }
  118.  
  119. void ks0108GotoXY(uint8_t x, uint8_t y) {
  120.         uint8_t chip = CHIP1, cmd;
  121.        
  122.         if(x > 127) x = 0;                                                              // ensure that coordinates are legal
  123.         if(y > 63)  y = 0;
  124.        
  125.         ks0108Coord.x = x;                                                              // save new coordinates
  126.         ks0108Coord.y = y;
  127.         ks0108Coord.page = y/8;
  128.        
  129.         if(x >= 64) {                                                                   // select the right chip
  130.                 x -= 64;
  131.                 chip = CHIP2;
  132.         }
  133.         cmd = LCD_SET_ADD | x;
  134.         ks0108WriteCommand(cmd, chip);                                  // set x address on active chip
  135.        
  136.         cmd = LCD_SET_PAGE | ks0108Coord.page;                  // set y address on both chips
  137.         ks0108WriteCommand(cmd, CHIP1);
  138.         ks0108WriteCommand(cmd, CHIP2);
  139. }
  140.  
  141. void ks0108Init(uint8_t invert) {
  142.         ks0108Coord.x = 0;
  143.         ks0108Coord.y = 0;
  144.         ks0108Coord.page = 0;
  145.        
  146.         ks0108Inverted = invert;
  147.        
  148.         LCD_CMD_DIR = 0xFF;                                                             // command port is output
  149.         LCD_CS_DIR = (1<<CSEL1) | (1<<CSEL2);
  150.         ks0108WriteCommand(LCD_ON, CHIP1);                              // power on
  151.         ks0108WriteCommand(LCD_ON, CHIP2);
  152.        
  153.         ks0108WriteCommand(LCD_DISP_START, CHIP1);              // display start line = 0
  154.         ks0108WriteCommand(LCD_DISP_START, CHIP2);
  155.         ks0108ClearScreen();                                                    // display clear
  156.         ks0108GotoXY(0,0);
  157. }
  158.  
  159. inline void ks0108Enable(void) {
  160.         LCD_CMD_PORT |= 0x01 << EN;                                             // EN high level width: min. 450ns
  161.         asm volatile("nop\n\t"
  162.                                  "nop\n\t"
  163.                                  "nop\n\t"
  164.                                  ::);
  165.         LCD_CMD_PORT &= ~(0x01 << EN);
  166.         for(volatile uint8_t i=0; i<8; i++);                    // a little delay loop (faster than reading the busy flag)
  167. }
  168. void ks0108FillRect(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t color) {
  169.         uint8_t mask, pageOffset, h, i, data;
  170.         height++;
  171.        
  172.         pageOffset = y%8;
  173.         y -= pageOffset;
  174.         mask = 0xFF;
  175.         if(height < 8-pageOffset) {
  176.                 mask >>= (8-height);
  177.                 h = height;
  178.         } else {
  179.                 h = 8-pageOffset;
  180.         }
  181.         mask <<= pageOffset;
  182.        
  183.         ks0108GotoXY(x, y);
  184.         for(i=0; i<=width; i++) {
  185.                 data = ks0108ReadData();
  186.                
  187.                 if(color == BLACK) {
  188.                         data |= mask;
  189.                 } else {
  190.                         data &= ~mask;
  191.                 }
  192.  
  193.                 ks0108WriteData(data);
  194.         }
  195.        
  196.         while(h+8 <= height) {
  197.                 h += 8;
  198.                 y += 8;
  199.                 ks0108GotoXY(x, y);
  200.                
  201.                 for(i=0; i<=width; i++) {
  202.                         ks0108WriteData(color);
  203.                 }
  204.         }
  205.        
  206.         if(h < height) {
  207.                 mask = ~(0xFF << (height-h));
  208.                 ks0108GotoXY(x, y+8);
  209.                
  210.                 for(i=0; i<=width; i++) {
  211.                         data = ks0108ReadData();
  212.                
  213.                         if(color == BLACK) {
  214.                                 data |= mask;
  215.                         } else {
  216.                                 data &= ~mask;
  217.                         }
  218.        
  219.                         ks0108WriteData(data);
  220.                 }
  221.         }
  222. }
  223. uint8_t ks0108DoReadData(uint8_t first) {
  224.         uint8_t data;
  225.         volatile uint8_t i;
  226.        
  227.         LCD_DATA_OUT = 0x00;
  228.         LCD_DATA_DIR = 0x00;                                                    // data port is input
  229.        
  230.         if(ks0108Coord.x < 64) {
  231.                 LCD_CS_PORT &= ~(0x01 << CSEL2);                        // deselect chip 2
  232.                 LCD_CS_PORT |= 0x01 << CSEL1;                           // select chip 1
  233.         } else if(ks0108Coord.x >= 64) {
  234.                 LCD_CS_PORT &= ~(0x01 << CSEL1);                        // deselect chip 1
  235.                 LCD_CS_PORT |= 0x01 << CSEL2;                           // select chip 2
  236.         }
  237.         if(ks0108Coord.x == 64 && first) {                              // chip2 X-address = 0
  238.                 ks0108WriteCommand(LCD_SET_ADD, CHIP2);         // wuff wuff
  239.         }
  240.        
  241.         LCD_CMD_PORT |= 0x01 << D_I;                                    // D/I = 1
  242.         LCD_CMD_PORT |= 0x01 << R_W;                                    // R/W = 1
  243.        
  244.         LCD_CMD_PORT |= 0x01 << EN;                                             // EN high level width: min. 450ns
  245.         asm volatile("nop\n\t"
  246.                                  "nop\n\t"
  247.                                  "nop\n\t"
  248.                                  ::);
  249.        
  250.         data = Reverse(LCD_DATA_IN);                                                            // read Data                     
  251.        
  252.         LCD_CMD_PORT &= ~(0x01 << EN);
  253.         for(i=0; i<8; i++);                                                             // a little delay loop (faster than reading the busy flag)
  254.        
  255.         LCD_DATA_DIR = 0xFF;
  256.        
  257.         ks0108GotoXY(ks0108Coord.x, ks0108Coord.y);
  258.        
  259.         if(ks0108Inverted)
  260.                 data = ~data;
  261.         return data;
  262. }
  263.  
  264. inline uint8_t ks0108ReadData(void) {
  265.         ks0108DoReadData(1);                                                    // dummy read
  266.         return ks0108DoReadData(0);                                             // "real" read
  267. }
  268.  
  269. void ks0108WriteCommand(uint8_t cmd, uint8_t chip) {
  270.         if(chip == CHIP1) {
  271.                 LCD_CS_PORT &= ~(0x01 << CSEL2);                        // deselect chip 2
  272.                 LCD_CS_PORT |= 0x01 << CSEL1;                           // select chip 1
  273.         } else if(chip == CHIP2) {
  274.                 LCD_CS_PORT &= ~(0x01 << CSEL1);                        // deselect chip 1
  275.                 LCD_CS_PORT |= 0x01 << CSEL2;                           // select chip 2
  276.         }
  277.        
  278.         LCD_CMD_PORT &= ~(0x01 << D_I);                                 // D/I = 0
  279.         LCD_CMD_PORT &= ~(0x01 << R_W);                                 // R/W = 0
  280.         LCD_DATA_DIR = 0xFF;                                                    // data port is output
  281.         LCD_DATA_OUT = Reverse(cmd);                                                            // write command
  282.         ks0108Enable();                                                                 // enable
  283.         LCD_DATA_OUT = 0x00;
  284. }
  285.  
  286. void ks0108WriteData(uint8_t data) {
  287.         uint8_t displayData, yOffset, cmdPort;
  288.  
  289.         if(ks0108Coord.x >= 128)
  290.                 return;
  291.  
  292.         if(ks0108Coord.x < 64) {
  293.                 LCD_CS_PORT &= ~(0x01 << CSEL2);                        // deselect chip 2
  294.                 LCD_CS_PORT |= 0x01 << CSEL1;                           // select chip 1
  295.         } else if(ks0108Coord.x >= 64) {
  296.                 LCD_CS_PORT &= ~(0x01 << CSEL1);                        // deselect chip 1
  297.                 LCD_CS_PORT |= 0x01 << CSEL2;                           // select chip 2
  298.         }
  299.         if(ks0108Coord.x == 64)                                                 // chip2 X-address = 0
  300.                 ks0108WriteCommand(LCD_SET_ADD, CHIP2);
  301.        
  302.         LCD_CMD_PORT |= 0x01 << D_I;                                    // D/I = 1
  303.         LCD_CMD_PORT &= ~(0x01 << R_W);                                 // R/W = 0
  304.         LCD_DATA_DIR = 0xFF;                                                    // data port is output
  305.        
  306.        
  307.         yOffset = ks0108Coord.y%8;
  308.         if(yOffset != 0) {
  309.                 // first page
  310.                 cmdPort = LCD_CMD_PORT;                                         // save command port
  311.                 displayData = ks0108ReadData();
  312.                
  313.                 LCD_CMD_PORT = cmdPort;                                         // restore command port
  314.                 LCD_DATA_DIR = 0xFF;                                            // data port is output
  315.                
  316.                 displayData |= data << yOffset;
  317.                 if(ks0108Inverted)
  318.                         displayData = ~displayData;
  319.                 LCD_DATA_OUT = Reverse(displayData);                                    // write data
  320.                 ks0108Enable();                                                         // enable
  321.                
  322.                 // second page
  323.                 ks0108GotoXY(ks0108Coord.x, ks0108Coord.y+8);
  324.                
  325.                 displayData = ks0108ReadData();
  326.                
  327.                 LCD_CMD_PORT = cmdPort;                                         // restore command port
  328.                 LCD_DATA_DIR = 0xFF;                                            // data port is output
  329.                
  330.                 displayData |= data >> (8-yOffset);
  331.                 if(ks0108Inverted)
  332.                         displayData = ~displayData;
  333.                 LCD_DATA_OUT = Reverse(displayData);                                    // write data
  334.                 ks0108Enable();                                                         // enable
  335.                
  336.                 ks0108GotoXY(ks0108Coord.x+1, ks0108Coord.y-8);
  337.         } else {
  338.                 if(ks0108Inverted)
  339.                         data = ~data;
  340.                 LCD_DATA_OUT = data;                                            // write data
  341.                 ks0108Enable();                                                         // enable
  342.                 ks0108Coord.x++;
  343.         }
  344.         LCD_DATA_OUT = 0x00;
  345. }

A bekötés annyiban különbözik hogy az adat lábak fordítva vannak:
AVR LCD
PA0 D7
PA1 D6
.
.
.
PA6 D1
PA7 D0

A Reverse függvény megváltoztatja a bitek sorrendjét. Valamiért krikszkrakszok jelennek meg a kijelzőn.

Mi lehet a gond?
A hozzászólás módosítva: Nov 2, 2014
(#) Sick-Bastard hozzászólása Nov 2, 2014 /
 
Üdv!

Egy AVR és ENC28J60-assal bíbelődöm. Jelenleg két komoly gondom van, de most csak az egyiket írom le.

Az IP és a TCP-hez írtam checksum for() ciklust, ami eddig jól ment.
  1. i = 34;                                         //      TCP starts at array[i]
  2. y = i+TCP_Total_Length;         //      array[IP_Total_Length]-20;
  3. for(i=i;i<y;i+=2)                       //      sum all data in selected array
  4. {checksum += ((unsigned int)(array[i]<<8) + (unsigned int)array[i+1]);}
  5. checksum = ((checksum & 0x0000FFFF) + ((checksum>>16) & 0x0000FFFF));
  6. checksum = ~checksum;


A problémám, hogy ha páratlan számú byte-okkal kell számolni, akkor az utolsót megduplázza, így rossz eredményt kapok.

Javaslata valakinek, hogyan lehet?
(Próbáltam ilyen-olyan megoldást a netről, de akkor mindegyik csomagot elrontja. Lehet már túl fáradt vagyok, vagy a fától nem látom az erdőt...)
(#) Sick-Bastard válasza Sick-Bastard hozzászólására (») Nov 3, 2014 /
 
Egy picit más lesz itt a probléma...

Az oldal nagyon egyszerű, csak egy gomb(ON/OFF) van rajta egy formban:

  1. package_length = String_To_Array(array,package_length,"HTTP/1.0 200 OK\r\nContent-Type: text/html\r\nPragma: no-cache");
  2. package_length = String_To_Array(array,package_length,"<html><body><form action=\"avr.php\" method=\"POST\">");
  3. if(relay[0] == 1)
  4. {package_length = String_To_Array(array,package_length,"<button type='Submit' name='r0' value=0>ON</button><br>");}
  5. else if(relay[0] == 0)
  6. {package_length = String_To_Array(array,package_length,"<button type='Submit' name='r0' value=1>OFF</button><br>");}
  7. package_length = String_To_Array(array,package_length,"</form></body></html>");


Röviden, ha relay[0] == 1 akkor ON gombot küld,
ha relay[0] == 0 akkor OFF gombot.

Amikor először betöltöm az oldalt, akkor alap állapotában páratlan a TCP byteok száma(241byte)(gomb ON állapotban).
Amikor megnyomom a gombot(ON), a TCP byte-ok száma páros lesz. Itt sincs gond. Szépen betölti az új oldalt az OFF gombbal(242byte).

Viszont, amikor megnyomom az OFF gombot, és be kéne töltenie az ON gombos oldalt, ott vérzik el.

A WireShark szerint elküldi az ON oldal csomagját,(241byte),az OFF gomb megnyomása után, de checksum error-t ír ki.

Hogy lehet, az hogy az első oldalnál jól számol, másodszor viszont nem?
(#) kapu48 válasza Sick-Bastard hozzászólására (») Nov 3, 2014 /
 
Hogy egyáltalán értelmezni tudjuk a problémádat, ismerni kellene a részleteket!

Például ennek a függvénynek a kidolgozását?:
package_length = String_To_Array(array,package_length,”…”)
???
(#) Sick-Bastard válasza kapu48 hozzászólására (») Nov 3, 2014 /
 
  1. unsigned int String_To_Array(unsigned char array[],unsigned int startat, char *string)
  2. {
  3.         unsigned int i = startat;
  4.         while(*string>0)
  5.         {
  6.                 array[i] = *string++;
  7.                 i++;
  8.         }
  9.         return(i);
  10. }


Közben megtaláltam a lehetséges hibát.
Mivel sok a RAM az AVRben (16KB), így lefoglaltam az elején 2x 1538byte helyet, mint RX ill TX Buffer.

  1. unsigned char RX_BUF[1538]={},TX_BUF[1538]={};


Nem biztos, hogy a legjobb megoldás, de nekem így volt átláthatóbb.

Szóval, az történik, hogy:
Amikor meghívom az első oldalt, azt szépen betölti a TX_BUF helyre, majd elküldi az ENC28J60-nak.
Amikor megnyomom a gombot, akkor ismét beleír a TX_BUF helyre, így felülírja az előző adatokat.
A gond ott keletkezik, amikor másodszor nyomom meg a gombot, ekkor ugyan beleír a TX_BUF-erbe, de ekkor az byte-ok száma 1-el kisebb lesz(mivel az ON gombos oldal csak 241byte, az OFF meg 242), mint előtte. Így a 242.-dik byte már nem íródik felül és megmarad az előző értéke, ami valószínűleg nem 0 volt.

  1. for(i=i;i<y;i+=2)                       //      sum all data in selected array
  2. {checksum +=((unsigned int)(array[i]<<8) + (unsigned int)array[i+1]);}


A checksum() for() ciklusa 2 byteból csinál egy integert amit hozzáad a checksum nevű temp változóhoz. Ha az integert alkotó alsó byte nem kell (páratlan számú TCP csomag esetében), akkor annak 0nak kell lennie.

Mivel a TX_BUF 242-byteja nem íródott felül, így az nem 0 volt, hanem 0x3e és így már borult is a checksum eredménye.

Miért fut le első indításra?
Mert a TX_BUF először üres, minden byte benne 0.

Szóval az átmeneti megoldásom az lett, hogy minden befejezett küldés után resetelem a TX_BUF-ert.

Így már működik is!
(#) sucuka válasza tkovacs hozzászólására (») Nov 3, 2014 /
 
Köszönöm a segítséget! Akkor eszerint a csatolt állomány csak az EEPROM-ba kerülő tartalom, és kéne mellé még a programkód HEX-állománya is. A címeknek majd utánajárok, remélem sikerül. És a feltöltendő programkódot is el kell kérnem a megrendelőmtől.
(#) Droot válasza Droot hozzászólására (») Nov 3, 2014 /
 
Valaki rápillantana erre?
(#) kapu48 válasza Droot hozzászólására (») Nov 3, 2014 /
 
Nem néztem végig az egészet, de biztos valahol nem hívod meg Reverse függvényt.
A végén Pl.:
} else {
if(ks0108Inverted)
data = ~data;
LCD_DATA_OUT = data; ??? // write data
ks0108Enable(); // enable
(#) Droot válasza kapu48 hozzászólására (») Nov 3, 2014 /
 
Ez a legutolsó sorban volt és valóban nem. Viszont így sem jó. Beraktam oda is, azelőtt krikszkrakszok jelentek meg, most pedig egy pixel sincs bekapcsolva.
(#) killbill válasza Droot hozzászólására (») Nov 3, 2014 /
 
A kijelzonek szolo parancsoknal is meg vannak forgatva a bitek?
(#) kapu48 válasza Droot hozzászólására (») Nov 4, 2014 /
 
Idézet:
„A bekötés annyiban különbözik, hogy az adat lábak fordítva vannak:
AVR LCD
PA0 D7
PA1 D6
.
.
.
PA6 D1
PA7 D0

A Reverse függvény megváltoztatja a bitek sorrendjét. Valamiért krikszkrakszok jelennek meg a kijelzőn.

Mi lehet a gond?

1. uint8_t Reverse( uint8_t x )
2. {
3. x = ((x >> 1) & 0x55) | ((x << 1) & 0xaa);
4. x = ((x >> 2) & 0x33) | ((x << 2) & 0xcc);
5. x = ((x >> 4) & 0x0f) | ((x << 4) & 0xf0);
6. return x;
7. }


Szerintem ez a függvény a gond!
(#) killbill válasza kapu48 hozzászólására (») Nov 4, 2014 /
 
Ezzel a fuggvennyel semmi gond nincs. Teljesen jol mukodik.
Következő: »»   625 / 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