* Не, того, для чего это надо, никто никогда не видел
Добавлено 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); // ограничиваем диапазон, чтобы исключить выбросы
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
может сам микрос в таких пределах дрыгается ... беру таймаут ...
_________________ (Аль Котоне,кот ещё тот,Cattus Sapiens) Усы и хвост - мои документы. Кот - авторитет! Скажет "Мяу!" - не поспоришь. (скажи мне "мяу" и я скажу кто ты)
"Мне говорят обидные слова. Зачем тебе, мол Коля, голова? Держать удар! Отвечу я вам всем. И, между прочим, головой я ем." Навеяло. Усы, хвосты, коты... ППЦ!
аппаратный модуль SPI, ежли программный shiftOut() не устраивает ну на крайний случай простейший "ногодрыг" вполне обеспечивает загрузку... А вот по ним урок от Гайвера: https://alexgyver.ru/lessons/max7219/ Вопрос кодогенератора и исходного ОЗУ буфера видеопамяти - то кому чего и как пожелается. Регенерация изображения в пределах матрицы выполняется самим контроллером MAX7219. Интервал загрузок для 4-8 байт не столь ж и велик (тем более, что вопросом регенерации заниматься не надо...
Карма: 22
Рейтинг сообщений: 94
Зарегистрирован: Чт мар 26, 2009 04:35:04 Сообщений: 3124 Откуда: Москва
Рейтинг сообщения:0
Там строка бежит и ссылку на даташит давал в начале темы, только лапы так и не добрались разобраться, куда делись полматрицы от 8-и.
А тут я написал, что тот же скетч в китайском LGT бежит в два раза быстрее.
_________________ (Аль Котоне,кот ещё тот,Cattus Sapiens) Усы и хвост - мои документы. Кот - авторитет! Скажет "Мяу!" - не поспоришь. (скажи мне "мяу" и я скажу кто ты)
Карма: 22
Рейтинг сообщений: 94
Зарегистрирован: Чт мар 26, 2009 04:35:04 Сообщений: 3124 Откуда: Москва
Рейтинг сообщения:0
Ну да, сия хрень только с микросом почти на 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."
_________________ (Аль Котоне,кот ещё тот,Cattus Sapiens) Усы и хвост - мои документы. Кот - авторитет! Скажет "Мяу!" - не поспоришь. (скажи мне "мяу" и я скажу кто ты)
Пока что мне совершенно непонятно - а к чему такая заморочка со скоростями то нужна? Только для обслуживания вывода в беглу строку это в случае с MAX7219 совсем не требуется... Обработка чего то другого - так вроде для световых замигаек также не слишком нужно... Да и на приемопередачу можно аппаратные средства МК задействовать...
Карма: 22
Рейтинг сообщений: 94
Зарегистрирован: Чт мар 26, 2009 04:35:04 Сообщений: 3124 Откуда: Москва
Рейтинг сообщения:0
От ардуины надо три вывода: - тактовая частота 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:
И всё было хорошо, пока мне не захотелось транслировать данные на другой выход ... ещё одна хрень выскочила из-за угла Ну это как бы внутренние данные (которые "случайные"), но было бы неплохо вместо них какие-то внешние подключить.
На 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)); вроде должно делать то же самое и делает, но с задержкой на период клока, независимо от частоты. Т.е. делает только в следующем такте. Это какого лошадиного хрена? /(с) моё/
_________________ (Аль Котоне,кот ещё тот,Cattus Sapiens) Усы и хвост - мои документы. Кот - авторитет! Скажет "Мяу!" - не поспоришь. (скажи мне "мяу" и я скажу кто ты)
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 10
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения