Warning: Illegal string offset 'name' in [path]/includes/functions.php on line 6439
ATMELis un assemblers
+
1 2 3 ...

thread: ATMELis un assemblers

  1. #1
    Senior Member
    Nov 2009
    Jēkabpils
    2,055

    ATMELis un assemblers

    Nolēmu tomēr rakstīt jaunā tēmā.
    Tātad turpinu cīnīties (iepazīties) ar ATTINY13. Uz darbagalda ir watchdog un enerģijas taupības režīmi. Uzrakstīju kodu, kas iestāda watchdog taimeri uz maksimālo periodu, dodu šim tiesības ar pārtraukumu pamodināt čipu un tad cilpā iedzenu čipu power down stāvoklī. Pārtraukumā nenotiek nekādas darbības, tikai čips pamostas un turpina darbības - šajā gadījumā invertē vienu izeju pie kuras ir LEDs, tad atlec uz cilpas sākumu un atkal tiek iedzīts power down stāvoklī. Līdz nākamajam pārtraukumam. Viss strādā. LEDs apmēram 8 sekundes dae, tad 8 sekundes nedeg u.t.t. Bet radās jautājums:
    Tātad izejas power down modē paliek tā kā bija? Nav tā, ka visas tiek atrubītas nost? Jebšu esmu kaut ko saputrojis, un čips netiek iedzīts power down? Datašītā īsti nevaru saprast. Raksta, ka i/o clk tiek apturēts, bet kas notiek ar izejām...
    :
    .macro outp 
        ldi temp, @1
        out @0, temp
    .endmacro
    
    .org 0x0000
        rjmp _reset_
    .org 0x0008
        rjmp _iv_wdt_
         
    _reset_:
        cli
        outp SPL, LOW(RAMEND)
      
        outp WDTCR, (1<<WDCE)
        outp WDTCR, (1<<WDP0)|(0<<WDP1)|(0<<WDP2)|(1<<WDP3)|(1<<WDTIE)
        outp MCUCR, (0<<SM0)|(1<<SM1)|(1<<SE)
        sei
    
    _main_:
        sleep
        sbic PORTB, PB4
        rjmp lbl_clear_bit
        sbi PORTB, PB4
        rjmp _main_
    lbl_clear_bit:
        cbi PORTB, PB4
        rjmp _main_
    
    _iv_wdt_:
        reti

  2. #2
    Moderator
    Jan 2009
    Rīga
    4,417

    Nu. Savulaik spēlējos ar tiny2313. Bija bišku citas prasības, bet... Uzmanīgi jīzlasa vaisas nianses par power down lietām. iklīdz kaut ko neievēro tad nekas nestrādā. Jurkinam iss itkā strādā. Atceros ka bija rekomendācija par enerģijas parētiņa samaināšanu un manipulācijam ar PINiem lai samazinātu realo patēriņu. Filosofiski jāpieņem ka katra kāja ir kā MOSFETu pustilts+ESD diodes. Aizsūtot MCU gulēt apstājas clock generatori un CU neko netērē. Pamostoties (WDT vai kas cits) tiek palaisti MCU clock generatori un nospieta (iespējams advancēta, lai netraumētu PINus) reset poga. Ir jālasa datasheet un jaeksperimentē. Piemeram paskaties kādā stāvoklī ir DDR, PORT un PIN pēc pamošanās. Vārdu sakot tur ir nianses kuras atkarīgas no konrētā udevuma un MCU sleep realizācijas.

  3. #3
    Senior Member
    Aug 2008
    565

    Kāda velna pēc tu to dari assamblerā!!!!!!!!!!!!!!!!!!????????????
    Sarežģītības par maz.

    Ja iedzen atmeli gulēšānā tad cik atceros arī izvadi jāizzslēdz, citādi atmelis guļ patērā kaut kādus tu nanoampērus, mikroampērus, vai cik nu tur bija bet taus ledz uz kājas 20MA un nekāda ekonomija. Neatceros kas bija ar iebūvēto puul up.


    Es kādreiz taisīju ko samērā līdzīgu uz Tiny45 un Tiny85, mazāki nebija.

    Te mana programma vari izķidāt kā piemēru.

    :
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <avr/wdt.h>
    #include <avr/sleep.h>
    #include <util/delay.h>
    
    //#define F_CPU 1000000UL
    
    #define START_DELAY 15         //Seconds Blink led
    #define VALVE_ON_TIME 1000     // mili seconds
    #define DELAY_AFTER_MOUTION 15 //Seconds
    
    
    #define LED_OFF() PORTB&=~(1<<PB1) //2
    #define LED_ON()  PORTB|=(1<<PB1)
    #define LED_OUTPUT_MODE()   DDRB|=(1<<PB1)
    
    #define VALVE_OFF() PORTB&=~(1<<PB4)
    #define VALVE_ON()  PORTB|=(1<<PB4)
    #define VALVE_OUTPUT_MODE() DDRB|=(1<<PB4)
    
    #define MOUTION_DETECTOR_INPUT_MODE() DDRB&=~(1<<PB3)
    
    
    unsigned int cikls;
    
    ISR(WDT_vect) 
    {
     WDTCR |= _BV(WDIE); // Alow wachdog interupt, otherwise reset
    }
    
    
    int main(void)
    {
       LED_OUTPUT_MODE();
       VALVE_OUTPUT_MODE();
       VALVE_OFF();
       MOUTION_DETECTOR_INPUT_MODE();
    
       ADCSRA &= ~(1<<ADEN);                     //turn off ADC
       ACSR |= _BV(ACD);                         //disable the analog comparator
       MCUCR |= _BV(7) | _BV(2);                 //turn off the brown-out detector
    
    
      for (cikls = 0; cikls < START_DELAY; cikls++)
         {
          _delay_ms(250);
          LED_ON();
          _delay_ms(250);
          LED_OFF();
          _delay_ms(250);
          LED_ON();
          _delay_ms(250);
          LED_OFF();
          }
    
    
     while(1)
      {
       VALVE_OFF();
       if(PINB&(1<<PB3)) 
        {
         VALVE_ON();
         _delay_ms(VALVE_ON_TIME);
         VALVE_OFF();
         for (cikls = 0; cikls < DELAY_AFTER_MOUTION; cikls++)     _delay_ms(1000);
        }
      VALVE_OFF();
    
    
    // Sleep controll                          
      set_sleep_mode(SLEEP_MODE_PWR_DOWN); // do a complete power-down
      sleep_enable();                      // enable sleep mode
      sei();                               // allow interrupts to end sleep mode                                    
      wdt_enable(WDTO_60MS);
      WDTCR |= _BV(WDIE);                  // Alow wachdog interupt, otherwise reset
      sleep_cpu();                         // go to sleep
      sleep_disable();                     // disable sleep mode for safety
      wdt_reset();
      wdt_disable();
      cli();                               // disable interupts
       }
    
    }
    Manā piemērā Atmelis guļ, ik pa laikam pamostās, apskatās, kas notiek, un ja vis OK tad atkal ātri iet gulēt.

  4. #4
    Senior Member
    Nov 2009
    Jēkabpils
    2,055

    To vai veikt tikai pamodināšanu un iet uz priekšu vai pamodināt un restartēt var izvēlēties. Manā gadījumā ir pamodināšana bez restarta. PORT un DDR toč ir tādā pašā stāvoklī kā pirms miega. Tam tā arī pēc loģikas vajadzētu būt. Bet mani izbrīna, ka miega laikā tas LEDs turpina degt, ja ir iedegts, MCU kloki izslēdzas un enerģiju netērē, bet, ja kaut kas ir pie porta un ir ieslēgts, tad turpina tērēt enerģiju. Var jau būt, ka tas ir pareizi un loģiski, un par to, lai netērētu ir jāparūpējās pašam.
    Uzrakstīju un ieraudzīju Powerona atbildi. Paldies. To arī gribēju dzirdēt, ka par izvadiem jāparūpējas.
    Kāpēc assemblerā? Izglītošanās nolūkos. Nu nav jau šis tik sarežģīts! Sevišķi šitādiem maziņiem nolūkiem.

  5. #5
    Senior Member
    Apr 2014
    Sigulda
    118

    ir doma arī izmēģināt uzkodēt kaut ko 'vienkāršu asamblerī, bet katru reizi, kad ieraugu, paliek bail

  6. #6
    Moderator
    Jan 2009
    Rīga
    4,417

    Atgādināšu. Patēriņs nesamazinās uz 0 femtoampēriem. CMOS trigeri rij enerģiju pārslēgšanās brīdi, tāpēc patēriņš ir miliampēros. Kamēr vis atrodas stabilā stāvoklī (clk nav, nekans netiek pārslēgts), timēr patēriņš ir nanoampēros. Attiecīgi IO reģistri paliek noteiktā stāvoklī un netērē neko, vai tērē gandrīz neko (nA). Paskaties uz iseju jā half-bridge shēmiņu. Tur nav nekā, kas var tērēt, jneskaita CMOS SR trigerus reģistors, bet tie ir nanoampēri. Nejauc absoluto nulli ar skaitli, kurš ir tuvs absolūtai nullei.

  7. #7
    Senior Member
    Nov 2009
    Jēkabpils
    2,055

    Kā māca vecs latviešu sakāmvārds - acis darba izbijās, rokas darba nebijās . Kamēr nebiju iesācis, tas asms likās kaut kas drausmīgs. Bet tad tā lēni un mierīgi uzkodēju visu (gandrīz, grūtāko uzkodēju) "1 wire" algoritmu. Protams, ka lasīju literatūru un skatījos paraugus.
    Protams, vienmēr var teikt - tak paņem atmeli ar 256K programmu atmiņu un kodē kaut C# (pārspīlēju laikam), un teicējam būs taisnība zināmā mērā. A bet es sporta pēc gribu iedzīt to visu 1K .

    Poweron, visu saprotu Tavā programmā izņemot vienu:
    kāpēc suņa pārtraukumā vajag atļaut pārtraukumu?

  8. #8
    Senior Member
    Jun 2006
    Cēsu novads
    989

    Katram savs. Man assembleris tieši liekas vienkāršs. Atliek zināt tos dažus desmitus komandu un visu var iztaisīt, un galvenais - patiešām zini, kā tas viss strādā. Bet kā C ir organizēts, piemēram, delay_ms(250); ? Kā es varu uzzināt, cik tas ir precīzs? Assemblerī es to aiztures precizitāti zinu precīzi. Man kolēģis, kas programmē attiny C pašreiz cīnās ar delay precizitāti. Patreiz taisu uz PC programmu, kas sazinās ar mikrokontrolieri un nodrošinās, lai uz datora ekrāna vizuāli attēlotu to, kā darās Atmelis. Taisu to Javā. Kāpēc tieši Javā? Tāpēc lai strādātu gan zem windows, gan linux un vēl visa kā cita. Vot Java tās gan ir šausmas! Viss tas lērums swing komponentu metožu, kas ir jāzina, lai kaut ko uz ekrāna saveidotu. Starp citu javā tie delay ir kaut kas drausmīgi neprecīzs, Pietiek paralēli uz datora palaist kādu citu procesu un tie delay intervāli sāk stiepties. Delphi7, ar ko darbojos iepriekš - tāpat. Nevaru sagaidīt, kad atkal tikšu no šitā vājprāta atpakaļ pie assemblera.

  9. #9
    Moderator
    Mar 2008
    Ogre
    1,445

    avr asm nav ne vainas, pats savu laiku knibinājos. tagad gan aiz slinkuma, sīkumus uz arduino taisu. Neko nopietnāku pagaidām nav bijis vajadzība lietot. Bet jā power down jau tikai pašā procesorā tupa enerģiju, par pārējo jārūpējas pašam.
    If it's worth doing, it's worth overdoing, right? / Tory Belleci, Mythbusters /

  10. #10
    Senior Member
    Nov 2009
    Jēkabpils
    2,055

    Vispār konkrētie humori ar tiem tīņiem.
    Ja sunim ieliek vieninieku WDTIE bitā, tad šis taisa tikai pārtraukumus, ja ieliek vieniniekus gan WDTIE gan WDE, tad pirmajā reizē uztaisa tikai pārtraukumu, otrajā pārtraukumu un aiziet uz reset. It kā viss ok, tā jābūt. Nomainu WDE atkal uz nulli, nokompilēju, pāršuju,bet tīnis turpina katrā otrajā pārtraukumā iet uz resetu. P....s kā mazais ezītis, kamēr pamēģināju ielikt citu tīni. Iešuju to pašu - viss ok, tikai pārtraukumi. Uzlieku WDE = 1, nokompilēju iešuju - viss ok, pārtraukums, tad pārtraukums + resets. Nomainu atpakaļ WDE = 0, nokompilēju, iešuju. Bāc! Atkal vecā dziesma. Atlieku atpakaļ iepriekšējo tīni (kuram palika WDE = 0, bet negāja kā vajag), viss ok. Izrādās, viss ok, ja noņem uz brīdi barošanu. WTF?

+