Формирование случайной импульсной последовательности

Поклонники продукции Microchip Technology Inc тусуются тут.
SpeedFighter
Открыл глаза
Сообщения: 63
Зарегистрирован: Вс май 28, 2017 19:07:32

Формирование случайной импульсной последовательности

Сообщение SpeedFighter »

Здарова, ребята.

Тут делаю небольшое устройство (пишу на сишке) на базе пичка (PIC18F1230). Его задачи:
Спойлер1. По нажатию кнопки пуск - работать, по нажатию кнопки стоп - не работать.
2. Формировать импульсы постоянной длительности со случайными задержками (импульс - 30 мкс, задержка от 100 мкс до 400 мс).
3. Работает - горит зеленый светодиот, не работает - красный.

В ходе работы возникли следующие вопросы:

1. Как выбрать правильно МК под мою задачу?
СпойлерКак минимум, я могу предположить, что МК должен нормально работать с импульсами, имеющими длительность 30 мкс. Но сейчас, как мне кажется, любой, даже самый дешевый МК может это.
Вот я выбрал PIC18F1230, но что-то мне кажется, что это не совсем рационально, т.к. я использую функции в работе только те, которые есть в каждом пичке.
2. Где можно в даташите посмотреть требования к окружающим условиям и к источнику питания (я в английском слаб, хотел бы просто ключевые слова получить, если можно)?

3. Как сделать задержку на определенное время?
СпойлерЧитал, что можно сделать задержку через циклы, но я не совсем понимаю, как приблизительно хотя бы прикинуть, сколько времени занимает выполнение одной пустой итерации цикла.
Где-то читал, что цикл for выполняется за 3 такта, а частота моего внутреннего генератора вроде бы 4 МГц (Oscillator frequency), так вот, получается, что 1 итерация цикла задерживает работу на:
t = 3/F = 3/(4*10^6) = 0,75 мкс. Я взял для уверенности 1 мкс. В итоге я потерпел фиаско, скажем, раз в 15 примерно. Прикладываю картинку выходного сигнала. Сигнал должен был длиться 15 мкс...
Изображение
4. Как узнать, что кнопка нажата?

5. Является ли признаком быдло-кода использование оператора goto программировании МК на C?

6. Как правильно настроить биты конфигурации в МК (использую MPLAB X 4.05)? А то я фигню какую-то понастраивал.

7. Какой компилятор оптимальнее всего использовать для решения таких задач? И какие у него должны быть настройки?

Прикладываю все важные файлы (проект в протосе, мплабе, изображение пичка)

Картинка пичка:
СпойлерИзображение
Код:
Спойлер

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

/*#include <pic.h>  // Библитека пичков
#include <stdio.h>*/
#include <stdlib.h>
//#include <pic18f1230.h> // Библиотека конкретного пичка
#include <xc.h>

// PIC18F1230 Configuration Bit Settings

// 'C' source line config statements

// CONFIG1H
#pragma config OSC = RCIO       // Oscillator (External RC oscillator, port function on RA6)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)
#pragma config IESO = OFF       // Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)

// CONFIG2L
#pragma config PWRT = OFF       // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOR = BOHW       // Brown-out Reset Enable bits (Brown-out Reset enabled in hardware only (SBOREN is disabled))
#pragma config BORV = 3         // Brown-out Reset Voltage bits (Minimum setting)

// CONFIG2H
#pragma config WDT = ON         // Watchdog Timer Enable bit (WDT enabled)
#pragma config WDTPS = 32768    // Watchdog Timer Postscale Select bits (1:32768)

// CONFIG3L
#pragma config PWMPIN = OFF     // PWM Output Pins Reset State Control bit (PWM outputs disabled upon Reset)
#pragma config LPOL = HIGH      // Low-Side Transistors Polarity bit (Even PWM Output Polarity Control bit) (PWM0, PWM2 and PWM4 are active-high (default))
#pragma config HPOL = HIGH      // High Side Transistors Polarity bit (Odd PWM Output Polarity Control bit) (PWM1, PWM3 and PWM5 are active-high (default))

