РЕШЕНО Прошу помощи с кодом

Тема в разделе "Arduino & Shields", создана пользователем Ariadna-on-Line, 17 мар 2026.

  1. Ariadna-on-Line

    Ariadna-on-Line Гуру

    #define R25 3 // R = 15 KOhm
    #define R75 4 // R = 5.1 KOhm

    //----------------------------------------------
    void SinGen(int Freq, int Dur) {

    uint32_t Del = 480000/Freq; // Длительность пауз мкСек
    uint32_t Takt = (Dur * Freq) / 1000; // количество периодов
    //--------------------
    for (uint32_t i = 0; i <= Takt; i++) {

    PORTB &= ~( 1 << R25 ); // LOW
    PORTB &= ~( 1 << R75 ); // LOW
    // PORTB &= ~( (1 << R25) | (1 << R75) ); // LOW R25, R75

    delayMicroseconds(Del); // Требуется именно так. Иначе не получишь
    delayMicroseconds(Del); // 50 Гц на Дигиспарке из-за переполнения.
    PORTB |= ( 1 << R25 ); // HIGH

    delayMicroseconds(Del);
    PORTB &= ~( 1 << R25 ); // LOW
    PORTB |= ( 1 << R75 ); // HIGH
    // PORTB = (PORTB | (1 << R75)) & ~(1 << R25); // HIGH R75, LOW R25

    delayMicroseconds(Del);
    PORTB |= ( 1 << R25 ); // HIGH

    delayMicroseconds(Del); // См. выше
    delayMicroseconds(Del); // См. выше
    PORTB &= ~( 1 << R25 ); // LOW

    delayMicroseconds(Del);
    PORTB |= ( 1 << R25 ); // HIGH
    PORTB &= ~( 1 << R75 ); // LOW
    // PORTB = (PORTB & ~(1 << R75)) | (1 << R25); // LOW R75, HIGH R25

    delayMicroseconds(Del); // Этот код занимает минимум памяти
    }
    }
    //----------------------------------------------
    //==============================================
    void setup() {
    // put your setup code here, to run once:

    pinMode(R25, OUTPUT);
    pinMode(R75, OUTPUT);

    // fosc = F_CPU;
    }
    //==============================================
    void loop() {
    // put your main code here, to run repeatedly:

    SinGen(100, 1000); // Frequency (Hz), Duration(mSec)
    delay(1000);
    //==============================================
    } // LOOP END
    //==============================================
    Ввиду весны и "лесной жизни" делаю компас-металлодетектор. А для него лучшего выхода чем пищание в наушниках не придумаешь. Слушать меандр - боже упаси. Есть два пина для генерации сисуноиды. Вот об этом и речь.
    Код в реале не испытывался. Гоняется на Протеусе. Назначение - генерация синусоидального сигнала с заданной частотой и длительностью. Синусоида генерируется прекрасно. Длительность (Т), по логике - T= N / Freq. Соответственно - N = T * F. Если Т задаём в миллисекундах - N = (Tms * F) / 1000. Понятно что N - счетчик цыкла. Затык в том что цыкл не останавливается. Уже голову свернул, не могу понять причины. Прошу помощи.

    ПС. Всё оказалось не сложно. Происходило переполнение разрядов.
    uint32_t Takt = (Dur * Freq) / 1000; // количество периодов
    Решилось переходом в плавающую арифметику. И всех делов.
    float Takt = 0.001 * Dur * Freq ; // количество периодов
     

    Вложения:

    • Син.png
      Син.png
      Размер файла:
      63,2 КБ
      Просмотров:
      14
    Последнее редактирование: 17 мар 2026
  2. Asper Daffy

    Asper Daffy Иксперд

    Да, уж ...

    pisez-smal.jpeg

    Видимо, использовать тип uint64_t роскомнадзор уже запретил :(