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   87 / 139
(#) idlob válasza uli hozzászólására (») Nov 20, 2012 /
 
Az ADC csatornák sorozatának konverziójára van konfigurálva, trigger után 2, 1, 0 csatorna sorrendben hajtja végre a konverziót, majd várakozik újabb triggerre.
Az MSC bit bebillentésével azt éred el, hogy amint befejezte az egyik csatorna konverzióját rögtön a következőre lép.
A konverziót az ADC10SC bit felfutó élére kezdi (a bit automatikusan törlődik). Tehát pl. a ADC10CTL0 |= ADC10SC; kifejezéssel.
A használható irodalom a FUG, szépen le van írva állapotgráfokkal együtt az ADC működése.
A kód elkezdi inicializálni a DTC-t is, természetesen annak is le van írva a működése.
(#) icserny válasza uli hozzászólására (») Nov 20, 2012 /
 
Ha az MSC bit nulla, akkor minden konverziót külön el kell indítani. Ha MSC = 1, mint a példádban, akkor pedig csak egy triggerjel kell, arra lefut a teljes szekvencia, amit beállítottál.

A mikrovezérlő gyári mintaprogramjai között számos (kimerítő mennyiségű) mintapéldát találsz az ADC kezelésére.

Ha nem használod a DTC-t (ami tulajdonképpen az ADC DMA csatornája), akkor minden konverzió eredményét külön ki kell olvasni (a gyári példákban levő ADC10SA = 0x200; sorban a fix cím helyett a tömb kezdőcímét add meg!). Ha a DTC opciót használod, akkor közvetlenül belepakoltathatod egy tömbváltozóba az adatokat, úgy talán egyszerűbb lesz az adatfeldolgozás (átlagszámítás, miegyéb).
(#) icserny hozzászólása Nov 20, 2012 / 1
 
Az MSP430G2553 hardveres UART full duplex használatához portoltam a PICula projektemben kidolgozott szoftveres bufferelésű (gyűrű táras) és interruptos kezelésű uart_putc(), uart_getc() függvényeket.

Használata: A projektekbe fel kell venni a hw_uart_buf.c állományt, s a fenti függvényket használó fordítási egységekbe (pl. főprogram) be kell csatolni hw_uart_buf.h fejléc állományt.

Egy kis bónusz: IAR EW esetén ha felüldefiniáljuk a putchar() függvényt, akkor a printf() függvény is használható a kiírásra. Ugye, milyen egyszerű? Mintapélda:
  1. #include <msp430.h>
  2. #include <stdint.h>
  3. #include <stdio.h>
  4. #include "hw_uart_buf.h"
  5.  
  6. int putchar(int outChar) {
  7.   uart_putc((uint8_t)outChar);
  8.   return outChar;
  9. }
  10.  
  11. char c;
  12. int main( void ) {
  13.   WDTCTL = WDTPW + WDTHOLD;            //Letiltjuk a watchdog időzítőt
  14.   DCOCTL = CALDCO_1MHZ;                //DCO beállítása a gyárilag kalibrált
  15.   BCSCTL1 = CALBC1_1MHZ;               //1 MHz-es frekvenciára  
  16.   uart_init(BPS_9600);
  17.   printf("NLIsten hozott a Launchpad projekthez!");
  18.   printf("hello_print program (hw_uart_buf)NL");
  19.   while (1) {
  20.     c=uart_getc();
  21.     printf("Vett karakter: %c = %dNL",c,c);
  22.   }
  23. }



Ha a printf() függvényt nem akarjuk használni, akkor a kiíratást a hw_uart_buf.c állományban definiált (itt már többször bemutatott) függvények segitségével is végezhetjük. Például így:
  1. #include <msp430.h>
  2. #include <stdint.h>
  3. #include "hw_uart_buf.h"
  4.  
  5. char c;
  6. int main( void ) {
  7.   WDTCTL = WDTPW + WDTHOLD;            //Letiltjuk a watchdog időzítőt
  8.   DCOCTL = CALDCO_1MHZ;                //DCO beállítása a gyárilag kalibrált
  9.   BCSCTL1 = CALBC1_1MHZ;               //1 MHz-es frekvenciára  
  10.   uart_init(BPS_9600);
  11.   uart_puts("NLIsten hozott a Launchpad projekthez!NL");
  12.   uart_puts("hello_int program (hw_uart_buf)NL");
  13.   while (1) {
  14.     c=uart_getc();
  15.     uart_puts("Vett karakter: ");
  16.     uart_putc(c);
  17.     uart_puts(" = ");
  18.     uart_outdec((int32_t)c,0);
  19.     uart_puts(" NL");
  20.   }
  21. }


Megjegyzések:
1. Sajnos, a fórummotor nem engedi berakni a newline karaktereket, ezért NL-lel helyettesítettem!
2. Az IAR EW projekt opcióknál célszerű a printf függvény használatát "Auto"-ra állítani, hogy fölösleges formátumok kezelésével ne tömje tele a programunkat.
(#) uli hozzászólása Nov 21, 2012 /
 
Sziasztok! Köszi mindkettőtöknek a segítséget. Valami még mindig nem tiszta. Átnéztem a FUG-ot meg a mintaprogramokat, de sehol sem találtam meg ami nekem kéne, és amiről icserny is írt.
Tudnátok egy programrészletet mutatni, hogy állítsam be a DTC-t úgy, hogy az ADC10MEM egy 2 elemű tömb legyen és azt a későbbiekben hogyan tudom kiolvasni egy x és y változóba? Köszönöm!
(#) szitko válasza uli hozzászólására (») Nov 21, 2012 /
 
Ezt a programrészletet a kazánvezérlőmből szedtem ki.
  1. unsigned int adc_temp[63];
  2.  
  3. void analog_setup(uint16_t csat, uint8_t port){
  4.     ADC10CTL0 &= ~ENC;
  5.     ADC10CTL1 = CONSEQ_2 + csat;                     // többszöri konverzió, a "csat" bemenetről
  6.     ADC10CTL0 = SREF_1 + ADC10SHT_2 + MSC + REFON + REF2_5V + ADC10ON + ADC10IE;
  7.     // ADC10ON, megszakítás eng, referencia be, ref 2.5volt
  8.     ADC10DTC1 = 0x40;                                // 64 konverzió
  9.     ADC10AE0 = port;                                 // ADC bemenet kiválasztása
  10. }
  11. void homero_olv(){
  12.     ADC10CTL0 &= ~ENC;                         // analóg kikapcsolása
  13.     while (ADC10CTL1 & BUSY);                  // várunk, ha ADC10 foglalt
  14.     ADC10SA = (uint16_t) adc_temp;             // adatok mentése "adc_temp"-be
  15.     ADC10CTL0 |= ENC + ADC10SC;                // mintavétel és konverzió indítása
  16.     __low_power_mode_0();                      // LPM0 mód bekapcsolás
  17. }
  18. ........
  19. #pragma vector=ADC10_VECTOR
  20. __interrupt void ADC10_ISR (void){
  21.   __low_power_mode_off_on_exit();        // Ébresztő
  22. }

64 konverziót csinál, és az értékeket az "adc_temp" nevű tömbbe menti.
Remélem ez segít.
(#) uli válasza szitko hozzászólására (») Nov 21, 2012 /
 
Köszönöm, sokat segített!!
(#) icserny válasza szitko hozzászólására (») Nov 21, 2012 /
 
Idézet:
„unsigned int adc_temp[63];”
Ennyire ne spórolj a memóriával, mert ez csak 63 tömbelemet definiál! (Magyarázat: Nem a maximális indexet, hanem a tömbelemek darabszámát kell megadni!)
(#) szitko válasza icserny hozzászólására (») Nov 21, 2012 /
 
Nem spórolok, pedig már lassan kéne. Az eredeti programban, nincs meghatározva a tömb mérete. Most csak valamiért beírtam. De hogy miért......?
(#) icserny válasza szitko hozzászólására (») Nov 21, 2012 /
 
Az eredeti programban, nincs meghatározva a tömb mérete.
Pedig nagyon célszerű beírni:
  1. unsigned int adc_temp[64];”

Különben honnan tudja a fordító, hogy mekkora memóriát foglaljon? A 63-mal az a baj, hogy az ADC "túlír" rajta, s beleír egy másik változódba.
(#) szitko válasza icserny hozzászólására (») Nov 22, 2012 /
 
Ááá, akkor ezért nem működik normálisan a program. Mostanában, egyre több "alapvető" hibát nem veszek észre, és követek el.
Köszönöm a javítást!
(#) icserny hozzászólása Nov 22, 2012 /
 
Jól pofára ejtett engem az ADC "ismételt konverzió" módja! A korábbi szingli méréseknél a konverzió után egyszerűen pollinggal vártam a ADC BUSY jelzőbitjének megszűnését. Az "ismételt konverzió" módban azonban nem szűnik meg a foglaltság (pedig direkt nem folytonos módot konfiguráltam!). Sok kínlódás után végül a megszakításkérő jelzőbit figyelésére tértem át, azzal működik a dolog.
  1. /*-------------------------------------------------------------
  2.  * Sorozat mérés egy ADC csatornában, 1,5 V a belső referencia
  3.  * Feltételezzük, hogy külső jel mérése esetén az analóg funkció
  4.  * már engedélyezve van (az ADC10AE0 regiszterben).
  5.  *-------------------------------------------------------------
  6.  * chan - csatornaválasztó bitek (a csatorna sorszáma << 12)
  7.  * pbuf - a mérési adatok tárhelyének címe
  8.  * ndat - az egy sorozatban elvégzendő mérések száma
  9.  */
  10. void ADC_multi_meas_REF1_5V(uint16_t chan, uint16_t *pbuf, uint8_t ndat) {
  11.   ADC10CTL0 &= ~ENC;                   //Az ADC letiltása újrakonfiguráláshoz
  12.     while (ADC10CTL1 & BUSY);          //Várakozás a foglaltság végére
  13.   ADC10CTL0 = ADC10SHT_3               //mintavétel: 64 óraütés
  14.              | ADC10ON                 //Az ADC bekapcsolása
  15.              | SREF_1                  //VR+ = VREF+ és VR- = AVSS
  16.              | REFON                   //Belső referencia bekapcsolása
  17.              | MSC;                    //Többszörös mintavétel és konverzió
  18.                                        //1,5 V-os referencia kiválasztása
  19.   ADC10CTL1 = ADC10SSEL_0              //csatorna = 'chan', ADC10OSC az órajel
  20.              | SHS_0                   //ADC10OSC indítja a mintavételezést
  21.              | CONSEQ_2                //Ismételt egycsatornás konverzió
  22.              | chan;                   //Az analóg csatorna kiválasztása  
  23.   ADC10DTC0 &= ~(ADC10TB+ADC10CT);     //Egy blokk mód
  24.   ADC10DTC1 = ndat;                    //ndat mérést végzünk  
  25.   ADC10SA = (unsigned short)pbuf;      //adatok mentése a mutatóval jelzett helyre
  26.   ADC10CTL0 |= ENC + ADC10SC;          //Konverzió engedélyezése és indítása
  27.   while (!(ADC10CTL0 & ADC10IFG));     //Várakozás a konverzió végére
  28. }


A teljes mintapéldát lásd a github lerakatomban! (4_cikk/4_ADC_multi_ref1)
(#) szitko válasza icserny hozzászólására (») Nov 23, 2012 /
 
Cikk is lesz belőle? Vagy még mindig nem működik rendesen a cikk szerkesztés?

Az IAR 5.51 mennyivel jobb, tud többet, mint az elődei? És milyen korlátozás van benne?
A hozzászólás módosítva: Nov 23, 2012
(#) icserny válasza szitko hozzászólására (») Nov 23, 2012 /
 
Idézet:
„Cikk is lesz belőle?”
Az idén nem lesz.
Idézet:
„Az IAR 5.51 mennyivel jobb, tud többet, mint az elődei?”
Legfőbb előnye, hogy ez letölthető, az elődei meg már nem... Más különbség nem tűnt fel.
Idézet:
„És milyen korlátozás van benne?”
Ez most egy próbaverzió (de már nem sok ideje van hátra), mert az egyik projektem már túllépte a memóriakorlátot.
(#) icserny válasza icserny hozzászólására (») Nov 24, 2012 /
 
Azt elfelejtettem mondani, hogy szeptembertől belecsöppentem a felsőoktatásba, s ha cikk nem is várható egyhamar, a Mikrokontrollerek programozása c. tantárgyi honlapomon az MSP430 tananyag menüpontban elérhetők a hétről-hétre szaporodó előadásvázlatok. A közérdeklődésre számot tartó példaprogramok pedig a https://github.com/icserny címen találhatók.
A hozzászólás módosítva: Nov 24, 2012
(#) szitko válasza icserny hozzászólására (») Nov 24, 2012 /
 
Számomra, mint kezdő amatőr hobbista, az oldalad maga a kánaán.
Gratulálok hozzá!
(#) szitko hozzászólása Nov 24, 2012 /
 
Sziasztok.

IAR-ban, nem értem ezt a hibát:
Idézet:
„Error[e16]: Segment DATA16_Z (size: 0x269 align: 0x1) is too long for segment definition. At least 0x71 more bytes needed. The problem occurred while processing the segment placement command
"-Z(DATA)DATA16_I,DATA16_Z,DATA16_N,TLS16_I,DATA16_HEAP+_DATA16_HEAP_SIZE=0200-03FF", where at the moment of placement the available memory ranges were "CODE:208-3ff"
Reserved ranges relevant to this placement:
200-3ff DATA16_I”

Létrehozok/nák egy tömböt, ("uint16_t tömb[256];") és ebbe szeretném bemásolni az I2C-n érkező adatokat, USCIAB0TX magszakításban:
ISR: .... tömb[256 - rx_count] = UCB0RXBUF; ....
Miért " túl nagy a segmens definíció"? Ha kiveszem megszakításból a beolvasást, nem szól egy szót sem.
(#) icserny válasza szitko hozzászólására (») Nov 24, 2012 /
 
Idézet:
„Létrehozok/nák egy tömböt, ("uint16_t tömb[256];")”
Ez 512 bájt, lefoglalja a teljes RAM-ot.
Idézet:
„Ha kiveszem megszakításból a beolvasást, nem szól egy szót sem.”
A megszakításnak is van helyigénye a RAM-ban, mert el kell mentenie a megszakított program állapotát. De már nincs hová....
(#) szitko válasza icserny hozzászólására (») Nov 24, 2012 /
 
Köszönöm szépen.

Így már világos, hogy a "char tömb[210]" miért engedi még meg.
Akkor már csak azt kell kitaláljam, hogy hogyan írjam ki az I2C-n érkező adatokat UART-ra, megszakításban. Legfeljebb majd a PC-re marad a feldolgozás.
(#) mechanika hozzászólása Nov 24, 2012 /
 
Sziasztok!

Az MSP4302452 három különböző I/O portjára közvetlenül rá köthetek három ilyen ledet: led. ?

Köszi!

A hozzászólás módosítva: Nov 24, 2012
(#) icserny válasza mechanika hozzászólására (») Nov 25, 2012 /
 
Közvetlenül sohasem, csak áramkorlátozó ellenálláson keresztül. S az áramot a mikrovezérlőhöz kell szabni, az a korlátozó tényező.

A 3x20 mA határesetnek tűnik, a kimeneti feszültség ilyenkor már leesik (ez akkor érdekes, ha a mikrovezérlő más kimeneteit közben logikai kimenetnek használod). Az adatlap szerint ugyanis az összes portlábon kivett áram nem lehet több 48 mA-nél, ha el akarod kerülni a 10 %-osnál nagyobb feszültségesést ( 3V-on -0.3V).

Szóval az alkalmazástól is függ, hogy mit engedhetsz meg. Ha zseblámpa lesz, akkor nem látom akadályát. Ha kényesebb az alkalmazás (ahol a LED csak jelzőfény), akkor viszont nem kellene teljesen (20 mA) kihajtani LED-eket.
(#) mechanika válasza icserny hozzászólására (») Nov 25, 2012 /
 
Köszi!

A mikrovezérlőt fényerő szabályozásra használnám, a programot a PWM ről szóló cikk 8_2. alapján raktam össze. Timer_A-t be tudom állítani két kimenetre, de három lábra sehogy nem jön össze.
Ha van tippetek, szívesen várom!
(#) icserny válasza mechanika hozzászólására (») Nov 25, 2012 /
 
A cikkben szereplő MSP430G2231-gyel szemben az MSP430G2553 mikrovezérlő két darab Timer_A3 modult tartalmaz. A második modul (Timer1_A3) mindhárom Compare csatornája kivezethető a Port2 lábakon. A pwm_cont példa alapján lehet elindulni, s összehozható három hardveresen vezérelt PWM.
(#) szikorapéter hozzászólása Nov 25, 2012 /
 
Sziasztok.Az lenne a kérdésem hogy az msp430 g2231-Ic-vel lehetne-e 2X16LCD-re óra perc másodperc kijelzéssel egybekötve?A felső sorba pedig valamilyen dátumhoz valami emlékeztető szöveget kiiratni vele.Ha ez megoldható.A válaszokat előre is köszönöm.
(#) szitko hozzászólása Nov 26, 2012 /
 
Sziasztok.

Egy számomra érthetetlen problémába ütköztem, és nem találom rá a megoldást.
A kazánvezérlő programom tesztelése során, észrevettem egy hibát, melyet az eeprom (24lc512) írásánál csinál a program, és nem tudok rájönni, hogy miért nem csinálja az amit mondok neki. Röviden a lényeg: Az eepromban tárolok két hőértéket (k_fok, v_fok), 2x2 bájtban, melyek ~12 percenkét kerülnek mentésre. Az eeprom minden második oldalának első bájtjaiba az idő/dátum kerül beírásra (prg. részlet). A gondom a második változó (v_fok) beírásánál van, ugyanis azt valamiért nem akarja végrehajtani a program, és nem tudok rájönni, hogy miért. Azért nem értem a dolgot, mert a "v_fok" változón kívül minden adatot szépen elment az eepromba, időt, dátumot, k_fok-ot.
Bár a program részletből szerintem nem derül ki semmi, de azért berakom:
  1. if(!(ram_addr & 0xff)){                 // ha az eeprom 2 oldalt beírt, beírja az órát
  2.           int min_hour = min << 8 | hour;
  3.           int day_month = day << 8 | month;
  4.           int year_h = year << 8 | 0x00;
  5.          
  6.           E_24lc512_tx_byte(ram_addr, min_hour, 4);
  7.           delay_ms(20);
  8.           ram_addr = ram_addr + 2;
  9.           E_24lc512_tx_byte(ram_addr, day_month, 4);
  10.           delay_ms(20);
  11.           ram_addr = ram_addr + 2;
  12.           E_24lc512_tx_byte(ram_addr, year_h, 4);
  13.           delay_ms(20);
  14.           ram_addr = ram_addr + 2;
  15.      }  // if    
  16.      E_24lc512_tx_byte(ram_addr, k_fok, 4);
  17.      delay_ms(20);
  18.      ram_addr = ram_addr + 2;
  19.      E_24lc512_tx_byte(ram_addr, v_fok, 4);
  20.      ram_addr = ram_addr + 2;

És két analizátor kép:

(#) idlob válasza szitko hozzászólására (») Nov 26, 2012 /
 
Szia!
Kíváncsiságból felcserélném a 16. és 19. sort. Vajon akkor a k_fok nem kerül kiírásra?!
(#) szitko válasza idlob hozzászólására (») Nov 26, 2012 /
 
Ezt még nem próbáltam. Azért furcsa a jelenség, mert mindkét sor, változó, egyforma. A k_fok és a v_fok is int típusú. Elsőnek azt hittem, hogy az eepromba nem tudok egymás után ennyi adatot bevinni, de erre nincs utalás az adatlapban, és ha csak a két hőértéket írom/nám be, tehát az idő/dátum kimarad, akkor se írja be a másodikat, csak elkezd valamit csinálni az i2c vonalon (v_fok kép).
(#) exorcist válasza szitko hozzászólására (») Nov 26, 2012 /
 
És ha a 19. sor után is berakod a 20ms delayt? (bár lehet hülyeség, mert nem tudom mi történik a 20. sortól.)
A hozzászólás módosítva: Nov 26, 2012
(#) szitko válasza exorcist hozzászólására (») Nov 26, 2012 /
 
Köszi. De...inkább leírom.

A k_fok kép = 16. sor, a v_fok kép = 19. sor. Közte látszik a 20ms késleltetés, (a kép jobb oldalán, [T1-T2] = 20.26....ms). Tehát, kiküldi az eepromnak a k_fok adatot, vár 20ms-ot, és elkezdi kiküldeni a v_fok adatot, csak azt nem fejezi be, (hozzáteszem, hogy a program nem áll le, ugyan úgy fut tovább, és ha eltelt a 12 perc, ismét beírja a k_fokot, és a v_fokot nem.). Ez látható a két analizátor képen, csak ha egy képen lenne, akkor nem lehetne értelmezni, ezért van kettőn.
Ebből adódik, hogy a 19. sor után már értelmetlen a késleltetés, mivel a 19. sorral van baj. Egyébként, a 19. sor után visszatér a program, a főciklusba, ahol engedélyezi az előzőleg letiltott port2 megszakítást, töröl egy-két változót, stb...
(#) icserny válasza szitko hozzászólására (») Nov 26, 2012 /
 
Az I2C buszon van olyan eszköz vagy kimenetnek konfigurált láb ami hardver ütközést okozhat? (Le- vagy felhúzás, amikor nem kellene?) Más okot nem tudok, ami miatt elakadna (v_fok esetében) az első bájt kiküldése.
(#) szitko válasza icserny hozzászólására (») Nov 26, 2012 /
 
Van más eszköz, de nem okoz ütközést. Legalábbis azt hiszem. Az SDA-n van egy LCD (SPI), és az i2c-n van még egy RTC. De ha az eeprom művelet megy természetesen minden tiltva van, máskülönben az első adatot sem írná ki az eepromba. Ezenkívül az eeprom törlésével, laponként, és az olvasásával sincs semmi baj. A törlést úgy csinálom, hogy laponként feltöltöm 0xff-el. Szó nélkül megcsinálja. (Már PicKit2 -vel is ellenőriztem, hátha az olvasás a rossz, de nem, minden második 2 bájt 0xff.)
A hozzászólás módosítva: Nov 26, 2012
Következő: »»   87 / 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