Котуинко

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить
Друг Кота
Аватара пользователя
Сообщения: 3168
Зарегистрирован: Чт мар 26, 2009 04:35:04
Откуда: Москва

Сообщение Полосатый »

Туда просто буквы засовываются, без развёртки.

Вот тут, начиная с поста от 10 марта 2023:
https://radiokot.ru/forum/viewtopic.php ... 0&start=20

*
Не, того, для чего это надо, никто никогда не видел :)


Добавлено after 1 hour 33 minutes 10 seconds:

Впендюрил микрос, даже отключил чтение потенциометра и жёстко задал период - всё равно длительность полупериода дрыгается примерно в пределах 4-х мкс. Не понимяу.
Спойлер

Код: Выделить всё

// Set up potentiometer pin
#define POT_PIN A3

// Set up clock out pin
#define CLC_OUT 9

// Set up free pin (для ловли наводок)
#define FREE_PIN A1

// Set up random out pin (выход данных)
#define RANDOM_OUT 10

// Set up MFM out pin (выход МЧМ)
#define MFM_OUT 2

 int RND = 0;    // текущий бит данных
 int RND_OLD = 0; // предыдущий бит данных
 unsigned int POT = 20;     // полпериода в микросекундах
 int MFM = 0;   // текущий бит МЧМ

 unsigned int arr[100];  // массив случайных чисел
 int i=0;
 int j=0;

 unsigned long time;


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

// Set ADC mode
  // Регистр настройки мультиплексора
     ADMUX  = 0b01000011; // 0B0100011 - опорное Uпит (первые 01), 10 bit (3-й 0), A3 (последние 0011)
  // Регистр статуса и контроля
     ADCSRA = 0b11110011; // CLK/8 - ускоряем АЦП - в 8 раз ниже частоты процессора (32/8=4МГц)

// Set up pins as input
  pinMode(POT_PIN, INPUT);
  pinMode(FREE_PIN, INPUT);

// Set up pins as outputs
  pinMode(CLC_OUT, OUTPUT);
  pinMode(RANDOM_OUT, OUTPUT);
  pinMode(MFM_OUT, OUTPUT);

  digitalWrite(MFM_OUT, MFM);

  randomSeed(analogRead(FREE_PIN));

  // для пинов 9 и 10 (таймер1) - для 10 кГц вроде не обязательно
  // TCCR1A = 0b00000001;  // 8bit
  // TCCR1B = 0b00001001;  // x1 fast pwm - 62.5 кГц - для UNO и 125 кГц - для LGT8F328P

  time = micros();
 
}


  // Main loop - put your main code here, to run repeatedly:

  void loop() {  // до 30 кГц без задержек на random и ускорением чтения потенциометра

  for(i = 0; i < 100; i++){ // в массиве будет 100 элементов    //
  arr[i] = random(65536); // заполним массив случайными числами   // Чтобы потом в цикле не вносить задержек
  }
 
  while(true){   // бесконечный цикл для основной программы


     while(micros()-time < POT+10){
     }
    time = micros();

  digitalWrite(CLC_OUT, HIGH);  // переключаем СLC на HIGH - тактовая частота, желателен меандр

  RND = bitRead(arr[i], j);             // чтение битов массива

    digitalWrite(RANDOM_OUT, RND);          // вывод случайных данных на 10-й пин 

  if (RND < 1 && RND_OLD < 1) digitalWrite(MFM_OUT, !digitalRead(MFM_OUT)); // смена логического уровня МФМ в начале  
                                                                           // бита данных, если второй 0 подряд
                    
   j=j+1;           //
   if(j > 15) {     // последовательное чтение
   j = 0;           // битов из массива
   i=i+1;           // (быстрее, чем random (2))
   }                 //     
   if(i > 99) i = 0;

   // POT = analogRead(POT_PIN);        // чтение потенциометра
   // POT = map(POT, 20, 1000, 1, 512); // масштабируем до диапазона 1 ... 512
   // POT = constrain(POT, 1, 512);     // ограничиваем диапазон, чтобы исключить выбросы

       while(micros()-time < POT+10){
     }
    time = micros();

  digitalWrite(CLC_OUT, LOW); // переключаем СLC на LOW - тактовая частота, желателен меандр

  if (RND > 0) digitalWrite(MFM_OUT, !digitalRead(MFM_OUT));  // переход уровня МФМ при 1 данных по спаду CLC -
                   // в середине бита, т.е. CLC должен быть меандром
    RND_OLD = RND;
    
    //  POT = analogRead(POT_PIN);   //
    // POT = map(POT, 20, 1000, 1, 512);  // 25 мкс
    // POT = constrain(POT, 1, 512);    // поэтому пока отключил

   } // закрыли while

} // закрыли loop
может сам микрос в таких пределах дрыгается ... беру таймаут ... :hunger:
Изображение (Аль Котоне, кот ещё тот, Cattus Sapiens)
Усы и хвост - мои документы.
Кот - авторитет! Скажет "Мяу!" - не поспоришь. (скажи мне "мяу" и я скажу кто ты)
Реклама
OKF
Это не хвост, это антенна
Сообщения: 1407
Зарегистрирован: Вт июн 07, 2011 08:03:18