// CONFIG3H
#pragma config FLTAMX = RA5     // FLTA Mux bit (FLTA input is muxed onto RA5)
#pragma config T1OSCMX = LOW    // T1OSO/T1CKI MUX bit (T1OSO/T1CKI pin resides on RB2)
#pragma config MCLRE = ON       // Master Clear Enable bit (MCLR pin enabled, RA5 input pin disabled)

// CONFIG4L
#pragma config STVREN = ON      // Stack Overflow/Underflow Reset Enable bit (Reset on stack overflow/underflow enabled)
#pragma config BBSIZ = BB256    // Boot Block Size Select bits (256 Words (512 Bytes) Boot Block size)
#pragma config XINST = OFF      // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled)

// CONFIG5L
#pragma config CP0 = OFF        // Code Protection bit Block 0 (000400-0007FF) (Block 0 is not code-protected)
#pragma config CP1 = OFF        // Code Protection bit Block 1 (000800-000FFF) (Block 1 is not code-protected)

// CONFIG5H
#pragma config CPB = OFF        // Code Protection bit (Boot Block Memory Area) (Boot Block is not code-protected)
#pragma config CPD = OFF        // Code Protection bit (Data EEPROM) (Data EEPROM is not code-protected)

// CONFIG6L
#pragma config WRT0 = OFF       // Write Protection bit Block 0 (000400-0007FF) (Block 0 is not write-protected)
#pragma config WRT1 = OFF       // Write Protection bit Block 1 (000800-000FFF) (Block 1 is not write-protected)

// CONFIG6H
#pragma config WRTC = OFF       // Write Protection bit (Configuration Registers) (Configuration registers are not write-protected)
#pragma config WRTB = OFF       // Write Protection bit (Boot Block Memory Area) (Boot Block is not write-protected)
#pragma config WRTD = OFF       // Write Protection bit (Data EEPROM) (Data EEPROM is not write-protected)

// CONFIG7L
#pragma config EBTR0 = OFF      // Table Read Protection bit Block 0 (000400-0007FF) (Block 0 is not protected from table reads executed in other blocks)
#pragma config EBTR1 = OFF      // Table Read Protection bit Block 1 (000800-000FFF) (Block 1 is not protected from table reads executed in other blocks)

// CONFIG7H
#pragma config EBTRB = OFF      // Table Read Protection bit (Boot Block Memory Area) (Boot Block is not protected from table reads executed in other blocks)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#define SIGNAL 30 // Длительность сигнала в мкс
#define DELMIN 100 // Минимальное время задержки в мкс
#define DELMAX 400000 // Максимальное время задержки в мкс


void delay(int type); // Функция задержки 
void Prepare(void); // Функция подготовки МК

int main()
{
    Prepare(); // Запуск подготовки МК
    while(1) // Бесконечный цикл, основная задача МК
    {
        delay(0); // Задержка межуд сигналами
        TRISB = 0b00010000; // Подаем на выход лог. единицу
        delay(1); // Длительность сигнала
        TRISB = 0b00000000; // Выставляем лог. ноль        
    }
    return 0;    
}

void delay(int type) // Функция задержки
{
    int N; // Локальная переменная для промежуточных присвоений
    if(type == 0)
    {
        N = DELMIN + rand() % DELMAX; // Формируем случайную задержку
    }
    else
    {
        N = SIGNAL; // Определяем длительность сигнала
    }
    
    for(int i = 0; i <= N; i++) {} // Держим заданный лог. уровень
}

// Подготовка МК
void Prepare(void)
{
    TRISA = 0b00000000; // Направление работы ножек порта А
    TRISB = 0b00010000; // Направление работы ножек порта В
    CMCON = 0x07; // Отключение компараторов
    PORTA = 0; // Очищаем порт А
    PORTB = 0; // Очищаем порт Б
    RBPU = 0;  // Подтягивающие R (0-вкл, 1-выкл)
}
Вложения
Proteus.rar
Проект в PROTEUS
(44.9 КБ) 299 скачиваний
Programm.X.rar
Проект в MPLAB
(69.14 КБ) 297 скачиваний
Реклама
Аватара пользователя
КРАМ
Друг Кота
Сообщения: 25261
Зарегистрирован: Чт янв 10, 2008 22:01:02
Откуда: Московская область, Фрязино

