Странный результат измерения длительности цифрового сигнала

Причем здесь прерывания. Процесс измерения занимает от одного до трех полупериодов. Если мы используем одно ядро, то непонятно как происходит формирования пиков, если процессор занят измерениями.
Возможно аппаратное переключение процессора с одной процедуру на другую производится очень быстро и все работает и в одном ядре правильно, но при двух ядрах этой проблемы просто нет. У нас процесс образования пиком и их измерение производится так, как будто это разные платы.

Покуда пользовательский код не объявлен как critical, RTOS дозволено вертеть им как угодно. И задерживать так же.

1 лайк

Да уж))) Отключил планировщик(в критичном месте), получше стало. Словом, учиться, учиться, и.т.д. Здесь так просто не разобраться. Сейчас другие дела, это ради интереса только глянул.

Спойлер
 /*
  определитель длительности ВЫСОКОГО

  Нужна развязка 4.7ком при работе с сигралом 5в

  При работе с digitalwrite возниикают расхожждения между задаваемой ддлительностью и определяемой
  как завышение так и уменьшение, что странно
  pic=10000 PP= 10001
  pic=1000 PP= 2002 !! независимо от частоты измерения. Это таймеры!!
  pic=500 PP= 501
  pic=100 PP= 101
  pic=50 PP= 51
  pic=10 PP= 10/11
  pic=5 PP= 5/6  5- редко
  pic=2 PP= 2/3
  pic=1 PP= 1/2 1 - редко
  without pic pp=1
*/
#define Pin 27  // 
#define Pin2 26  // 
#define taskENTER_CRITICAL( x )   portENTER_CRITICAL( x )

unsigned long tt, pp, tt2, pic = 1000; // pic длительность высокого в микросек

TaskHandle_t One_task;
TaskHandle_t Two_task;

#define ONE_STACK_SIZE 40000   //  4 Кб
#define TWO_STACK_SIZE 30000  // 30 Кб


void setup() {
  // put your setup code here, to run once:

  pinMode(Pin, INPUT_PULLDOWN);//, INPUT_PULLUP);INPUT_PULLDOWN);
  pinMode(Pin2,  OUTPUT);

  Serial.begin(115200);
  delay(5000);

  Serial.print("pic= "); Serial.println(pic);
  disableCore0WDT(); // Блокировка прерываний
  disableCore1WDT();
  disableLoopWDT(); // You forgot this one !

  //создаем задачу, которая будет выполняться на ядре 0 с максимальным приоритетом (1)
  xTaskCreatePinnedToCore(
    Task1code,   /* Функция задачи. */
    "One_Task",     /* Ее имя. */
    1000,       /* Размер стека функции */
    NULL,        /* Параметры */
    5,           /* Приоритет */
    NULL, //&One_task,      /* Дескриптор задачи для отслеживания */
    0);          /* Указываем пин для данного ядра */
  delay(500);

  //Создаем задачу, которая будет выполняться на ядре 1 с наивысшим приоритетом (1)
  xTaskCreatePinnedToCore(
    Task2code,   /* Функция задачи. */
    "Two_Task",     /* Имя задачи. */
    1000,       /* Размер стека */
    NULL,        /* Параметры задачи */
    5,           /* Приоритет */
    NULL, //&Two_task,      /* Дескриптор задачи для отслеживания */
    1);          /* Указываем пин для этой задачи */
  delay(500);

}
//Task1code: мигает светодиодом
void Task1code( void * pvParameters )
{
  Serial.print("Task1 running on core ");
  Serial.println(xPortGetCoreID());

  void vTaskSuspendAll();
  {
    for (;;)
    {
      digitalWrite(Pin2, HIGH);
      delayMicroseconds(pic);
      digitalWrite(Pin2, LOW);
      delayMicroseconds(pic);
    }
  }
  portBASE_TYPE xTaskResumeAll();
}
//Task2code: отслеживает длительность высокого
void Task2code( void * pvParameters )
{
  Serial.print("Task2 running on core ");
  Serial.println(xPortGetCoreID());

  for (;;)
  {
    void vTaskSuspendAll();
    {
      while (digitalRead(Pin) == HIGH) {} // Ожидаем конец высокого
      while (digitalRead(Pin) == LOW) {} // Затем надо дождаться высокого
      tt = micros(); // Начало высокого
      while (digitalRead(Pin) == HIGH) {} // Ожидаем конца высокого
      pp = micros() - tt;   // Определяем длину цуга
    }
    portBASE_TYPE xTaskResumeAll();
    Serial.print("PP= "); Serial.println(pp);
    delay(2000);
  }
}
void loop() {
  // put your main code here, to run repeatedly:

}
Спойлер