Сообщение OKF »

"Мне говорят обидные слова. Зачем тебе, мол Коля, голова?
Держать удар! Отвечу я вам всем. И, между прочим, головой я ем."
Навеяло.
Усы, хвосты, коты... ППЦ!
Реклама
Друг Кота
Аватара пользователя
Сообщения: 15598
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

Ну и что в тех матрицах сверхсложного то?
max7219-8x8-led-matrix-module-datasheet.pdf
(2.15 МБ) 116 скачиваний
аппаратный модуль SPI, ежли программный shiftOut() не устраивает ну на крайний случай простейший "ногодрыг" вполне обеспечивает загрузку...
А вот по ним урок от Гайвера:
https://alexgyver.ru/lessons/max7219/
:tea:
Вопрос кодогенератора и исходного ОЗУ буфера видеопамяти - то кому чего и как пожелается.
Регенерация изображения в пределах матрицы выполняется самим контроллером MAX7219.
Интервал загрузок для 4-8 байт не столь ж и велик (тем более, что вопросом регенерации заниматься не надо...
:roll:
Друг Кота
Аватара пользователя
Сообщения: 3168
Зарегистрирован: Чт мар 26, 2009 04:35:04
Откуда: Москва

Сообщение Полосатый »

Там строка бежит и ссылку на даташит давал в начале темы, только лапы так и не добрались разобраться, куда делись полматрицы от 8-и.

А тут я написал, что тот же скетч в китайском LGT бежит в два раза быстрее.
Изображение (Аль Котоне, кот ещё тот, Cattus Sapiens)
Усы и хвост - мои документы.
Кот - авторитет! Скажет "Мяу!" - не поспоришь. (скажи мне "мяу" и я скажу кто ты)
Реклама
Эиком - электронные компоненты и радиодетали
Друг Кота
Аватара пользователя
Сообщения: 3168
Зарегистрирован: Чт мар 26, 2009 04:35:04
Откуда: Москва

Сообщение Полосатый »

Ну да, сия хрень только с микросом почти на 25 кГц тоже дрыгается:
Спойлер

Код: Выделить всё

// Set up clock out pin
 #define CLC_OUT 8	// PORTB нулевой бит PBO

 unsigned long time;

 void setup() {

// Set up pins as outputs
  pinMode(CLC_OUT, OUTPUT);

  time = micros();

}

  void loop() {

   label:

   PORTB |= (1 << 0);

   while(micros()-time < 20){
   }

   time = micros();

   PORTB &= ~(1 << 0);

   while(micros()-time < 20){
   }

   time = micros();

   goto label;

} // закрыли loop
и чё делать пока непонятно. Ладно, разборки на потом оставлю, сейчас сделаю с тем, что есть.


Добавлено after 2 hours 1 minute 53 seconds:

"Люблпытно, что команда запроса времени micros() выполняется вдвое дольше, чем millis(), хотя, по логике следовало бы сделать это наоборот.

Кстати, кто не знает, micros() округляет показания до ближайшей "четверки", т.е. результат ее выполнения всегда делится нацело на 4. Это для тактовой частоты 16 МГц. Для 8 МГц - на 8, т.е. результатом можкт быть 8, 16, 32, 48, 64, 80, 96..., но никак не 28 или 60."

https://arduino.ru/forum/obshchii/vremy ... nd-arduino
Изображение (Аль Котоне, кот ещё тот, Cattus Sapiens)
Усы и хвост - мои документы.
Кот - авторитет! Скажет "Мяу!" - не поспоришь. (скажи мне "мяу" и я скажу кто ты)
Реклама
Друг Кота
Аватара пользователя
Сообщения: 15598
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

Пока что мне совершенно непонятно - а к чему такая заморочка со скоростями то нужна?
Только для обслуживания вывода в беглу строку это в случае с MAX7219 совсем не требуется...
Обработка чего то другого - так вроде для световых замигаек также не слишком нужно...
Да и на приемопередачу можно аппаратные средства МК задействовать...
:dont_know:
Реклама
Друг Кота
Аватара пользователя
Сообщения: 3168
Зарегистрирован: Чт мар 26, 2009 04:35:04
Откуда: Москва

Сообщение Полосатый »

От ардуины надо три вывода:
- тактовая частота CKC - желательно до 100 кГц, но можно и 20, желательно меандр, регулируемая внешним потенциометром,
- выход данных - типа "случайные", на самом деле до лампочки, просто чтобы явно не повторялись,
- дополнительный выход обработанных данных (два if'а, по одному на полупериод) - не проблема.

Вообще всё не проблема, но на 10-20 кГц уже явный джиттер - фронты CLC дрыгаются в пределах 5 мкс, что нехорошо.
Боролся я с этим на форуме arduino.ru и в результате получилось избавиться от джиттера.
Частота регулируется от 900 Гц (укоротил POT на четверть) до 20 кГц, стабильность нормальная.
Спойлер

Код: Выделить всё

// Получение последовательности псевдослучайных данных с регулируемой внешним потенциометром
// стабильной частотой (без джиттера) от 900 Гц до 20 кГц.

// Set up potentiometer pin
 #define POT_PIN A3

// Set up clock out pin
 #define CLC_OUT 9      // PORTB первый бит PB1

// Set up random out pin (выход данных)
 #define RANDOM_OUT 10  // PORTB второй бит PB2

 byte RND = 0;          // текущий бит данных

 int GEN=650;
 bool XOR=1;

 unsigned int POT = 10;
 // unsigned int m=30; // считал, что 20 мкс - это 160 тактов при частоте 8 МГц, но получилось 30 (?)
 // unsigned int POT_PLUS = POT + m; // добавка для выравнивания меандра

 unsigned int l=0;

 void setup() {

// Set up pins as input
  pinMode(POT_PIN, INPUT);

// Set up pins as outputs
  pinMode(CLC_OUT, OUTPUT);
  pinMode(RANDOM_OUT, OUTPUT);

 }

   void loop() {

   noInterrupts();

   label:				   // до метки заполнялся массив случайных данных, пришлось убрать

   XOR=bitRead(GEN, 14)^bitRead(GEN, 13);  //
   GEN=GEN<<1;				   // псевдослучайная последовательность на переменной GEN (аналог LFSR)
   bitWrite(GEN, 0, XOR);		   // более стабильная, чем random (фронты CLC не дрожат)

   RND=bitRead(GEN, 15);		   // "случайные" биты данных

   // RND = analogRead(A1)&0b1;            // 23-24 мкс, тоже без джиттера, но нужен шум на А1 

   PORTB |= (1 << 1);                      // фронт CLC

   // Вывод данных

   // digitalWrite(RANDOM_OUT, RND);       // вывод данных на 10-й пин - около 3 мкс, сильный джиттер

   if (RND < 1) PORTB &= ~(1 << 2); // установить 0 в бите 2 (10-й пин), всего за пару микросекунд
   else PORTB |= (1 << 2);          // установить 1 в бите 2 (10-й пин)


   POT = analogRead(POT_PIN);              // "чтение" потенциометра - 23-24 мкс

   POT=POT/4*3;				   // уменьшил, чтобы приблизить мин. частоту к 1 кГц

   for (l = 0; l < POT; l++) {             // задержка, определяемая потенциометром
   asm ("nop");
   }

   PORTB &= ~(1 << 1);                     // спад CLC

   for (l = 0; l < POT+30; l++) {          // добавка +30, чтобы приблизить CLC к меандру (не обязательно)
   asm ("nop");
   }

   goto label;

   interrupts();

} // закрыли loop
Меандровый CLC нужен только мне для третьего выхода, а тут только "случайные" данные с регулируемой частотой.
Для них меандр не нужен.
Если убрать добавку +30, то отрицательный полупериод станет коротким и максимальная частота будет больше 30 кГц, стабильность не пострадает.
Если после этого перенести POT = analogRead(POT_PIN); после спада CLC, то положительный полупериод CKC будет коротким, что более котфортабельно :)

Да, у меня китайский аналог LGT8F328P, на уне не пробовал.

*
*
*

Добавлено after 6 hours 17 minutes 53 seconds:

И всё было хорошо, пока мне не захотелось транслировать данные на другой выход ... ещё одна хрень выскочила из-за угла :kill:
Ну это как бы внутренние данные (которые "случайные"), но было бы неплохо вместо них какие-то внешние подключить.

На 10-й пин выводятся внутренние. С 10-го пина на 11-й подключил резистор 3,9 кОм - перевёл данные с 10-го выхода на 11-й вход.
А снова они выходят на 5-м пине (увидел, что там якобы больше нагрузочная способность, но не суть).
Расписал это так:
Спойлер

Код: Выделить всё

 
.
.
.
 PORTD |= (1 << 2);                  // фронт CLC

   if (RND < 1) PORTB &= ~(1 << 2); // установить 0 в бите PB2 (10-й пин) // вывод "случайных" данных
   else PORTB |= (1 << 2);               // установить 1 в бите PB2 (10-й пин) // пара микросекунд

    // int dat = (PINB & (1 << 3));      // не удлиняет период

    int dat = digitalRead(RANDOM_IN);  // плюс ещё пара микросекунд - чуть удлиняет период

   if (dat < 1) PORTD &= ~(1 << 5);   // установить 0 в бите PD5 (5-й пин) - трансляция c 3-го бита PB
   else PORTD |= (1 << 5);                // установить 1 в бите PD5 (5-й пин)

.
.
.
digitalRead чётко отрабатывает функционал, хотя и длиннее на пару микросекунд. Данные на входе и на выходе идентичные и синхронные.

А вот это безобразие - int dat = (PINB & (1 << 3)); вроде должно делать то же самое и делает, но с задержкой на период клока, независимо от частоты. Т.е. делает только в следующем такте. :shock: Это какого лошадиного хрена? /(с) моё/
Изображение (Аль Котоне, кот ещё тот, Cattus Sapiens)
Усы и хвост - мои документы.
Кот - авторитет! Скажет "Мяу!" - не поспоришь. (скажи мне "мяу" и я скажу кто ты)
Друг Кота
Аватара пользователя
Сообщения: 3168
Зарегистрирован: Чт мар 26, 2009 04:35:04
Откуда: Москва

Сообщение Полосатый »

Справились с хренью:
Спойлер

Код: Выделить всё


   PORTD |= (1 << 2);                  // фронт CLC

   if (RND < 1) PORTB &= ~(1 << 2);    // установить 0 в бите PB2 (10-й пин) // вывод "случайных" данных
   else PORTB |= (1 << 2);                   // установить 1 в бите PB2 (10-й пин) // пара микросекунд

     for (int k = 0; k < 5; k++) {     // задержка перед считыванием данных (надёжность записи)
     asm ("nop");                           // нужна для срабатывания int dat = (PINB & (1 << 3));
     }                                           // 

     int dat = (PINB & (1 << 3));

   // int dat = digitalRead(RANDOM_IN);    // работает нормально, не требует задержки, +2 мкс

   if (dat < 1) PORTD &= ~(1 << 5);         // установить 0 в бите PD5 (5-й пин) - трансляция c 3-го бита PB
   else PORTD |= (1 << 5);                      // установить 1 в бите PD5 (5-й пин)

"Обзор от ИИ: На Ардуино нет встроенного флага подтверждения записи в порт" :kill:

Ушёл спать ...
Изображение (Аль Котоне, кот ещё тот, Cattus Sapiens)
Усы и хвост - мои документы.
Кот - авторитет! Скажет "Мяу!" - не поспоришь. (скажи мне "мяу" и я скажу кто ты)
Друг Кота
Аватара пользователя
Сообщения: 15598
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

Неужели то каждому тактовому импульсу нужно запустить ГСЧ и выдать полученный результат на шину даных?
Т. Е. Сначала запуск ГСЧ, затем вывод значения на шину данных и затем генерация строба тактирования?
Или таки подобная скророспелость/садомазохизм штука излишняя?
Ведь ещё и корректура частоты по АЦП вроде есть - а то процесс не слишком шустрый (с учётом всех дополнительных процессов).
Может не стоит гнаться за немедленным выполнением всего вышеуказанного, а согласиться на возможность прохода одного/нескольких тактовых импульсов подряд с одинаковым значением частоты и выходных данных при заметно лучшей "прозрачности" по отношению к основной программе?
Зато и стабильность генерации тактов и чёткость вывода заметно повысится. Плюс вполне доступна и основная программа будет, а не только "дрыголап".
:roll:
Друг Кота
Аватара пользователя
Сообщения: 3168
Зарегистрирован: Чт мар 26, 2009 04:35:04
Откуда: Москва

Сообщение Полосатый »

Да там всё просто, только от random() фронты дрыгаются и если сначала заполнять случайный массив, а потом читать в цикле - тоже дрыгаются.
Не дрыгаются, только если читать шум с висящего аналогового входа, но должен быть шум (кто-то должен стоять рядом и громко ругаться матом :) ) Уже хотел лепить сверхрегенератор на одном транзисторе (хорошо шумит), а потом такую штуку придумал.
Там всего две строчки - сдвиг битов (типа "регистр сдвига") и запись в нулевой бит (типа "обратная связь"). Никаких дополнительных ресурсов и проблем.
Другое ограничение - максимальная частота, пока только до 20 кГц, потому что дольше всего читается с потенциометра.
Если можно увеличить частоту АЦП, то это интересно, но пока и 20-и хватит.
Изображение (Аль Котоне, кот ещё тот, Cattus Sapiens)
Усы и хвост - мои документы.
Кот - авторитет! Скажет "Мяу!" - не поспоришь. (скажи мне "мяу" и я скажу кто ты)
Друг Кота
Аватара пользователя
Сообщения: 15598
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