Re: Формирование случайной импульсной последовательности

Сообщение КРАМ »

Задача действительно простая и может быть реализована практически на любом контроллере, желательно с модулем CCP (Capture-Compare-PWM). Этот модуль позволит аппаратно получать импульсы в 30 мкс. Но можно и без него, просто дергая ногой с программной задержкой в 30 мкс.
Единственное, что Вы не сможете получить - True Random. Любая случайная функция будет ПСЕВДОслучайной, то есть иметь какой то интервал повторения.
Узнать нажатие кнопки можно опросом порта и маскированием бита на котором висит кнопка. Опрос следует проводить с интервалом большим, чем время дребезга кнопки. Это позволит защититься от этого самого дребезга. Обычно хватает интервала 10...30 миллисекунд.
Совершенно непонятно зачем Вам goto для такой задачи. И таки да, на Си этот оператор применять не следует без каких то совершенно безвыходных случаев (я таких не встречал).
Температурный диапазон и требования к питанию указаны в разделе электрических параметров (в конце даташита). Факт того, что Вы их не нашли, означает, что Вы их и НЕ ПЫТАЛИСЬ искать. Достаточно посмотреть оглавление. Незнание английского тоже не аргумент, нынче гуглопереводчик доступен так же, как и сам гугол.
Выбор Вами контроллера совершенно не обоснован. Ну разве только он единственный есть в наличии. Это очень старый МК и весьма дорогой.
Реклама
vladlen-from-vrtp
Первый раз сказал Мяу!
Сообщения: 28
Зарегистрирован: Чт май 01, 2014 07:28:15

Re: Формирование случайной импульсной последовательности

Сообщение vladlen-from-vrtp »

[uquote="КРАМ",url="/forum/viewtopic.php?p=3248750#p3248750"]...
Единственное, что Вы не сможете получить - True Random. ...[/uquote]

Не так давно решено и описано по ссылке в сообщении #593469


.
Аватара пользователя
КРАМ
Друг Кота
Сообщения: 25261
Зарегистрирован: Чт янв 10, 2008 22:01:02
Откуда: Московская область, Фрязино

Re: Формирование случайной импульсной последовательности

Сообщение КРАМ »

Это не решение. Это хуже, чем псевдослучайная функция. Патамушта случайная функция подразумевает на выходе белый шум в спектральном интервале квантования, а с WDT получится корреляция с питанием и температурой. А это совсем не случайные величины. То есть матожидание будет следовать за этими величинами.
Если человек решает задачи криптографии, то простым будет генератор шума на стабилитроне и ОУ. Сигнал подаем на АЦП и имеем тот самый True Random. А если это типа" елочной гирлянды", то даже тупое повторение таблицы из 256 значений даст более чем отличный результат.
Реклама
Эиком - электронные компоненты и радиодетали
SpeedFighter
Открыл глаза
Сообщения: 63
Зарегистрирован: Вс май 28, 2017 19:07:32

Re: Формирование случайной импульсной последовательности

Сообщение SpeedFighter »

[uquote="КРАМ",url="/forum/viewtopic.php?p=3248750#p3248750"]Задача действительно простая и может быть реализована практически на любом контроллере, желательно с модулем CCP (Capture-Compare-PWM). Этот модуль позволит аппаратно получать импульсы в 30 мкс. Но можно и без него, просто дергая ногой с программной задержкой в 30 мкс.
Единственное, что Вы не сможете получить - True Random. Любая случайная функция будет ПСЕВДОслучайной, то есть иметь какой то интервал повторения.
Узнать нажатие кнопки можно опросом порта и маскированием бита на котором висит кнопка. Опрос следует проводить с интервалом большим, чем время дребезга кнопки. Это позволит защититься от этого самого дребезга. Обычно хватает интервала 10...30 миллисекунд.
Совершенно непонятно зачем Вам goto для такой задачи. И таки да, на Си этот оператор применять не следует без каких то совершенно безвыходных случаев (я таких не встречал).
Температурный диапазон и требования к питанию указаны в разделе электрических параметров (в конце даташита). Факт того, что Вы их не нашли, означает, что Вы их и НЕ ПЫТАЛИСЬ искать. Достаточно посмотреть оглавление. Незнание английского тоже не аргумент, нынче гуглопереводчик доступен так же, как и сам гугол.
Выбор Вами контроллера совершенно не обоснован. Ну разве только он единственный есть в наличии. Это очень старый МК и весьма дорогой.[/uquote]

