Перейти к содержанию

Bugrim

Members
  • Постов

    235
  • Зарегистрирован

  • Посещение

Сообщения, опубликованные Bugrim

  1. Доброго времени суток.

    Есть, на первый взгляд, простая задача, однако меня ставит в затруднительное положение. Есть напряжение 36АС, необходимо получить 5DC 0,3А. Классика (диодный мост и кренка) не подходят. Для кренки входное напряжение будет высоким, да и рассеиваемая мощность будет велика. По габаритам хочется компактности. Миниатюрный трансформатор, с моей точки зрения, 36В на 7В было бы идеально, но не знаю где взять небольшое железо под него. Может кто другой вариант предложит, буду признателен.

     

  2. Доброго времени суток.

    Подскажите, просто бесит разбивать выражения, чем отличается запись:

    *slovo1=(*(data+temp)>>4+0x30);

    от 

    *slovo1=*(data+temp)>>4;  
    *slovo1+=0x30;

    С моей точки зрения обе записи эквивалентны, однако желаемый результат дает второе. Может я что то не понимаю.

    Использую MPLABX v5.3, XC8 v1.33, PIC18F67K22.

  3. 04.10.2020 в 19:07, ARV сказал:

    Много ли надо места потратить на такую "оберточную" функцию?!

    Убедили.

    7 часов назад, mazzi сказал:

    пишите как можно проще и понятнее

     Это потому что я не опытный или этот совет всем полезен?

     

     

  4. Места жалко. А для функций можно написать подсказки, что бы высвечивались при записи аргументов (за что этот аргумент отвечает и какие значения может принимать). Или описание функций в комментариях самой функции писать?

  5. не знаю правильно ли, но работает другой вариант:

    void myGreatFunction(char par1, char *par2, char par3)
    
    {
    	myVeryImportantVariable = par2;    
    	if (par1 =6) {myVeryImportantVariable = (char)&(*par2)};
    	.......
    
    }
    
    void myGreatFunction(6, 0x72, 2);

    это больше мне нравиться

  6. Доброго времени суток.

    Прошу подсказать как в си в функцию, аргумент которой указатель передать число без сторонней переменной. То есть:

    Есть функция вывода данных/команд на ЖКИ:

    void LSD_zapis(unsigned char F_LSD_data_comand,unsigned char *F_LSD_data, unsigned char F_LCD_kol_polubayt);

    где: 

    F_LSD_data_comand- выбор передачи команды или данных;

    *F_LSD_data - указатель на массив данных;

    F_LCD_kol_polubayt - длина массива в полубайтах.

    при выводе массива данных проблем не возникает так как данные расположены в массиве, а вот при выдаче команды часто приходится выдавать просто один байт, сейчас это делаю так:

        temp_data=0x73;
        LSD_zapis(1,temp_data,2);

    Но хочется без temp_data , указывать число 0х73 как аргумент, то есть так:

        LSD_zapis(1,0x73,2);

    Как возможно это сделать?

     Использую компилятор XC8. Да я понимаю что тема не для этого компилятора, но принцип, я думаю, должен быть одинаков.

    За ранее спасибо.

  7. Разобрался. Регистр ANSELH не был настроен. При запуске устанавливался в единицы (аналоговые входы). При правильной настройке, правильно и макетка (до этого не совсем корректно) и протеус заработал.

    Всем спасибо.

  8. Доброго времени суток.

    Подскажите что делаю не так. Необходимо настроить внешнее прерывание на RB0. Proteus на изменение RB0 совсем не реагирует. Решил промоделировать в живую на макетке. Прерывание срабатывает однако флаг прерывания не сбрасывается (наблюдаю в пошаговом выполнении). Камень PIC16f886, программатор/отладчик PicKit4, среда разработки MPLABX IDE v5.3, proteus 8.4 SP0.

    void main(void) {
        nastroyka();
        F_bili_izmeneniya=1;
        while (1) {
           
            
    //        ekran();
            ADC_start();
            ADC_read();
            
            __delay_ms(50);
            __nop;
        }
    }
    void nastroyka(void){
        //******Настройка прерываний********
        //******GIE=1   PEIE=1  T0IE=0  INTE=0
        //******RBIE=1  T0IF=0  INTF=0  RBIF=0
        
        INTCON=0b11001000;
        IOCB=0xff;
        BCLIE=1;
        //ULPWUIE=1;
       // ANS12=1;
        
        
        
        //*******Настройка порта A
        TRISA0=1;   //вход ***Вход АЦП
        TRISA2=1;   //вход **Вход Uref-
        
        //*******Настройка порта B
        TRISB0=1;
        
        //***********Настройка АЦП***********
        // Настройка времени обрабатки АЦП = 32*Tosc
        ANS0=1;
        ANS2=1;
        ADCS0=0;
        ADCS1=1;
        ADFM=1; //Правое выравнивание результата
            //*****Подключение канала 0
        CHS0=0;
        CHS1=0;
        CHS2=0;
        CHS3=0;
            //****Подтяжка Vref+ к внутренниму +
        VCFG0=0;
        //**** Vref- к внешниму источнику (AN2))
        VCFG1=1;
        //Включить АЦП
        ADON=1;
        
        
        //***********Настройка PORTC***********
        TRISC=0x18;////RC3 and RC4 Input (SDC and SDA)
        TRISC5=1;   //вход кнопки
        
        //***********I2C***********
        SSPADD=0X09;
        SSPSTAT=0X80;
        SSPCON=0X38;
    }
    void interrupt interr(void){
        volatile char temp;
        if(RBIF){
            temp=PORTB;
            RBIF=0;
        }
    }

    Почему флаг прерывания не сбрасывается? Что делаю не так? Подскажите протеус адекватный к внешним прерываниям.

  9. ПИД регулятор. Контроль температуры. Хочется:

    1 частота опроса 25 Гц для каждого канала.

    2 каналов - 3

    3 датчик температуры - термопара К типа - 3 шт.

    4 динамическая индикация 5 разрядов.

    5 органы управления - 4 кнопки.

    В первом приближении так.

    В вычислениях предполагаю использовать такой формат. 16 бит: 5 разрядов - дробная часть, 10 - целая, 1 знаковый. Расчет примерно так ( ещё обдумываю):

    U = K * ( Err + (1/Ti)*Int + Td*dErr )

    Eo = E; Нам нужна прошла ошибка. Ошибки — по 16бит

    E = Y-X; Вычисляем новое рассогласование. 16bit

    Int = Int + (E+Eo)/2; Интегрируем ошибку. При этом считаем полусумму разности (разностная схема). 32bit = 32bit + 16bit

    cI = Int * (1/Ti); Считаем интегральный вклад — 32bit * 32bit => 32bit

    cD = Td * (E-Eo); Считаем диф вклад — 16*16 => 32bit

    PID = E + cI + cD; Подскобочное; 16+32+32 => 32bit

    U = K*PID/256; Коэфф; 32*16/8 bit => 40bit.

    Будет ли успевать на частоту 25Гц, или изначально снизить надо.

    Источник вдохновения - https://m.habr.com/ru/post/145991/

     

     

  10. Может и за умножение загнул, но так или иначе оперировать надо 32 разрядными. На данном этапе пока что это размышления о будующем проекте. Но в протеусе посмотреть проблемы не составит, однако я подозреваю, что время операции деления числа на 2, 4 или 8 будет отличатся от времени деления на число, например, 863. Все комбинации деления перебрать - глупость, с моей точки зрения. Подозреваю, что не один я столкнулся с подобным.  

  11. Доброго дня.

    Подскажите возможно ли вычислить максимальное время вычисления выражения. В конкретном случае деление/умножение 32 разрядных чисел. Максимальное время выполнения операций необходимо для расчета времени (частоты) опроса датчика, который предоставит новые данные для вычисления. Пишу на xc8.

    За ранее благодарен.

  12. Объявлены массивы:

    unsigned char  dekady[4][10],dekadyBCD[4][10];

    Начальный адрес первого 0х110, второго 0х190.

    Функция

    void inc_chass(char *chas_dec,char *chas_bcd);

    Тогда вызов функции

    inc_chass(&dekady[1][0],&dekadyBCD[1][0]);

    должен передать указателю chas_dec значение 0х11А, а указателю   chas_bcd значение 0х19А. Однако при прогоне в протеусе указателю chas_dec присваивается значение 0x0F1A, почему мне не понятно. Указателю chas_bcd присваивается правильное значение 0х19А.

  13. Да так и есть - предупреждение "illegal conversion between pointer types". Однако переписав вызов функции:

    inc_chass(&(dekady[1][0]),&(dekadyBCD[1][0]));         //увеличить час

    приводит не совсем к нужному результату:  chas_dec=0x0F1A, должен быть 0х11А, chas_bcd=0х19А, что есть правильно.

    48 минут назад, Alex сказал:

    Адрес начала массива - есть само имя массива. Без всяких там индексов и т.д...

    Я знаю, однако, в дальнейшем, необходимо будет передавать указатель  на разные области массива.

  14. Опять затупил. Помогите разобраться. Объявлены массивы:

    unsigned char  dekady[4][10],dekadyBCD[4][10];

    Начальный адрес первого 0х110, второго 0х190.

    Есть функция 

    void inc_chass(unsigned char *chas_dec,unsigned char *chas_bcd){
        if (++(*chas_dec)==24)
            *chas_dec=0;
        *chas_bcd=bin_to_bcd(*chas_dec);
        *(chas_bcd+1)=*chas_bcd&0x0f;
        *chas_bcd=(*chas_bcd>>4)&0x0f;
    }

    Ее прототип:

    void inc_chass(char *chas_dec,char *chas_bcd);

    Вызов функции:

    inc_chass(dekady,dekadyBCD[1][0]);         //увеличить час

    Но в функцию передаются не те данные, которые хочу, т.е. не адрес начала массива "dekady" (0х110) и не адрес "dekadyBCD[1][0]" (0х19А), а вот что:5cc59d3060340_.jpg.63109e408054050928ff1f8170928d55.jpg

    Где не прав, подскажите. Может это длина адреса виновата, которая в char не помещается?

×
×
  • Создать...