Если выполнять на Т1 (с учетом его аппаратной начинки и прерываний) никаких дрожаний фронтов для тактового сигнала не будет.
Единственно - выходной тактовый сигнал на фиксированных аппаратных выводах - перебросить на другие будет невозможно. Плюс настройки таймера придется "вне рамок референса" делать - по даташитам и с учетом соответствующих заголовочных файлов (они в IDE имеются - только поискать надо).
Связь с результатом АЦП и ГСЧ по флагам запросов по готовности данных.
:roll:
Друг Кота
Аватара пользователя
Сообщения: 3168
Зарегистрирован: Чт мар 26, 2009 04:35:04
Откуда: Москва

Сообщение Полосатый »

Ну это только CLC, мне ещё такой скетч предложили:
Спойлер

Код: Выделить всё

const byte pinCoarse = A0;
const int32_t CoarseStep = 200ul;
const byte pinFine = A1;
const byte MaxCount = 16;
const uint32_t FreqMax = 140000ul;


void inline setWave(uint32_t fr) {
  //собствеенно включение генератора. комментировать нечего
  if (fr > 1000) {
    uint16_t ht = 8000000L / fr; //тиков на полпериода
    TCCR1A = 0b10001110;//COM1A1:COM1A0:COM1B1:COM1B0:X:X:WGM11:WGM10
    TCCR1B = 0b00011001;//X:X:X:WGM13:WGM12:CS12:CS11:CS10
    // ИТОГО канал только А, режим 14 (FastPWM TOP=ICR1), нон инвертинг, частота 16МГц /64 =250КГц
    ICR1 = (uint16_t) (ht << 1);
    OCR1A = (uint16_t)(ht);
  }
  else {
    uint16_t ht = 1000000L / fr;
    TCCR1A = 0b10001110;//COM1A1:COM1A0:COM1B1:COM1B0:X:X:WGM11:WGM10
    TCCR1B = 0b00011010;//X:X:X:WGM13:WGM12:CS12:CS11:CS10
    // ИТОГО канал только А, режим 14 (FastPWM TOP=ICR1), нон инвертинг, частота 16МГц /8 =2 МГц
    ICR1 = (uint16_t) (ht << 1);
    OCR1A = (uint16_t)(ht);
  }

}