1. Про рандом я знаю, что получаю псевдослучайное число.
2. Спасибо, некоторые нужные строчки в даташите нашел.
3. А какой тогда из современных и недорогих пичков (именно пичок хочу) можно взять?
Реклама
Аватара пользователя
КРАМ
Друг Кота
Сообщения: 25261
Зарегистрирован: Чт янв 10, 2008 22:01:02
Откуда: Московская область, Фрязино

Re: Формирование случайной импульсной последовательности

Сообщение КРАМ »

3. Полагаю, что PIC12F1822 Вас устроит. Если кварцевая точность 30 мкс не нужна (1...2% разброса устроит), то можно еще понизить цену и взять PIC12F1501, а может и PIC10F322. Последний вообще в корпусе SOT23-6, что сделает устройство суперкомпактным.
Реклама
SpeedFighter
Открыл глаза
Сообщения: 63
Зарегистрирован: Вс май 28, 2017 19:07:32

Re: Формирование случайной импульсной последовательности

Сообщение SpeedFighter »

Спасибо, 1-2% вполне устроят.

Пока попробую на старом мк доделать полностью, а потом уже попробую на один из этих пичков перенести.

Таки да, компактный пичок:
СпойлерИзображение
ОПЪ:

Как заставить работать такую строчку:

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

__delay_us(K);
где:

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

int K = DELMIN + rand() % DELMAX;
Компилятор на это ругается:

main.c:5388: error: (800) undefined symbol "__delay$0"
main.c:5393: error: (800) undefined symbol "__delay"

Но такая строчка работает:

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

__delay_us(SIGNAL); // Длительность сигнала
SIGNAL - через #define объявлен.

Так же, задержка работает и при большИх значениях (400 000), хотя на форуме англоязычном говорили, что может из-за этого такая ошибка.
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: Формирование случайной импульсной последовательности

Сообщение Аlex »

__delay_us и __delay_ms - это не функции, а встроенные в компилятор макросы. По этому, переменную в них передавать нельзя.
Если хотите с переменной, то пишите свою функцию. Но учтите, что частота процессора при этом должна быть достаточной, чтобы отработать 1 цикл в функции задержки за 1 us.
SpeedFighter
Открыл глаза
Сообщения: 63
Зарегистрирован: Вс май 28, 2017 19:07:32

Re: Формирование случайной импульсной последовательности

Сообщение SpeedFighter »

[uquote="Аlex",url="/forum/viewtopic.php?p=3248984#p3248984"]__delay_us и __delay_ms - это не функции, а встроенные в компилятор макросы. По этому, переменную в них передавать нельзя.
Если хотите с переменной, то пишите свою функцию. Но учтите, что частота процессора при этом должна быть достаточной, чтобы отработать 1 цикл в функции задержки за 1 us.[/uquote]
Вот проблема как раз в том, что я сам писал задержку через пустой цикл for, но увы, потерпел фиаско, слишком неточно.
Аватара пользователя
КРАМ
Друг Кота
Сообщения: 25261
Зарегистрирован: Чт янв 10, 2008 22:01:02
Откуда: Московская область, Фрязино

Re: Формирование случайной импульсной последовательности

Сообщение КРАМ »

точные задержки делают на таймере и прерываниях.
SpeedFighter
Открыл глаза
Сообщения: 63
Зарегистрирован: Вс май 28, 2017 19:07:32

