Fórum témák

» Több friss téma
Fórum » PIC programozása C nyelven, C-Compiler
Lapozás: OK   118 / 153
(#) dzsonszpartan válasza killbill hozzászólására (») Nov 12, 2015 /
 
A lentebb ajánlott link szerint pontosan így csináltam, ahogy Te is írtad és érthetően működik is!

Köszönöm mindenkinek a gyors segítséget!
(#) cassis hozzászólása Nov 28, 2015 /
 
Ismerkednék a DMA modullal C30 ban és persze a C vel is... .
Az alábbi kód második sora hibával fordul.

  1. unsigned int BufferA[8] __attribute__(space(dma));
  2. DMA1STA = __builtin_dmaoffset(BufferA);


error: argument to _builtin_dmaoffset() is not the address of an object in a dma section
the object must not be qualified with any form of index

Mi lehet a hiba oka?
A hozzászólás módosítva: Nov 28, 2015
(#) icserny válasza cassis hozzászólására (») Nov 29, 2015 /
 
Én még csak az ADC-hez használtam DMA-t. Az egyik példaprogramot átnézve, úgy látom, hogy az __attribute__(space(dma)) mellett az igazítás is számíthat, s még egy aligned(8) attribútum is kellhet.

  1. //A CONVERSIONS_PER_INPUT makró a csatornánkénti mérések számát írja elő,
  2. //csak az alábbi értékek közül választhatunk: 1, 2, 4, 8, 16, 32, 64, 128
  3. #define CONVERSIONS_PER_INPUT  1
  4. #define MAX_CHANNELS   16
  5. //A DMA átvitel mérete szavakban.
  6. #define MAX_TRANSFER (CONVERSIONS_PER_INPUT*MAX_CHANNELS)  //kettő hatványa legyen!
  7.  
  8. //DMA bufferek, az igazítás az átvitt bájok száma szerint
  9. uint16_t au16_bufferA[MAX_TRANSFER] __attribute__((space(dma),aligned(MAX_TRANSFER*2)));
  10. uint8_t u8_NumChannelsScanned;
A hozzászólás módosítva: Nov 29, 2015
(#) zenetom hozzászólása Nov 29, 2015 /
 
Sziasztok!
Meg van valakinek a C18 v3.39-es fordító?
(#) icserny válasza zenetom hozzászólására (») Nov 29, 2015 /
 
Gyanús, hogy a Microchip-nek sem tetszett az a verzió, mert az archívumban v3.38 után v3.40 következik.
(#) zenetom válasza icserny hozzászólására (») Nov 29, 2015 /
 
Az a "vicc" hogy nekem pedig pont azért kéne ez a verzió, mert ebben még nincs benne ez a hiba:
Idézet:
„E:\3.46\pic18-lt\cxx-framework\src\traditional\proc\p18f46k22.asm”

Ez konkrétan a p18f46k22.lib fájlban van, annak ellenére, hogy nincs is "E:" meghajtóm, és teljesen máshova telepítettem a fordítót. Egyébként ilyen bejegyzés még 2635x szerepel ebben a LIB fájlban.
A programok hiba nélkül lefordulnak, azonban a COF fájlt nem lehet használni (pl. Proteus szimuláció), mert a forrásfájlokat az "E:" meghajtón keresné a LIB miatt...
És úgy néz ki, hogy a 3.40 körüli, és azutáni LIB-eknél létezik ez a probléma, azt nem tudom hogy az összes LIB-nél, vagy csak ennél, mert már így is megkukultam, mire rájöttem hogy hol van a kutya elásva.
Most ezt a bugot úgy "patkoltam meg", hogy sikerült leszedni egy 3.36-os LIB-et, amivel felülírtam a mostanit (most 3.35-ös compiler van fent), azonban ott is más útvonalak vannak a LIB-ben, de azt legalább létre tudtam hozni.
Na ez így most lehet kicsit zagyva, de ráment egy napom arra, hogy elkezdhessem írni a progit...
Ha ez nem lett volna, akkor lehet átpártolok C-re, de így tuti csak akkor írok C-re, ha nagyon muszáj. Ez a bajom igazából szinte az összes magasabb szintű fejlesztőkörnyezettel: mindig kalapálni kell valamit, mert magától semmi sem működik (persze vannak kivételek).
(#) AZoli hozzászólása Nov 29, 2015 /
 
Sziasztok!

Mi a probléma ezzel a paraméter átadással:
  1. typedef unsigned int uInt;
  2. uInt CAN_TB[7] = {0,0,0,0,0,0,0};
  3. //***
  4.     CAN_TB[6] = 0b10001010;
  5.     CAN_Transmit (CAN_TB);
  6.  
  7. //...
  8. uInt CAN_Transmit (uInt CAN_TB_loc[])
  9. {
  10.     uInt ConMask = CAN_TB_loc[6];
  11.  
  12.     if ((ConMask & 0b10000000) == 0)
  13.     {
  14.         Nop();
  15.         //ConMask = ConMask | 0b10000000;
  16.     }

Hogy lehetséges az, hogy a függvényben a ConMask = 0x0A?
Szerk.: (PIC24EP... + XC16 tehát az uInt 16 bites.)
A hozzászólás módosítva: Nov 29, 2015
(#) icserny válasza zenetom hozzászólására (») Nov 29, 2015 / 1
 
Szerintem egyszerűbb és jobb megoldás, ha újrafordítod a p18f46k22.lib fájlt.
  1. make_one_device_t.bat 18F46K22

Ha a C:\MCC18-ba telepítetted/másoltad/linkelted a C18 cuccait, akkor feltehetőleg nem lesz benne az E: meghajtóra történő hivatkozás.
(#) cassis válasza icserny hozzászólására (») Nov 29, 2015 /
 
A PIC-kwik oldalt ismerem, és jó referenciának tartom.
Sajnos nem oldódott meg a probléma, az aligned(8) attribútum sem segített.
Érdekes hogy a Microchip ajánlása sem említi, az alábbiak szerint jár el, persze nem megy.

Idézet:

For example:
int result;
char buffer[256] __attribute__((space(dma)));
result = __builtin_dmaoffset(buffer);

Might generate: mov #dmaoffset(buffer), w0

Prototype: int __builtin_dmaoffset(int buffer);

Argument: buffer DMA address value

Return Value: Returns the offset to an accumulator.

Error Messages An error message will be displayed if the result is not an accumulator
register.


Nem tudom mire gondoltál az igazítást illetően. Ha lenne új ötlet azt is szívesen venném.
(#) icserny válasza cassis hozzászólására (») Nov 29, 2015 /
 
Idézet:
„Sajnos nem oldódott meg a probléma, az aligned(8) attribútum sem segített.”
Bocs, elnéztem a változótípust! Tegyél még egy próbát aligned(16)-tal, az int típusú tömbelemekre való tekintettel...
(#) cassis válasza icserny hozzászólására (») Nov 29, 2015 /
 
az aligned(16)-tal sem megy.
A tömbelemek egyébként unsigned int ek.
(#) icserny válasza cassis hozzászólására (») Nov 29, 2015 /
 
Nálam ez lefordul (PIC24HJ128GP502-t választottam ki). A forráskód természetesen így nem jó semmire, csak fordítási próba!

  1. #include <p24hxxxx.h>
  2. #include <stdint.h>
  3. #ifndef _DMA0IF
  4.         #error "A választott mikrovezérlő nem rendelkezik DMA vezérlővel!"
  5. #endif
  6.  
  7. _FOSCSEL(FNOSC_FRC);       // Belső órajelet használunk
  8. _FOSC(FCKSM_CSECMD & OSCIOFNC_OFF);
  9.  
  10. #define MAX_TRANSFER 8
  11. uint16_t bufferA[MAX_TRANSFER] __attribute__((space(dma),aligned(MAX_TRANSFER*2)));
  12. uint16_t bufferB[MAX_TRANSFER] __attribute__((space(dma),aligned(MAX_TRANSFER*2)));
  13.  
  14. int main() {
  15.   DMA0STA = __builtin_dmaoffset(bufferA);
  16.   DMA0STB = __builtin_dmaoffset(bufferB);
  17. }
(#) cassis válasza icserny hozzászólására (») Nov 29, 2015 /
 
ez viszont lefordult.
Most már csak tudni kell mi az oka.
(#) cassis válasza icserny hozzászólására (») Nov 29, 2015 /
 
  1. #define MAX_TRANSFER 8
  2. uint16_t bufferA[MAX_TRANSFER]__attribute__((space(dma),aligned(MAX_TRANSFER*2)));
  3. uint16_t bufferB[MAX_TRANSFER]__attribute__((space(dma),aligned(MAX_TRANSFER*2)));
  4. // unsigned int BufferA[8] __attribute__((space(dma)));  
  5. // unsigned int BufferB[8] __attribute__((space(dma),aligned(16)));



uint16_t típussal megy, unsigned int el pedig nem. Nem értem miért, miközben mindkettő 16 bit széles típus.
megj: Az aligned jelenléte nélkül is lefordul, ha szükség van is rá nem érteném a funkcióját.
A hozzászólás módosítva: Nov 29, 2015
(#) icserny válasza cassis hozzászólására (») Nov 29, 2015 /
 
Az aligned(16) azt jelenti, hogy a változó helyfoglalása 16-tal osztható címen kezdődjön, s többek között a DMA vagy a DSP címzéseknél lehet rá szükség.

Idézet:
„A közvetlen memóriaelérés (Direct Memory Access, DMA) hatékony mechanizmust nyújt a perifériák speciális funkciójú regiszterei és a RAM adatmemória közötti, minimális CPU beavatkozást igénylő adatátvitelre. A DMA vezérlő komplett adatblokkok mozgatására képes, s mivel saját buszt használ az átvitelhez, cikluslopásra sincs szükség, nem gátolja a CPU programfuttatását. A DMA által mozgatott adatok eléréséhez a program által használt buffereket vagy változókat a DMA vezérlő által is kezelt kettős hozzáférésű RAM területen kell elhelyezni. A PIC24HJ128GP502 mikrovezérlőnél ez a RAM memória 0x2000 - 0x27FF címtartományába esik, lásd a bevezető fejezet "Az_adattároló_memória_szervezése" c. szakaszát!. A DMA RAM területen történő elhelyezéshez a változók deklarálásakor az __attribute__((space(dma), aligned(nnnn)) módosítót kell használni, ahol nnnn a DMA átvitel során mozgatott bájtok száma (kettő hatványa legyen!). A DMA átvitel részleteit a PIC24H Family Reference kézikönyv Direct Memory Access (DMA) című fejezete írja le, s mintapéldákat is találunk benne.
(#) cassis válasza icserny hozzászólására (») Nov 29, 2015 /
 
Akkor valamit keverek, mert én
DMA0CNT = 7;
regiszterben megadott érték alapján gondoltam ezt.
Korábban is olvastam az általad idézett sorokat, kissé akkor is zavaros volt a dolog.

Idézet:

DMAxCNT reg:

This register contains the transfer count. DMAxCNT + 1 represents the number of DMA requests the channel must service before the data block transfer is considered complete.
That is, a DMAxCNT value of ‘0’ will transfer one element. The value of the DMAxCNT register is independent of the transfer data size (SIZE bit in the DMAxCON register). Writes to this register while the orresponding DMA channel is enabled (i.e., active) may result in unpredictable behavior and should be voided


És továbbra sem értem miért lehet az uint16_t és az unsigned int el eltérő működés.
A hozzászólás módosítva: Nov 29, 2015
(#) zenetom válasza icserny hozzászólására (») Dec 22, 2015 /
 
Kissé későn reagálva, de ezt kipróbálva se javult a helyzet, marad a "kalapálás". Ha lenne rá időm, utánajárnék a dolgoknak alaposabban, de "jó ez így is".
(#) nagzso hozzászólása Dec 29, 2015 /
 
Sziasztok!
Miért lehet az, hogy működik a programom normálisan, viszont ha egy függvényen belül a már meglévők mellé új változót deklarálok, akkor pedig hibásan. Értem: van egy alap menüm, ami induláskor megjelenítődik, de ha létrehozom a változót, akkor az egyik almenüpontja jelenítődik meg induláskor. A létrehozott változónak semmi, köze a menükezeléshez. Ha static-ként deklarálom, akkor megint megy helyesen.
PIC16F1716-ot használok, Program space: 52% Data space: 29% (fordításnál ezeket látom), a fordító XC8 v1.35.
(#) potyo válasza nagzso hozzászólására (») Dec 29, 2015 /
 
A kód látása nélkül pl. valamit túlindexelsz vagy hibásan castolsz valamit. De ezek csak tippek, mutass kódrészletet
(#) nagzso válasza potyo hozzászólására (») Dec 29, 2015 /
 
Valóban van egy túl indexelés, viszont kipróbálni majd csak holnap tudom. Köszi szépen.
(#) killbill válasza nagzso hozzászólására (») Dec 29, 2015 /
 
Lokalis valtozok a stack-en allokalodnak. Ha static, akkor nem. Nem lehet, hogy egyszeruen stack tulcsordulasod van?
(#) nagzso válasza killbill hozzászólására (») Dec 29, 2015 /
 
Erre is gondoltam, de engedélyeztem a reset-et, ha stackoverflow van, és induláskor ellenőrzöm is és kiíratom amennyiben előfordult.
(#) ativagyok hozzászólása Jan 11, 2016 /
 
Üdv!

Egy olyan táblázatot szeretnék megvalósítani, ahol a bemenet egy értéktartományához tartozik egy adott kimeneti érték. Konkrétabban, ha az ADC-vel 700mV és 710mV között mérek, a kimenet értéke legyen 50. Lookup table néven kerestem, de nem találtam számomra megfelelő megoldást.
Előre is köszönöm, ha valaki tud segíteni.
(#) kissi válasza ativagyok hozzászólására (») Jan 11, 2016 / 1
 
Szia!
Milyen nyelven akarod elkövetni ?
szerk.: Bocs, most nézem a topic címét !

  1. if (ADC< hatar1 )  ertek=50;
  2. else if ( ADC<hatar2 ) ertek=55;
  3. else if ( ADC<hatar3) ertek =60;
  4. else ertek=default;


A hatar1, stb-t a megfelelő kóddal helyettesíted, amit adott értéknél kapsz !
A hozzászólás módosítva: Jan 11, 2016
(#) ativagyok válasza kissi hozzászólására (») Jan 11, 2016 /
 
Köszönöm.
50db ertek-em lenne, nem jelent problémát, vagy nem csúnya megoldás ennyi elágazás?
(#) kissi válasza ativagyok hozzászólására (») Jan 11, 2016 / 1
 
Valahogy szelektálnod kell... vagy egy függvény segítségével kapod meg a kívánt értéket, vagy egy táblázatból olvasod ki 8 de akkor tudnod kell a sorszámot !) vagy így megnézed, hogy melyik sorra igaz... !
Nem tudok jobbat, ha tartományokról van szó, ill. ha pl. 10 bites AD-t használsz, akkor az AD értékét használod egy tömbben a címzéshez, az értékek pedig a tömbben vannak, akkor nem kell szelektálni, csak egy nagy tömb kell ( akár a ROM-ban is lehet!) !
Így érthető vagy részletezzem még ?!
A hozzászólás módosítva: Jan 11, 2016
(#) ativagyok válasza kissi hozzászólására (») Jan 11, 2016 /
 
Nagyjából érthető
Egyelőre nekifutok az általad ajánlott if-es megoldással.
Köszönöm még egyszer.
(#) kissi válasza ativagyok hozzászólására (») Jan 11, 2016 / 1
 
A tömbös se rossz: 10 bitnél
  1. tomb[1024]= { ertek0,ertek1, ertek2,... ,ertek1023};
  2.  
  3.  
  4. ertek=tomb[ADC]


Így viszont meg kell adnod az összes bemeneti értékhez (ADC) tartozó kimeneti értékeket, ami a tartományok miatt többször is ugyanaz lesz !
A hozzászólás módosítva: Jan 11, 2016
(#) potyo válasza ativagyok hozzászólására (») Jan 11, 2016 / 1
 
Ha lineáris az eloszlás, akkor eloszthatod az ADC értékét egy konstanssal, és akkor arányosan kisebb táblázat is elég lesz. Esetleg mivel az osztás sok erőforrást emészt, ezért szorzásra és jobbra shiftelésre cserélhető.

Pl.:

  1. tomb[50] = { ... };
  2.  
  3. ertek = tomb[(ADC * 50) / 1024]; // optimalizálva: ertek = tomb[(ADC * 25) >> 9];
(#) ativagyok válasza kissi hozzászólására (») Jan 12, 2016 /
 
Ez a megoldás is tetszik, viszont 12bites ADC-t használok.
Az már egy kicsit nagy tömb lenne.
Az If-es megoldással szépen működik, egyelőre marad az, aztán ha később kedvet kapok, majd kísérletezek.

potyo:Köszönöm, sajnos egyáltalán nem lineáris az eloszlás, így maradtam a fent említett megoldásnál.
Viszont tanulságos, később jól jöhet ez a megoldás.

Üdv,
Ati
Következő: »»   118 / 153
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