void setup() {
  pinMode(9, OUTPUT);
  Serial.begin(115200);
}

void loop() {
  static byte count = 0;
  static uint16_t valueCoarse = 0;
  static uint16_t valueFine = 0;

  int32_t fr = 100;

  valueCoarse += analogRead(pinCoarse); //Усредняем ЦАП за MaxCount измерений
  valueFine   += analogRead(pinFine  ); //Усредняем ЦАП за MaxCount измерений
  count++;

  if (count == MaxCount) {
    //вычисляем частоту грубый режим по 200 Гц, начиная со 100, точный - по одному
    fr = CoarseStep * map(valueCoarse / MaxCount, 0, 1023, 1, FreqMax / CoarseStep) +
         map(valueFine / MaxCount, 0, 1023, -CoarseStep / 2, CoarseStep / 2);

    setWave(fr);
    
    //просто вывод значений, желающие переделывают на экранчик ;))
    Serial.print(" Freq=");
    Serial.print(fr);
    Serial.println();

    valueCoarse = 0;
    valueFine = 0;
    count = 0;
  }
  delay(10);
}
Изображение (Аль Котоне, кот ещё тот, Cattus Sapiens)
Усы и хвост - мои документы.
Кот - авторитет! Скажет "Мяу!" - не поспоришь. (скажи мне "мяу" и я скажу кто ты)
Друг Кота
Аватара пользователя
Сообщения: 15598
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