Re: Формирование случайной импульсной последовательности

Сообщение SpeedFighter »

Я столкнулся ещё с одной неопределенностью. Как правильно назначить направление портов?

Я сделал так и все работает*:

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

    TRISA = 0b11111111; // Направление работы ножек порта А (вход)
    TRISB = 0b00000000; // Направление работы ножек порта В (выход)
Под работает я понимаю, что на выходе получаю то, что хочу.

Но в некоторых гайдах я встречал, что для входа наоборот, нужно ставить все нули, а для выхода - единицы.
Аватара пользователя
КРАМ
Друг Кота
Сообщения: 25261
Зарегистрирован: Чт янв 10, 2008 22:01:02
Откуда: Московская область, Фрязино

Re: Формирование случайной импульсной последовательности

Сообщение КРАМ »

TRISA/TRISB - означает Tri-state - третье состояние, то есть отключенное состояние ВЫХОДНОГО буфера.
Таким образом, 1 в регистре TRIS означает чистый вход, а 0 - выход и вход одновременно (можно прочесть значение выхода).
Не забывайте, что помимо ТRIS ногой управляет аналоговая функция этой ноги, если она присутствует. Включение аналоговой функции отключает цифровой вход.
Аватара пользователя
7seg
Потрогал лапой паяльник
Сообщения: 303
Зарегистрирован: Ср май 03, 2017 03:22:26

Re: Формирование случайной импульсной последовательности

Сообщение 7seg »

Как-то делал генератор случайных чисел . и за основу взял импульсы дребезга контактов вполне не плохо получается.
andrei23061996@gmail.com
.................................................................................................................
diplodok
Мудрый кот
Сообщения: 1781
Зарегистрирован: Чт авг 10, 2017 20:57:51

Re: Формирование случайной импульсной последовательности

Сообщение diplodok »

Посмотри здесь. После получения случайного числа используй модуля ССР в режиме "сравнение установка выхода в 1/0" (compare set/clear output) для получения своей последователности.
SpeedFighter
Открыл глаза
Сообщения: 63
Зарегистрирован: Вс май 28, 2017 19:07:32

Re: Формирование случайной импульсной последовательности

Сообщение SpeedFighter »

Спасибо.

А вот я что ещё прикинул:

Есть функция srand(чиселка), которая выполняет инициализацию генератора случайных чисел rand(). С помощью неё я хочу и запустить псевдогенератор на пички, вставляя в srand предыдущее сгенерированное число. А первое число можно получить из rand(), например.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18550
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Формирование случайной импульсной последовательности

Сообщение ARV »

Первое число лично я получаю следующим образом: сразу после подачи питания (определяю по флагам), еще до того момента, когда Си очистит память статических переменных, подсчитываю CRC16 всей памяти, что доступна, ну или заметного её куска. И уже эту CRC использую в качестве стартового для srand. Так как после подачи питания RAM имеет случайное состояние, получается почти настоящая случайность. Во всяком случае получше srand(rand()), что вы предложили.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
SpeedFighter
Открыл глаза
Сообщения: 63
Зарегистрирован: Вс май 28, 2017 19:07:32

Re: Формирование случайной импульсной последовательности

Сообщение SpeedFighter »

На PIC18F1230 я сделал, все работало, пусть и через костыли (не смог отключить АЦП на выводах RA0 и RA1, подключил к другим - все работало).
На PIC10F322 - все не так гладко. Почему-то не загорается красный светодиод при отсутствии входных сигналов.

Прикладываю схему из протоса и код.

Код:
Спойлер

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

// Подключение нужных библиотек
#include <stdio.h>
#include <stdlib.h>
#include <xc.h>

#define _XTAL_FREQ 8000000 // Тактовая частота 4 МГц

#define SIGNAL 30 // Длительность сигнала в мкс
#define DELMIN 100 // Максимальная задержка в мкс
#define DELMAX 400000 // Максимальная задержка в мкс

// PIC10F322 Configuration Bit Settings

// 'C' source line config statements

