Fórum témák

» Több friss téma
Fórum » MSP430 mikrovezérlők
 
Témaindító: gomzito, idő: Ápr 21, 2006
Témakörök:
Lapozás: OK   28 / 139
(#) szitko válasza David.zsombor hozzászólására (») Jan 10, 2012 /
 
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
  1. fesz_sz = (long)akku * ref;    // A fenti számítások
  2.       fesz_sz *= oszto;
  3.       fesz_sz /= 100000;

a sorokat, egy sorba tömöríteni,
  1. fesz_sz = ((long)akku*(ref/1023)*oszto)/100000;
de nem sikerült valamiért. (Az eredmény mindig 0 lett) Egy kis videót feltettem róla. (utolsó videó) A videón látszik, hogy a kijelzésnél, még van egy kis hiba, de már javítottam. A progiba minden fontos le van írva.
Remélem e kis progival segítek elindulni a cikked írásához vezető úton.
Ha valamit rosszúl írtam volna, javítsatok ki.
(#) Beachway hozzászólása Jan 10, 2012 /
 
É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 __delay_cycles(1000);
}
}

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;
}
}
}
}
}]>>>>>
(#) szitko válasza Beachway hozzászólására (») Jan 10, 2012 /
 
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"?
(#) Beachway válasza szitko hozzászólására (») Jan 10, 2012 /
 
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ó.
(#) Beachway hozzászólása Jan 10, 2012 /
 
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.
(#) idlob válasza szitko hozzászólására (») Jan 10, 2012 /
 
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
(#) szitko válasza idlob hozzászólására (») Jan 10, 2012 /
 
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.
(#) szitko hozzászólása Jan 11, 2012 /
 
Sziasztok.
Elakadtam a belső hőmérő olvasásánál.
  1. ADC10CTL1 = INCH_10 + ADC10DIV_3;     // CPU hőszenzor ADC10CLK/4
  2.   ADC10CTL0 = SREF_1 + ADC10SHT_3 + REFON + ADC10ON + ADC10IE;
  3. // Vref = 1.5V + VSS
  4.   ADC10CTL0 |= ENC + ADC10SC;             // Mintavétel indítás
  5.   __low_power_mode_0();                                // Szundi
  6.   hoertek = ADC10MEM;

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.
(#) DecebaL válasza szitko hozzászólására (») Jan 11, 2012 /
 
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)
}
(#) szitko válasza DecebaL hozzászólására (») Jan 11, 2012 /
 
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.
(#) DecebaL válasza szitko hozzászólására (») Jan 11, 2012 /
 
A procinak az órajelét mire állítottad?.
(#) szitko válasza DecebaL hozzászólására (») Jan 11, 2012 /
 
Kalibrált 1MHz.
  1. #include "io430.h"
  2. #include "intrinsics.h"
  3. int hoertek;
  4. void main(void){
  5.   WDTCTL = WDTPW + WDTHOLD;
  6.   BCSCTL1 = CALBC1_1MHZ;
  7.   DCOCTL = CALDCO_1MHZ;
  8.   ADC10CTL1 = INCH_10 + ADC10DIV_3;
  9.   ADC10CTL0 = SREF_1 + ADC10SHT_3 + REFON + ADC10ON + ADC10IE;
  10.   ADC10CTL0 |= ENC + ADC10SC;
  11.   __low_power_mode_0();                         // Szundi
  12.   hoertek = ADC10MEM;
  13.   while(1){
  14.   ADC10CTL0 |= ENC + ADC10SC;
  15.     __low_power_mode_0();                         // Szundi
  16.   hoertek = ADC10MEM;
  17.   __delay_cycles(10000000)
  18. }
  19. }
  20. #pragma vector=ADC10_VECTOR
  21. __interrupt void ADC(void){
  22.   __low_power_mode_off_on_exit();        // Ébresztő
  23. }

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.
(#) DecebaL válasza szitko hozzászólására (») Jan 11, 2012 /
 
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.
(#) szitko válasza DecebaL hozzászólására (») Jan 11, 2012 /
 
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:
„__bis_SR_register(CPUOFF + GIE);”
ez.
A többi AD konverziót is így csináltam és azok mennek. Szerintem inkább alszom rá egyet.
(#) DecebaL válasza szitko hozzászólására (») Jan 11, 2012 /
 
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
(#) szitko válasza DecebaL hozzászólására (») Jan 11, 2012 /
 
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.
(#) icserny válasza szitko hozzászólására (») Jan 12, 2012 /
 
Idézet:
„Erre már Én is gondoltam, de megbízom icserny cikkében.”
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:
  1. #define __low_power_mode_0() (__bis_SR_register(  __SR_GIE      \
  2.                                                 | __SR_CPU_OFF))

Ez tehát nem lehet oka a problémának (egyébként is "visszajött" a program, s kaptál értéket...).
(#) icserny válasza szitko hozzászólására (») Jan 12, 2012 /
 
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.
(#) szitko válasza icserny hozzászólására (») Jan 12, 2012 /
 
Ö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".

ad.txt
    
(#) icserny válasza szitko hozzászólására (») Jan 12, 2012 /
 
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:
„É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”
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.
(#) szitko válasza icserny hozzászólására (») Jan 12, 2012 /
 
Ú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.

main.c
    
(#) szitko válasza szitko hozzászólására (») Jan 12, 2012 /
 
Ö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.
(#) JOCO10 válasza balux33 hozzászólására (») Jan 12, 2012 /
 
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.
(#) szitko hozzászólása Jan 12, 2012 /
 
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.
(#) icserny válasza szitko hozzászólására (») Jan 13, 2012 /
 
Idézet:
„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.”
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/
Idézet:
„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.”
Pedig a fentiek alapján ezt a technikát kellene csiszolni.
(#) szitko válasza icserny hozzászólására (») Jan 13, 2012 /
 
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.
(#) JOCO10 válasza szitko hozzászólására (») Jan 13, 2012 /
 
Itt Bővebben: Link használja a program a belső hőmérőt és az adc-t egyszerre.
(#) szitko válasza JOCO10 hozzászólására (») Jan 13, 2012 /
 
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.

ad.txt
    
(#) icserny válasza szitko hozzászólására (») Jan 13, 2012 /
 
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.
(#) szitko válasza icserny hozzászólására (») Jan 13, 2012 /
 
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 !
Következő: »»   28 / 139
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