Так с CLC напрямую завязан вывод заранее подготовленных данных на другой вывод. Сам тактовый сигнал формируется аппаратно на Т1.
Одно из аппаратных прерываний выполняет выдачу данных в промежутках между активным статусом тактового сигнала. Быстрее уж никак не получится.
8)
Друг Кота
Аватара пользователя
Сообщения: 3168
Зарегистрирован: Чт мар 26, 2009 04:35:04
Откуда: Москва

Сообщение Полосатый »

На прерывания я потом прервусь :) сейчас до 20 кГц работает и ладно. Это только небольшая часть макета, надо всё доделать, а потом буду разбираться.
Изображение (Аль Котоне, кот ещё тот, Cattus Sapiens)
Усы и хвост - мои документы.
Кот - авторитет! Скажет "Мяу!" - не поспоришь. (скажи мне "мяу" и я скажу кто ты)
Друг Кота
Аватара пользователя
Сообщения: 15598
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

Лаподрыг то работает, но уж слишком ЖАБА давит заставлять МК только одной задачей заниматься (ежли то не тинька 13/2313)...
А тут практически "без дела" аппаратный генератор с весьма приличными возможностями прохлаждается.
Правда там также некоторые ограничения по максимальной частоте и шагу смены частоты имеются, но все же гораздо удачнее результат может получиться.
8)
Друг Кота
Аватара пользователя
Сообщения: 3168
Зарегистрирован: Чт мар 26, 2009 04:35:04
Откуда: Москва

