Fórum témák
» Több friss téma |
Sziasztok.
Az éjjel "véletlenül" sikerült csinálnom egy egyszerű voltmérőt. Bár nem ennyire pontosat szerettem volna csinálni, de így sikerült. A pontosságot, tovább lehet növelni, az ellenállás osztóba épített ellenállások pontosságával, és vagy a fesz osztás hardveres javításával. (pl. műv. erősítő) A szoftverben is lehet javítani a pontosságon, de szerintem indulásnak jó, és nekem nem kell ennyire pontos. Szerettem volna ezeket
a sorokat, egy sorba tömöríteni,
Remélem e kis progival segítek elindulni a cikked írásához vezető úton. Ha valamit rosszúl írtam volna, javítsatok ki.
Én is elkészültem a tanulmány ként írt ajtó, nyitó vezérlő egységével. Minden úgy működik ahogyan szerettem volna. Még ha ezeket a fránya goto utasításokat el tudtam volna hagyni.... Na majd idővel...
[ #include "io430.h" #include "intrinsics.h" void delay_ms(unsigned int delay) { int i; for(i=0; i } } void main( void ) { WDTCTL = WDTPW + WDTHOLD; //WDT ki P1DIR &= ~BIT4; //nyomógomb zárás P1DIR &= ~BIT2; //nyomógonb nyitás P1DIR |= BIT6; //világítás P1DIR |= BIT7; //működtető trafó P1DIR |= BIT1; //nyitás relé P1DIR |= BIT0; //zárás relé while(1) { P1OUT = 0X00; oda: //zárásból visszanyitáskor ugrás while(~P1IN & BIT2) { //nyitási feltétel P1OUT = 0XC2; //P1.1 P1.6 P1.7 portok be int a; for(a=0; a<100; a++) { delay_ms(120); //nyitási idő, amíg a motor megy (12s) if(~P1IN & BIT4) { //kiurgási feltétel vissza záráshoz goto ide; } } P1OUT = 0X40; //P1.6 port be int b; for(b=0; b<1000; b++) { delay_ms(120); //világítás késleltetési ideje(2perc) if(~P1IN & BIT4) { //kiugrási feltétel vissza záráshoz goto ide; } } } ide: while(~P1IN & BIT4) { //zárási feltétel P1OUT = 0XC1; //P1.0 P1.6 P1.7 portok be int c; for(c=0; c<100; c++) { delay_ms(120); //zárási idő ,amíg a motor megy (12s) if(~P1IN & BIT2) { //kiugrási feltétel vissza nyitáshoz goto oda; } } P1OUT = 0X40; //P1.6 port be int d; for(d=0; d<1000; d++) { delay_ms(120); //világítás késleltetési ideje (2perc) if(~P1IN & BIT2) { //kiugrási feltétel vissza nyitáshoz goto oda; } } } } }]>>>>>
Gratula. Ha megnézed az lcd_menu progimat, és végigköveted, akkor rájössz, hogy lehet "goto" nélkül élni. Amúgy nekem is nehéz a goto nélkül. Működik már az "stdint.h"?
Nem működik sajna. Pedig lecseréltem azzal amit küldtél (az IAR könyvtárában) Majd az új telepítés után próbálkozom. Köszi! Gratulálok a munkáidhoz!! Már volt szerencsém látni régebben, csak nem tudtam, hogy te vagy az alkotó.
Szeretnék írni egy programot távirányításra. Infra vagy rádiós, és csak néhány csatornás lenne. Egy adót, és egy vevőt, ami egy saját egyszerű protokol alapján kódolná az adatokat.Ennek nincsen jelentősége.Majd ahogyan sikerül. Nagy előny ezeknél a chippeknél a 3 voltos tápfeszültség.Arra gondoltam, hogy egy bináris adatsort küldenék ki , amelyben egy két bit megváltoztatásával tudnám a csatornákat aktivizálni.A vevő pedig ezeket összehasonlítva tudná aktivizálni a portokat.Programilag úgy látom, hogy a switsh, case utasításokban kellene gondolkoznom.Mivel kezdő vagyok ,az infra led helyett egy sima Led-et használnék, és látható sebességű órajelet alkalmaznék.Ha valaki tud segíteni azt előre is nagyon köszönöm.
ref/1023 eredménye kb. 0,32 lenne. De mivel az egészt osztasz egésszel a / eredménye 0 lesz, így aztán az egész szorzaté.
Megoldás lehetne pl. a ref/1023.0, de az előző kódból nem tudom honnan következik ez az osztás, lehet nincs is szükséged rá? Hint: int a=9; float e; e = (float) a/2; //4.5 e = (float) (a/2.0); //4.5 e = a / (float) 2; //4.5 DE e = (float) (a/2); //4
Nincs mert megy így is, csak először az egész eredeti műveletet egy sorban szerettem volna megoldani. (A progi elején van a számítás.)
Tehát: ref = VCC, (ami a lentebb csatolt progiban már el van osztva a 10bites felbontással), oszto = feszosztó, akkor az egyenlet = (ADérték*(ref=3,3V/1023=ADC10bit-es felbontás))*feszültségosztás, ami leegyszerűsítve =(AD*(3,3/1023)*4,13 jelen ell.osztónál. De mivel icserny írta még régebben, hogy jelen procik nem támogatják a "float" változókat, úgy gondoltam megoldom "long"-al mert csak abban fér el az eredmény. Ezért kell a végén osztani 100000-el. Azt még hozzáteszem, hogy Én 3,3V-al számolok, és nem 3,5V-al ami az LP-n van. Remélem érthető vagyok.
Sziasztok.
Elakadtam a belső hőmérő olvasásánál.
A lényeg, hogy a "hoertek" mindíg 737, és ez az érték nem változik, hiába melegítem vagy hűtöm a procit. Olyan mintha nem menne az AD konverzió, vagy valamit nem jól adtam meg? Az adatlap, és a FUG. szerint így kell. A proci g2352-es.
Szerintem lemaradt az ADC megszakítás
__enable_interrupt(); ..... // ADC10 interrupt service routine #pragma vector=ADC10_VECTOR __interrupt void ADC10_ISR (void) { __bic_SR_register_on_exit(CPUOFF); // Clear CPUOFF bit from 0(SR) }
Benne van, csak nem csatoltam. Sőt már raktam bele várakozást is hátha..,de úgy sem megy. Már azt is kipróbáltam, hogy csak ezt a programot raktam bele a prociba, és semmi mást. Az eredmény így is 737.
A procinak az órajelét mire állítottad?.
Kalibrált 1MHz.
Nagyvonalakban gyorsan összevágva. Úgynéztem, hogy mindent az adatla szerint csináltam. Már azt is megnéztem, hogy egyáltalán van-e benne hőszenzor, de ebben van.
IAR -ban még nem csináltam semmit de szerintem az SR regiszternél van a kutya elásva.
__bic_SR_register( __SR_GIE); _BIS_SR(LPM4_bits); _BIS_SR(LPM0_bits + GIE); nem tudom, hogy IAR -ban hogy kell írni a fentiek közül valamelyik.
Erre már Én is gondoltam, de megbízom icserny cikkében.
Idézet: „__low_power_mode_0() nevű beépített függvénnyel állíthatjuk be, amely a Status regiszter GIE és CPUOFF bitjeit '1'-be állítja” tehát ugyan az mint: Idézet: ez.„__bis_SR_register(CPUOFF + GIE);” A többi AD konverziót is így csináltam és azok mennek. Szerintem inkább alszom rá egyet.
Nekem nincs itthon 2352 -m, de egy 2452 -be betöltöttem a progit és SR nélkül nálam sem mintavételezett igaz nekem nincs feltelepítve a IAR. Az alábbi sor beírása után azonnal ment a konverzió.
__bis_SR_register(CPUOFF + GIE); CCS -el próbáltam, long hoertek -el
Holnap kipróbálom, meg megnézem CCS-ben is, abban még nem próbáltam.
Valahonnan vesz egy mintát, vagy mindig ugyanazt az értéket veszi, mert az a 737, valahonnan jön. Próbáltam úgy is, hogy a változónak értéket adtam, hátha valami zavar van (int hoertek=0. A "long hoertek" szerintem fölösleges, mert úgyis csak 1023 lehet, de lehet, hogy tévedek. Idézet: Ez rendes dolog tőled, de azért biztosabb, ha megnézed az intinsics.h fejléc állományban. Minden low_power mód bekapcsolásban benne van a GIE bit beállítása. Például:„Erre már Én is gondoltam, de megbízom icserny cikkében.”
Ez tehát nem lehet oka a problémának (egyébként is "visszajött" a program, s kaptál értéket...).
A programod nálam működik MSP430G2231 és MSP430G2452 CPU-val is (enyhe melegítésre bekapcsolástól kezdve 729-737, illetve 747-755 közötti értékeket kaptam).
Megjegyzés: az IAR újabb verzióinál az #include "intrinsics.h" már fölösleges. Régebben kellett csak (kb. tavaly nyár elején). Mostmár az io430.h is becsatolja automatikusan.
Örülök neki, hogy működik. Megint ott tartok, hogy mindenhol jó a program, csak nálam nem. Már csak arra tudok gondolni, hogy összekeveredik a programban, a másik AD konverzióval. Bővebben: A programban több AD-t használok, és ha az adott analóg értékre van szükségem, újrainicializálom az egész AD-t. Pl. csatolva. Pedig úgy is kipróbáltam, hogy csak a hőmérő prog. volt benne. Marad a két állandó lehetőség: Vagy a prog.íróban van a hiba, vagy ezt a CPU-t is kinyírtam.
U.I: Remélem nem haragszol meg ha, kijavítalak, de nem tudom mit jelent "az IAR újabb verzióinál", Én az 5.40-est használom, és nem az "io430.h" csatolja be a "intrinsics.h" állományt, hanem az adott CPU header fájla, jelen esetemben a "io430g2352.h".
Próbáltad már erőteljesebben melegíteni a mikrovezérlőt (pl. 50 fokra)? Mert az általad kapott érték szobahőmérséklet környékén hihetőnek tűnik, csak az gyanús, hogy nem változik.
Idézet: Ebben igazad van, és elnézést, hogy pongyola voltam. Én csak azt akartam jelezni, hogy az #include "io430.h" után már fölösleges az intrinsics.h becsatolása. „Én az 5.40-est használom, és nem az "io430.h" csatolja be a "intrinsics.h" állományt, hanem az adott CPU header fájla”
Úgy néz ki, hogy elindult. De, ha elíndítom a másik AD-t akkor visszatérek a kezdetekhez. "Szenvedtem" vele, hogy az adatlap/FUG-ből jól írjam meg, mármint a belső hőmérő vezérlést, és a mintaprogramok között ott van. Namost onnan kimásolva a számítást, az Lcd-n 32 fok jelenik meg, ami a számításaim és mért adataim szerint 3 fokkal több a szobahőmérsékletnél. Tehát kalibrálni kellene valahogy, és megoldani, hogy menjen a két AD egyszerre. Most úgy működik, ahogy a csatolt fájlban van. Egyébként levegős pákával melegítettem 68 fokig. (tovább nem mertem.)
Idézet: „Én csak azt akartam jelezni...” U.i: Én meg elfelejtettem megköszönni, hogy szóltál ez miatt. Köszönöm/jük az IAR haszálók nevében.
Örömmel jelentem, a hibát megtaláltam.(hála, a minimális ASM tudásomnak, és a "Watch" ablaknak.)
Az első AD konverzió után, a második AD konverzió inicializálásakor, nem írja felül az ADC10CTL0, ADC10CTL1 regiszereket. Legalábbis ezt mutatja az IAR.
Sziasztok.
Most kaptam meg a programozót. Szeretnék vele meghajtani egy Nokia 3410-es kijelzőt. A topikban a 9. oldalon lévő drivert hogyan kell használni? A "C" programozást most kezdtem tanulni. Idáig bascomban programoztam avr-t. Ha tudnál küdeni valami konkrét mintát, hogyan irsz valami pár sor szöveget, azt nagyon megköszönöm. Esetleg komplett project mappát. A procim Msp430G2553 és a IAR kickstart progit használom.
Hát nem akar összejönni a két AD konverzió, ill. a belső hőmérő, és egy portról olvasott. Menet közben az is világos lett, hogy a 737 nem a hőmérő értéke, hanem a portról beolvasott érték volt.
Tehát a lényeg: A lentebb csatolt "main.c" alapján, beolvasom a portról az analóg jelet, feldolgozom, stb.. utána be szeretném olvasni a hőmérő AD értékét, de ahogy írtam már, nem írja felül az ADC10CTLx regisztereket. Ha viszont nem a belső hőmérőt inicializálom, hanem egy másik AD portot, akkor simán felülírja. Ha megcserélem a sorrendet, (először a hőmérőt inicializálom, utána a portot) akkor a hőmérő adatai maradnak. Próbáltam, hogy a két AD olvasás között kikapcsolom az ADC-t, (ADC10CTL0 &= ~ENC), de így minden olvastott érték 1023. Úgyhogy mostmár teljesen elvesztettem a fonalat. Nem értem, hogy miért nem megy ez a hőmérős dolog, és miért megy a két-három portról olvasás. Idézet: A FUG azt írja, hogy néhány kivételtől eltekintve a vezérlő biteket (értsd regisztereket) csak az ADC kikapcsolt állapotában (ENC=0) lehet módosítani. /SLAU144H 22.2.1 bekezdés vége/ „beolvasom a portról az analóg jelet, feldolgozom, stb.. utána be szeretném olvasni a hőmérő AD értékét, de ahogy írtam már, nem írja felül az ADC10CTLx regisztereket.” Idézet: Pedig a fentiek alapján ezt a technikát kellene csiszolni. „Próbáltam, hogy a két AD olvasás között kikapcsolom az ADC-t, (ADC10CTL0 &= ~ENC), de így minden olvastott érték 1023.”
Igen ezt már "olvastam", és ezért nem értem, hogy mit rontok el, és hol. Vagy miért csinálja azt, hogyha a két konverzió között kikapcsolom akkor az ADC10MEM értéke 1023, és nem változik? Továbbá az nem fér a kis agyamba, hogyha két portról olvasom be az AD értéket, ugyanezzel a technikával, (AD kikapcsolás nélkül) akkor miért jó? Már úgy vagyok vele, hogy feladom, és rakok rá egy külső hőmérőt, de csak nem hagy nyugodni a dolog.
Itt Bővebben: Link használja a program a belső hőmérőt és az adc-t egyszerre.
Köszi. Idáig már eljutottam a FUG segítségével. Sőt mostmár működik is, de....
A lényeg, és ahogy nálam működik: Első AD inicializálás, konverzió, érték kiolvasás, AD kikapcsolás, és a lényeg ADC10CTL1 = INCH_0;. Ha nem rakom be az utolsó műveletet, akkor a következő AD inicializáláskor az INCH bitek így néznek ki: 1110 , hogy miért? Az első AD-nál a BIT6 lett beírva ami INCH = 0110, és a második AD-nál az INCH =1010 kellene legyen. Beírta az INCH_10-et, csak elfelejti kivenni a INCH_6-ot. Ha pl másik portot rakok az első AD-hoz, mondjuk A7-et (0111), akkor ez az eredmény: 1111. Tehát hiába kapcsolom ki az AD-t, az INCH-t nem írja felül, de ha berakom a ADC10CTL1 = INCH_0 parancsot, nullázza az egész ADC10CTL1 regisztert. Számomra ez már túl rejtélyes dolog, úgyhogy így hagyom.
Szerintem az a baj, hogy túlbonyolítottad az értékadásokat! Ha az egész regisztertartalmat összeállítod, akkor az alábbi sorban a |= helyett használj egyenlőségjelet!!!
Idézet: „ADC10CTL0 |= SREF_1 + ADC10SHT_3 + REFON + ADC10ON + ADC10IE;” Ugyanígy a többi helyen is... A bitenkénti VAGY operátor csak akkor kell, ha '1'-be akarsz állítani bizonyos biteket.
Mégiscsak a profi mesterek közé tartozol. "|" Ez volt a hiba, de az ADC10CTL0 &= ~ENC; kell! Azt, hogy hogyan kelrült a VAGY bele, azt nem tudom, pedig biztos Én írtam oda. Megnézve a másik programom, (ahol 3 AD-t használok) oda is csak = jelet raktam.
Köszönöm, köszönöm mester ! |
Bejelentkezés
Hirdetés |