// CONFIG
#pragma config FOSC = EC        // Oscillator Selection bits (EC: CLKIN function enabled)
#pragma config BOREN = ON       // Brown-out Reset Enable (Brown-out Reset enabled)
#pragma config WDTE = OFF        // Watchdog Timer Enable (WDT enabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = OFF      // MCLR Pin Function Select bit (MCLR pin function is digital input, MCLR internally tied to VDD)
#pragma config CP = ON          // Code Protection bit (Program memory code protection is enabled)
#pragma config LVP = ON         // Low-Voltage Programming Enable (Low-voltage programming enabled)
#pragma config LPBOR = ON       // Brown-out Reset Selection bits (BOR enabled)
#pragma config BORV = LO        // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config WRT = OFF        // Flash Memory Self-Write Protection (Write protection off)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

void Prepare(); // Функция подготовки МК

int main()
{
    Prepare(); // Запуск функции подготовки      
    int K = 4; 
    while(1) // Бесконечный цикл работы
    {   
        if(RA3 == 1) // Проверка на нажатые кнопки
        {
            RA2 = 1; // Зажигаем зеленый светодиод
            srand(K); // Инициализация генератора случайных импульсов
            K = DELMIN + rand ()% DELMAX; // Присвоение псевдослучайного числа 
            for(int i = 0; i <= K/60; i++) {} // Пустой цикл задержки
            //__delay_us(SIGNAL-4); // Определяем задержку
            RA1 = 1; // Подаем на выход лог. единицу
            __delay_us(SIGNAL-2); // Определяем длительность сигнала
            RA1 = 0; // Подаем на выход лог. ноль   
        }
        else
        {
            RA2 = 0; // Зажигаем красный светодиод
            RA1 = 0; // На выход ставил лог. ноль
        }       
    }
    return 0;    
}

// Функция подготовки
void Prepare()
{
    TRISA = 0b1000; // Направление работы ножек порта А (вход)
    PORTA = 0b0000; // очищаем порт А
}
Схема:
СпойлерИзображение
Вложения
PIC10F322.X.production.hex
hex
(2.46 КБ) 586 скачиваний
PIC10F322.rar
Проект в протосе
(71.58 КБ) 304 скачивания
diplodok
Мудрый кот
Сообщения: 1781
Зарегистрирован: Чт авг 10, 2017 20:57:51

Re: Формирование случайной импульсной последовательности

Сообщение diplodok »

Читаем документацию на 10F322

LVP = 1 - MCLR/Vpp pin is MCLP. Weak Pull-Up is enabled.

Твой код не может определить 1 на входе. Там всегда есть 1.
Аватара пользователя
КРАМ
Друг Кота
Сообщения: 25261
Зарегистрирован: Чт янв 10, 2008 22:01:02
Откуда: Московская область, Фрязино

Re: Формирование случайной импульсной последовательности

Сообщение КРАМ »

Вообще непонятна история с двумя кнопками на одном входе. Что автор хотел получить?
Впрочем, со светодиодами такая же история. Светодиоды нельзя будет погасить оба.
SpeedFighter
Открыл глаза
Сообщения: 63
Зарегистрирован: Вс май 28, 2017 19:07:32

Re: Формирование случайной импульсной последовательности

Сообщение SpeedFighter »

[uquote="diplodok",url="/forum/viewtopic.php?p=3252443#p3252443"]Читаем документацию на 10F322

LVP = 1 - MCLR/Vpp pin is MCLP. Weak Pull-Up is enabled.

Твой код не может определить 1 на входе. Там всегда есть 1.[/uquote]

А как убрать её?

#pragma config LVP = OFF - не помогает.
КРАМ писал(а):Вообще непонятна история с двумя кнопками на одном входе. Что автор хотел получить?
Впрочем, со светодиодами такая же история. Светодиоды нельзя будет погасить оба.
Нажатая кнопка включения - все работает. Не нажата кнопка включения или нажата кнопка выключения - МК не генерирует сигнал, только светодиод красный горит. На PIC18F1230 у меня все работало, тут же - нет.
Ответить

Вернуться в «PIC»