Bu bir-birining uzilish timerini almashtiradimi?

class Pseudo_Interrupt {
  //only cummulative time is important, exact interval is not
 //Class Member Variables
 //These are initialized at startup
  long OffTime = 1000;//milliseconds of off-time
 //These maintain the current state
  unsigned long previousMillis;//will store last time updated

  void Update() {
   //check to see if it's time for an Interrupt
    unsigned long currentMillis = millis();
    if ((currentMillis - previousMillis >= OffTime) {
      //Time to execute the one second code
    }
  }
}
1
Siz deyarli bor. Oldingi intervalda oldingiMillisni joriyMillis (if-statement ichida) ga o'rnatishingiz kerak. PreviousMills va currentMillis uzunligi bo'lishi kerak. "O'chirish" belgisi imzolangan tamsayı yoki uzoq muddat imzolangan bo'lishi mumkin, ammo agar siz bu belgisiz ham uzun bo'lsa, unda hamma narsa kodni aniqroq qiladi va derivat o'zgaruvchiga aylantirilmaydi.
qo'shib qo'ydi muallif Standback, manba

5 javoblar

Butun fikr juda yaxshi, lekin bir nechta o'zgarishlarni amalga oshiraman:

  • as explained by Jot in a comment, you have to update previousMillis inside the if statement. You have two choices:
    • set it to currentMillis, then OffTime will be the minimum time between the pseudo-interrupts
    • increment it by a constant amount, which I would call period, then this will be the average time between pseudo-interrupts; this is more similar to how real timer interrupts work
  • add a constructor for:
    • making the period user-selectable
    • making the action of the timer user-selectable via a callback
    • initializing previousMillis

Ushbu o'zgarishlar bilan sinf quyidagicha bo'ladi:

class Pseudo_Interrupt {
    unsigned long period;
    unsigned long previousMillis;
    void (*callback)();

public:
    Pseudo_Interrupt(void (*callback)(), unsigned long period)
        : period(period), previousMillis(millis()), callback(callback)
    { }

    void update()
    {  
        if (millis() - previousMillis >= period)
        {
            callback();
            previousMillis += period;
        }
    }
};
3
qo'shib qo'ydi
Uzluksiz muddat uchun (oldingiMillisni doimiy ravishda oshirish), masalan, o'rnatish ko'p vaqt talab qilganda portlashni yuzaga keltirishi mumkin. Bunday holda o'rnatish oxirida oldingiMillisni millisiga qo'ydim. Sketchni boshlash va o'rnatish ko'p vaqt talab etilganda portlashni oldini oladi.
qo'shib qo'ydi muallif Standback, manba

Sizning dasturingiz tomonidan chaqiriladigan funksiya bir necha funktsiyalarni amalga oshirishi mumkin, ammo barchasi emas. Tez-tez qo'ng'iroq qilsangiz, "sizning ikkinchi kodingizni" o'z vaqtida bajarishingiz mumkin. Qanday qilib tez-tez qo'ng'iroq qilishingiz kerakligini aniq bajarishingizga bog'liq. Siz asosiy kodingizni talab qila oladiganingizdan ko'ra ko'proq vaqt sarflashni talab qilishi mumkin; bu sizning shaxsiy shartlaringizga bog'liq.

Haqiqiy kesish funktsiyasi deyarli darhol voqeani boshlash uchun qanday voqeaning paydo bo'lishiga qarab chaqiriladi. Shu vaqtgacha ota-kodingizdan hech qanday vaqt olinmaydi.

Buning ta'siri samarali bo'ladimi, muayyan vaziyatga bog'liq.

Siz bergan kod sintaktik ravishda to'g'ri emas va kompilyatsiya qilinmaydi. Yadro funktsiyalari C yoki C ++ tillarida mavjud emas, va 'if' iborasida parentezlar muvozanat emas.

1
qo'shib qo'ydi
Nima bo'lishidan qat'iy nazar, kod Arduino IDE da tuzilmadi.
qo'shib qo'ydi muallif caryden, manba
Yo'q, u kompilyatorga xos emas; bu standartlarga mos keladi. Ba'zi kompilyatorlar tilni kengaytirishi mumkin. Bu ularni tilning bir qismiga aylantirmaydi.
qo'shib qo'ydi muallif caryden, manba
> Yadro funktsiyalari C yoki C ++ ga kiritilmagan ... ... bu kompilyatorga xosdir.
qo'shib qo'ydi muallif dannyf, manba
hali ham asl nusxangizni to'g'rilab qo'ymaydi
qo'shib qo'ydi muallif dannyf, manba

Ha, agar oldingi millilisni 1000 ga tenglashtirsangiz, bu taqqoslash haqiqiydir.

Vaqt xatolarini to'playotganda oldingi millisizni joriy millatlarga sozlash noto'g'ri yondashuvdir.

tahrir:

Bu erda siz umid qilmoqchi bo'lgan narsalarni qilishingiz mumkin bo'lgan oddiy narsadir.

//pseudo timer isr
//return 1 if the timer overflows MYTMR_PR
uint8_t mytmr_ovf(void) {
    static uint32_t last_time=0;        //previous time
    uint32_t current_time;

    current_time = millis();            //take current time
    if (current_time - last_time >= MYTMR_PR) {
        last_time += MYTMR_PR;          //update last time
        return 1;                       //indicate overflow
    }
    return 0;                           //indicate no overflow
}

Men ilgari tavsiya qilganidek, kod taymer uzoq muddatli bo'lishi uchun yozilgan.

Umid qilamanki yordam beradi.

tartibga solish 2: yuqorida keltirilgan kod PIC24F ustida ishlaydi, MYTMR_PR qiymati 100 ga (= 100ms)

//user loop
void loop(void) {
    //looping around
    if (mytmr_ovf()) digitalWrite(LED, !digitalRead(LED));   //flip the led
}

enter image description here

1
qo'shib qo'ydi
@dannyf, men faqat o'qiganman "faqat jamlash vaqti muhim, aniq oraliq emas". Siz to'g'ringizda, doimiy ravishda oshirilsa, uni microcontroller/protsessorning kristallari bilan bir xil aniqlik bilan ishlashga majbur qiladi.
qo'shib qo'ydi muallif Standback, manba
Men buni siz uyali telefonga yozgan deb o'ylayman.
qo'shib qo'ydi muallif user18101, manba

Oxirgi Versiyalar: 7/6/17

//--------------------------------------------------------
class Pseudo_Interrupt {

{  //These maintain the current state of the timer
public: 
volatile unsigned long previousMillis;  //will store last time updated   
volatile unsigned long lateMillis = 0;      //how late was it
volatile bool CallOneMinute = false; //facilitates while loops, 
}
// to prevent a callback set previousMillis = millis(); periodically within the 'period'
// to start the callback set previousMillis = millis() - period; lateMillis = 0;
volatile unsigned long currentMillis; 
static const unsigned long period = 1000;    //milliseconds of off-time delay
volatile unsigned long delta;
    void (*callback)();
public:
    Pseudo_Interrupt(void (*callback)(), unsigned long period)
        : period(period), previousMillis(millis()), callback(callback)
    { }

    void update()
    {       currentMillis = millis(); 
            CallOneMinute = false
            delta = currentMillis - previousMillis - period
        if (lateMillis + delta >= 0)                         
            lateMillis = delta;
            CallOneMinute = true             
        {
            callback();  //with correction to keep net correct cumulative time
            previousMillis += ( period - lateMillis ); 
    }
};
//----------------------------------------------------------
1
qo'shib qo'ydi
Sizning testingiz if (lateMillis + delta> = 0) har doim to'g'ri. volatile kalit so'zi bu erda foydasiz.
qo'shib qo'ydi muallif Sprogz, manba

Shundan beri men doimiy ravishda tez aylanaga aylantirdim. Dastur unga tushganda, uni bajaradi. Bir soniya biroz noto'g'ri, ammo jami kümülatif taxminan to'g'ri.

long OffTime = 1000;    //milliseconds of off-time

// These maintain the current state of the timer
long previousMillis;  //will store last time updated   
long lateMillis;      //how late was it

//----------------------------------------------------------------------

currentMillis = millis();     //correct for millis() overflow
if (currentMillis - previousMillis < 0 )
    currentMillis = currentMillis + 32768;
{
    if (currentMillis - previousMillis >= OffTime - lateMillis )

       //Assume the difference is longer than 1000 milliseconds
       //because the sample time will be late but not by much
        lateMillis = currentMillis - previousMillis - OffTime;

       //Thus, cumulative time is essentially correct 
        //Time to execute the one second code here
        do some code
    else
        return;
    }
// ---------------------------------------------------- 
} // End Of Run Repeatedly
0
qo'shib qo'ydi
millis() toshqinga oid ma'lumotlaringiz noto'g'ri. Faqat noldan o'tib ketishingizga ruxsat bering va barcha vaqt parametrlarini imzosiz qoldiring. Aslida, bu savoldan kodda buni hal qilish kerak bo'lgan yo'l to'g'ri edi.
qo'shib qo'ydi muallif Sprogz, manba