Сообщение Полосатый »

Это глобальная философия :) для более масштабных задач. И, разумеется, всё это надо знать и уметь использовать. Но если надо на практике просто заменить вот этим:

Изображение

https://aliexpress.ru/item/1005010313697351.html

5-7 корпусов логики с обвязкой, то тут жаба скорее сама повесится :)
Изображение (Аль Котоне, кот ещё тот, Cattus Sapiens)
Усы и хвост - мои документы.
Кот - авторитет! Скажет "Мяу!" - не поспоришь. (скажи мне "мяу" и я скажу кто ты)
Друг Кота
Аватара пользователя
Сообщения: 15598
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

Меня ЖАБА удавит использовать жирный МК для задач "программируемого периферийного контроллера", если задачу можно решить "мелколапкой"
8)
(Однако на сегодня с учетом поставок, ценовой политики и наличия комплектующих вероятно такой подход будет абсолютно не актуален :twisted: )
Тем более, что у ардуино на сегодня в качестве "платформ" представлены практически все "ходовые" АВРки..
Да и ассемблер под остатки запасов мелкопиков и АВРок пока еще в силе (плюс 51я в вариантах от атмела да других).
Ардуинка упрощает старт создания проекта под СИ, но не отменяет процесса продумывания программ для более удачного решения.
Это всего лишь один из возможных инструментов разработки для МК АВР.
:beer:
Пы.сы...
Ежли лень не удавит выложу чуток позже свое видение решения...
:sleep:
Друг Кота
Аватара пользователя
Сообщения: 3168
Зарегистрирован: Чт мар 26, 2009 04:35:04
Откуда: Москва

Сообщение Полосатый »

Вставил вот это - фронты снова дрыгаются ... в пределах около 7 мкс при длительности полупериода 25 мкс:
Спойлер

Код: Выделить всё

 

.
.
.

if (DAT < 1 && DAT_OLD < 1) {
      PORTD = PORTD^0b01000000;         // в начале бита данных, если второй 0 подряд

      MFM = PIND & (1 << 6);

      if (MFM < 1) PORTB = PORTB & 0b11111100; // 0 - в PB0 и PB1 (операция И меняет 2 младших бита)
      else {
       if (SIDE < 1) PORTB |= (1 << 0);                // 1 в PB0 (на левой стороне)
       if (SIDE > 0) PORTB |= (1 << 1);                // 1 в PB1 (на правой стороне)
       SIDE = 1.3 - SIDE;	   		// округление до целого числа (меняем сторону)
      } 
   }

.
.
.

   if (DAT > 0) {
    PORTD = PORTD^0b01000000;           // в середине бита, т.е. CLC должен быть меандром

     MFM = PIND & (1 << 6);
    
      if (MFM < 1) PORTB = PORTB & 0b11111100; // 0 - в PB0 и PB1 (операция И меняет 2 младших бита)
      else {
       if (SIDE < 1) PORTB |= (1 << 0);                // 1 в PB0 (на левой стороне)
       if (SIDE > 0) PORTB |= (1 << 1);                // 1 в PB1 (на правой стороне)
       SIDE = 1.3 - SIDE;	   		// округление до целого числа (меняем сторону)
      } 
   }
.
.
.
перед этим тоже были аналогичные операции и так не дрыгалось.

Т.е. это не из-за способа получения случайных данных, как я раньше думал. Тут какие-то другие накладки.

А функционально всё нормально работает.

Для макета и так сойдёт, напрягаться не надо. Потом можно будет спокойно разобраться. Только ещё хочу попробовать залить сие в стандартную дуньку, а не китайскую.
Изображение (Аль Котоне, кот ещё тот, Cattus Sapiens)
Усы и хвост - мои документы.
Кот - авторитет! Скажет "Мяу!" - не поспоришь. (скажи мне "мяу" и я скажу кто ты)
Друг Кота
Аватара пользователя
Сообщения: 3168
Зарегистрирован: Чт мар 26, 2009 04:35:04
Откуда: Москва

Сообщение Полосатый »

И ещё 168-я атмега нано не шьётся ... если думать, что она 328-я ... совсем буржуи распоясались :)

Частота клока, понятно, меньше (в 3 раза) и он уже не меандр - 120 мкс высокий и 75 низкий, все фронты так же дрыгаются.
А сначала не замкнул 10-й и 11-й выводы и получил такую фигню:

Изображение

Уже просто интересно, откуда она взялась :)
Изображение (Аль Котоне, кот ещё тот, Cattus Sapiens)
Усы и хвост - мои документы.
Кот - авторитет! Скажет "Мяу!" - не поспоришь. (скажи мне "мяу" и я скажу кто ты)
Друг Кота
Аватара пользователя
Сообщения: 15598
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

Для каждой АВРки в адуринке своя "платформа" или опции выбора из нескольких подобных в пределах одной платформы.
Настройки и фузов и бутлоадера могут заметно отличаться. Да и бутлоадеры могут иметь варианты в пределах одной платформы.
Работать надо таким же набором опций, с каким выполнено ранее
"инструменты ->записать загрузчик" (естественно эту операцию делаем через программатор*).
8)
Относительно "трещалки-пищалки" Вашей...
Ниже вариант тестового "писка с треском" на ардуино - нано :
Спойлер

Код: Выделить всё

#include <avr/interrupt.h> // обслуживание прерываний

#define outdat 8 // вместо D8 ставим соотвествующий (любой из возможных) номер вывода адуринки
#define outclock 10 // OC1A = D9/PB1, OC1B = D10/PB2 возможные варианты вывода
                 // сигнала Clc (OC1A при ICR=периоду, OC1B при OC1A=периоду)
volatile unsigned int tmpClc; // РВХ данных периода
volatile unsigned int tmpPwm; // РВХ данных активной части Clc (ШИМ)
// volatile byte tmpOut; // буфер данных для вывода на линию данных
volatile byte FqClc; // флаг запроса смены параметров тактового сигнала
            // активный уровень = 1
volatile byte FqRnd; // флаг запроса обработчика для очередного вывода данных
            // в tmpOut (на линию outdat в следующих циклах Clc)

volatile byte cnt = 0; // for test

#define hasm0 1
#define hasm2 0b01000000

void rndmod();

union {
 uint64_t bigdat;
 struct {
  byte vdat0;
  byte vdat1;
  byte vdat2;
  byte vdat3;
  byte vdat4;
  byte vdat5;
  byte vdat6;
  byte vdat7; }lowdat;
} recodum;

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

void setup() {
	// put your setup code here, to run once:
 pinMode(outdat, OUTPUT); digitalWrite(outdat, LOW);
 pinMode(outclock, OUTPUT); digitalWrite(outclock, LOW);
 // настройки таймера Т1 для работы
 // период задан по OCR1A, ШИМ 50% определен в OCR1B
 // для вывода Clc задан OC1B = D10/PB2
 // для outdat может выбираться любой из свободных  цифровых
 cli();
 TCCR1A = (1<<COM1B0) | (1<<COM1B1) | (1<<WGM10);
 TCCR1B = 1<<WGM13; // только режим! таймер остановлен
          // 1<<CS10 = пуск таймера с  clkI/O/1 (No prescaling)
          // 1<<CS11 = пуск таймера с clkI/O/8 (From prescaler)
 TIMSK1 = (1<<OCIE1A) | (1<<TOIE1);
 // загрузка начального нижнего значения (20000 единиц clkI/O/8 на 1 период) частоты в РВХ
 tmpClc = 20000/2; tmpPwm = tmpClc>>1; FqClc = 1;
 rndmod(); // загрузка данных в recodum.lowdat.vdat0 (tmpOut)
 sei();
 TCCR1B = TCCR1B | 1<<CS11; // пуск таймера Т1 0.000000062*8=0.0000005
}

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

void loop() {
	// put your main code here, to run repeatedly:

	if(FqRnd){
    rndmod(); cnt++;
    if(cnt == 10){ 
       tmpClc = tmpClc - cnt; cnt = 0;
       if(tmpClc <= 150){ tmpClc = 20000/2; }
       tmpPwm = tmpClc>>1;
       FqClc = 1;
      }
    FqRnd = 0;
	}
}

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

ISR(TIMER1_COMPA_vect){
	if(FqClc){OCR1A = tmpClc; OCR1B = tmpPwm; FqClc = 0;}
}

ISR(TIMER1_OVF_vect){
	digitalWrite(outdat, bitRead(recodum.lowdat.vdat0, 0));
	if(!FqRnd){	FqRnd = 1;}
}

void rndmod()
{
 byte tmpa, tmpb;
 if(recodum.bigdat == 0){recodum.bigdat = UINT64_MAX;}
 tmpa = recodum.lowdat.vdat0 & hasm0;
 if(tmpa){tmpa = 0xFF;}
 tmpb = recodum.lowdat.vdat2 & hasm2;
 if(tmpb){tmpb = 0xFF;}
 tmpa = tmpa ^ tmpb;
 recodum.bigdat = recodum.bigdat >> 1;
 if(tmpa){bitWrite(recodum.lowdat.vdat7, 7, 1);}
  else {bitWrite(recodum.lowdat.vdat7, 7, 0);}
}

//----------**********************----------

//-------------конец файла/end of file---------------------
Тактовый импульс на D10, выход ГСЧ на D8.
Забавно трещит. Осциллографом не смотрел - то уже "для гурманов".
:))
Последний раз редактировалось BOB51 Вт янв 06, 2026 11:19:18, всего редактировалось 2 раза.
Ответить

Вернуться в «Разные вопросы по МК»