Форум Микро-Чип
Поиск и заказ электронных компонентов
 

Вернуться   Форум Микро-Чип > Общетехнические вопросы

Общетехнические вопросы Общие вопросы аналоговой и цифровой электроники.

Ответ
 
Опции темы Опции просмотра
Старый 19.08.2018, 19:06   #1
GoshaGrek
Senior Member
 
Регистрация: 29.09.2011
Сообщений: 273
Вес репутации: 357/32
GoshaGrek is just really niceGoshaGrek is just really niceGoshaGrek is just really niceGoshaGrek is just really nice
По умолчанию вопрос по DS18B20&PIC16F690

Всем доброго,коллеги...
Такая тема возникла.Понадобилося вот термометр состряпать с функцией регулирования до 100-110 град.
Без всяких наворотов аля LCD,CAN и прочего. Чтоб просто тупо с одного датчика считать на самый дешевый 7 сегментник вывести, ну короче чтоб видно

было только , ну и попутно функцию регулирования присобачить, чтоб была
Рещил даллас использовать
Никогда не занимался раньше 18В20.
В просторах сети всяких примеров полно, но все или с LCD, или там всякой всячины навешано уйма что не нужна мне на фиг. Ну кое что попробовал-

готовое-короче если без допила- то не то что нужно.
Ну вот сам решил состряпать - конечно не с нуля на ровном месте- почерпнул кое что из инета и нашего форума))), например обработку кнопок у Testera(правда немного изменил под себя там)
В итоге получилось вот что...
Вроде работает- и в протезе и в железе тоже...Но не совсем до конца.
Температуру считывает, показывает, типа терморегулятор тоже вроде работает.
Но в режиме работы когда просто меряет температуру- иногда на индикатор на 1-2 сек выбрасывает некорректные показания.
Причем в симуляторе протеуса тоже самое! Как и в железе.Одинаково.
Видимо где то в коде хомуты.
Все уже излазил...И задержки кое где менял и процедуру чтения датчика в прерывания ставил(правда понял что так хуже и нельзя)))
Короче может кто взглянет свежим взглядом- где тут что не так...а то уже мозги набекрень за три вечера
да... проект на библиотеки не разбивал ,чтоб не путаться пока
Код:
//=========================================================================
// Типа терморегулятор - термометр        
// Датчик - DS18B20                 
// Процессор 16F690 - частота 4МГц
// Контроль температуры от -55 до +125°С
// Регулирование - от 0 до +125°С
// Регулирование температуры по двухпозиционному закону
// Гистерезис 2°С
// Выход на реле 
// Задержка включения/выключения реле 2сек              
//=========================================================================


#include <xc.h>

#define _XTAL_FREQ 4000000 //defined for delay

// PIC16F690 Configuration Bit Settings

// 'C' source line config statements

// CONFIG
#pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator: High-speed crystal/resonator on RA4/OSC2/CLKOUT and RA5/OSC1/CLKIN)
#pragma config WDTE = ON        // Watchdog Timer Enable bit (WDT enabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = ON       // MCLR Pin Function Select bit (MCLR pin function is MCLR)
#pragma config CP = OFF         // Code Protection bit (Program memory code protection is disabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)
#pragma config BOREN = OFF      // Brown-out Reset Selection bits (BOR disabled)
#pragma config IESO = OFF       // Internal External Switchover bit (Internal External Switchover mode is disabled)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is disabled)

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

//=========================================================================
//                    КОНСТАНТЫ,МАКРОСЫ И ПЕРЕМЕННЫЕ
//=========================================================================
//типа макросы
#define BitIsClear(reg, bit)    ((reg & (1<<(bit))) == 0)
//пример: if (BitIsClear(PORTB,1)) {...} //если бит очищен

#define BitIsSet(reg, bit)       ((reg & (1<<(bit))) != 0)
//пример: if(BitIsSet(PORTB,2)) {...} //если бит установлен

#define InvBit(reg, bit)      reg ^= (1<<(bit))
//пример: InvBit(PORTB, 1); //инвертировать 1-й бит PORTB

//для датчика DS18B20
#define Skip_ROM             0xCC
#define Convert_T            0x44
#define Read_scratchpad      0xBE

#define Port_18B20           RC5
#define Port_18B20_output    TRISC5 = 0
#define Port_18B20_input     TRISC5 = 1

#define WAIT1                1000
#define WAIT2                500

#define DS18B20_CONV_TIME    750
#define DS18B20_RESET_PULSE  480 //480
#define DS18B20_WAIT_TIME    60 //60
#define DS18B20_PULLUP_TIME  2

#define ONEWIRE_PRESENT      0
#define ONEWIRE_ABSENT       1

#define flag_minus flags.b7

volatile unsigned char temperature;
unsigned char tempL, tempH;
unsigned int temp_result;
unsigned int tmp;

//рабочие выходы 
#define HEAT      RC3

//для индикатора 
#define SGA       RA1
#define SGB       RB7
#define SGC       RB4 
#define SGD       RC1
#define SGE       RC0
#define SGF       RA2
#define SGG       RB5

#define DIGIT_1     RA0 
#define DIGIT_2     RC6
#define DIGIT_3     RC7
#define DIGIT_4     RB6

#define pusto            10
#define C                11
#define P                12
#define S                13
#define n                14
#define F                15
#define h                16
#define r                17
#define L                18
#define u                19
#define minus           20
#define degree           21

const unsigned char SEGMENTE[22] = {
    // gfedcba    
    0b00111111, // 0
    0b00000110, // 1
    0b01011011, // 2
    0b01001111, // 3
    0b01100110, // 4
    0b01101101, // 5
    0b01111101, // 6
    0b00000111, // 7
    0b01111111, // 8
    0b01101111, // 9
    0b00000000, // pusto
    0b00111001, // C 
    0b01110011, // P
    0b01101101, // S
    0b01010100, // n
    0b01110001, // F
    0b01110100, // h 
    0b01010000, // r 
    0b00111000, // L 
    0b00011100, // u
    0b01000000, // minus
    0b01100011 // degree  
};

// для преобр. байта в сегменты 

volatile union {
    unsigned char j;

    struct {
        unsigned b0 : 1;
        unsigned b1 : 1;
        unsigned b2 : 1;
        unsigned b3 : 1;
        unsigned b4 : 1;
        unsigned b5 : 1;
        unsigned b6 : 1;
        unsigned b7 : 1;
    } indbi;
} indbt;

volatile unsigned int display; // то что выводим на индикатор
volatile unsigned char sg1, sg2, sg3, sg4;
unsigned char hundreds, tens, ones;
unsigned int temp;
volatile unsigned char segcounter;

//флаги 
#define flag_ind     flags.b0
#define flag_set     flags.b1 // 
#define flag_heat    flags.b2 // 
#define flag_blink   flags.b3 // 
#define flag_hold    flags.b4 // 

volatile struct {
    unsigned b0 : 1;
    unsigned b1 : 1;
    unsigned b2 : 1;
    unsigned b3 : 1;
    unsigned b4 : 1;
    unsigned b5 : 1;
    unsigned b6 : 1;
    unsigned b7 : 1;
} flags;

//переменные 
volatile unsigned char hyst = 2; //гистерезис при регулировании
volatile unsigned char setpoint;
volatile unsigned char setpoint_old;
volatile unsigned char blinkcounter; //мигалка в режиме установки уставки
volatile unsigned char setcounter; //счетчик  режимов меню установки
volatile unsigned char switchcounter;
volatile unsigned char temperature;

//для контроля кнопок и входов

volatile struct {
    unsigned char Toggle; // Состояния входов
    unsigned char Jitter : 2; // Для подавления дребезга 
    unsigned char Counter; // Для проверки удерживания
    unsigned char Hold; // Состояние длительного удерживания
    //-------------------------------  // События:
    unsigned char Short; // Короткое нажатие и отпускание
    unsigned char Changed; // Состояние входов изменилось
} inState;

//=========================================================================
//             НАЧАЛЬНАЯ ИНИЦИАЛИЗАЦИЯ КОНТРОЛЛЕРА
//=========================================================================

void init(void) {
    CLRWDT();
    PEIE = 0;
    GIE = 0;
    CM1CON0 = CM2CON0 = 0x00; //компаратор отключить!!!!!!!!!!
    CCP1CON = 0x00; //модуль ШИМ отключить
    // АЦП отключить!!!!
    ANSEL = 0x00;
    ANSELH = 0x00;
    ADCON1 = 0x00; // 
    ADCON0 = 0x00; //
    ADRESL = ADRESH = 0x00;
    //инициализация портов и таймеров
    TRISA = 0b00001000;
    WPUA = 0x00;
    TRISB = 0b00000000;
    TRISC = 0b00100000;
    OPTION_REG = 0b10000011;
    //инициализация TMR1
    T1CON = 0b00010101;
    T1CON = 0b00000101;
    TMR1IE = 1;
    TMR1L = 3;
    TMR1H = 217;
    TMR1IF = 0;
    //инициализация TMR2
    T2CON = 0b01111001;
    TMR2IF = 0;
    TMR2IE = 1;
    PR2 = 78;
    TMR2ON = 1;
}
//===========================================================================
//         функции работы с датчиком  DS18B20
//===========================================================================

unsigned char reset() {
    Port_18B20_output; // Tris = 0 (output)
    Port_18B20 = 0; // set pin# to low (0)
    __delay_us(DS18B20_RESET_PULSE); // 1 wire require time delay
    Port_18B20_input; // Tris = 1 (input)
    __delay_us(DS18B20_WAIT_TIME); // 1 wire require time delay

    if (Port_18B20 == 0) // if there is a presence pluse
    {
        __delay_us(DS18B20_RESET_PULSE); // Reset and return
        return ONEWIRE_PRESENT; // return 0 ( 1-wire is presence)
    }
    __delay_us(DS18B20_RESET_PULSE); // Reset and return  
    return ONEWIRE_ABSENT; // return 1 ( 1-wire is NOT presence)
}
//--------------------------------------------------------------------------- 

void write(char WRT) {
    char i, Cmd;
    Cmd = WRT;
    Port_18B20_input; // set pin# to input (1)
    for (i = 0; i < 8; i++) {
        if ((Cmd & (1 << i)) != 0) {
            // write 1
            Port_18B20_output; // set pin# to output (0)
            Port_18B20 = 0; // set pin# to low (0)
            __delay_us(DS18B20_PULLUP_TIME); // 1 wire require time delay
            Port_18B20_input; // set pin# to input (release the bus)
            __delay_us(DS18B20_WAIT_TIME); // 1 wire require time delay
        }
        else {
            //write 0
            Port_18B20_output; // set pin# to output (0)
            Port_18B20 = 0; // set pin# to low (0)
            __delay_us(DS18B20_WAIT_TIME); // 1 wire require time delay
            Port_18B20_input; // set pin# to input (release the bus)
        }
    }
}
//--------------------------------------------------------------------------  

unsigned char read() {
    char i, result = 0;
    Port_18B20_input; // TRIS is input(1)
    for (i = 0; i < 8; i++) {
        Port_18B20_output; // TRIS is output(0)
        Port_18B20 = 0; // genarate low pluse for 2us
        __delay_us(DS18B20_PULLUP_TIME);
        Port_18B20_input; // TRIS is input(1) release the bus
        if (Port_18B20 != 0) {
            result |= 1 << i;
        }
        __delay_us(DS18B20_WAIT_TIME); // wait for recovery time
    }
    temp_result = result;
    return result;
}
//========================================================================
//              СЧИТЫВАНИЕ ТЕМПЕРАТУРЫ С 18В20
//========================================================================

void metering(void) {
    //измерение температуры  - DS18B20
    reset();
    write(Skip_ROM);
    write(Convert_T);
    __delay_ms(DS18B20_CONV_TIME);
    reset();
    write(Skip_ROM);
    write(Read_scratchpad);
    tempL = read();
    tempH = read();
    //если положительная
    if (BitIsClear(tempH, 4)) {
        flag_minus = 0;
        tempL >>= 4;
        tempH <<= 4;
        temperature = tempL | tempH;
    }        //если отрицательная
    else if (BitIsSet(tempH, 4)) {
        flag_minus = 1;
        tmp = (tempH << 8) | tempL;
        tmp = ~tmp + 1;
        tempL = tmp;
        tempH = tmp >> 8;
        temperature = ((tempH & 7) << 4) | (tempL >> 4);
    }
}
//========================================================================
//                    КОНТРОЛЬ СОСТОЯНИЯ КНОПОК И ВХОДОВ
//========================================================================

void button_control(void) {
    static unsigned char prInputs; // Предыдущее состояние входов
    unsigned char inTemp;
    inTemp = 0x00;
    if (!DIGIT_1) inTemp |= 0x01;
    if (!DIGIT_2) inTemp |= 0x02;
    if (!DIGIT_3) inTemp |= 0x04;

    inTemp ^= prInputs; // Изменения с момента последнего выполнения
    prInputs ^= inTemp; // Текущее состояние входов
    // Подавление дребезга
    if (inTemp) {
        inState.Jitter = 0;
        return;
    }
    //---------------------------------------------------------------------
    inState.Jitter++;
    inTemp = prInputs ^ inState.Toggle; // Маска изменения состояние
    // Состояние изменилось, дребезг подавлен
    if (!inState.Jitter && inTemp) {
        // Есть отпущенные        
        if (inState.Toggle & inTemp) {
            inState.Changed |= inTemp;
            inState.Short |= inTemp;
            inState.Short &= ~inState.Hold;
            inState.Hold &= ~inTemp;
        }
        // Есть нажатые
        if ((inState.Toggle ^ inTemp) & inTemp) {
            inState.Changed |= inTemp;
            inState.Short &= ~inTemp;
        }
        inState.Toggle = prInputs;
        inState.Counter = 0;
    }
    inState.Counter++;
    // Длительное удерживание
    if (inState.Counter == 50) {
        inState.Changed |= inState.Hold ^ inState.Toggle;
        inState.Hold = inState.Toggle;
    }
}

//========================================================================
//             функция вывода байта на индикаторы                    
//========================================================================

void outByte(unsigned char bt) {
    indbt.j = SEGMENTE[bt];
    SGA = !indbt.indbi.b0;
    SGB = !indbt.indbi.b1;
    SGC = !indbt.indbi.b2;
    SGD = !indbt.indbi.b3;
    SGE = !indbt.indbi.b4;
    SGF = !indbt.indbi.b5;
    SGG = !indbt.indbi.b6;
}

//========================================================================
//функция преобразование int числа из двоичного в двоично-десятичный формат                   
//========================================================================

void convert(void) {
    hundreds = 0;
    tens = 0;
    ones = 0;
    while (temp > 9) {
        if (temp > 99) {
            hundreds++;
            temp -= 100;
        } else if ((temp > 9) && (temp <= 99)) {
            tens++;
            temp -= 10;
        }
    }
    if ((temp >= 0) && (temp <= 9)) ones = temp;
    sg1 = hundreds;
    sg2 = tens;
    sg3 = ones;
}

//========================================================================
//                     ДИНАМИЧЕСКАЯ ИНДИКАЦИЯ
//========================================================================

void dinind(void) {
    switch (segcounter) {
            //вывод первого индикатора
        case 0:
            DIGIT_1 = 1;
            DIGIT_2 = 0;
            DIGIT_3 = 0;
            DIGIT_4 = 0;
            if (flag_minus == 1)outByte(minus);
            else if (sg1 == 0) {
                outByte(pusto);
            }
            else if ((flag_set == 0) || ((flag_set == 1)&&(flag_blink == 1)) ||
                    ((flag_set == 1)&&(flag_hold == 1))) {
                outByte(sg1);
            }
            break;
            //вывод второго индикатора
        case 1:
            DIGIT_1 = 0;
            DIGIT_2 = 1;
            DIGIT_3 = 0;
            DIGIT_4 = 0;
            if ((sg1 == 0)&&(sg2 == 0)) {
                outByte(pusto);
            }
            else if ((flag_set == 0) || ((flag_set == 1)&&(flag_blink == 1)) ||
                    ((flag_set == 1)&&(flag_hold == 1))) {
                outByte(sg2);
            }
            break;
            //вывод третьего индикатора
        case 2:
            DIGIT_1 = 0;
            DIGIT_2 = 0;
            DIGIT_3 = 1;
            DIGIT_4 = 0;
            if ((flag_set == 0) || ((flag_set == 1)&&(flag_blink == 1)) ||
                    ((flag_set == 1)&&(flag_hold == 1))) {
                outByte(sg3);
            }
            break;
            //вывод четвертого индикатора
        case 3:
            DIGIT_1 = 0;
            DIGIT_2 = 0;
            DIGIT_3 = 0;
            DIGIT_4 = 1;
            if ((flag_set == 0) || ((flag_set == 1)&&(flag_blink == 1)) ||
                    ((flag_set == 1)&&(flag_hold == 1))) {
                outByte(degree);
            }
            break;
    }

    if (segcounter++ > 2) segcounter = 0;
}

//==========================================================================
//                     ОБРАБОТКА ПРЕРЫВАНИЙ
//==========================================================================

void interrupt isr(void) {
    //прерывание TMR1
    // Tick  10ms   
    if (TMR1IF && TMR1IE) {
        CLRWDT();
        //управление нагревом
        if ((temperature >= setpoint)&&(flag_heat == 1)) {
            switchcounter++;
            if (switchcounter == 200) {
                HEAT = 0;
                flag_heat = 0;
                switchcounter = 0;
            }
        }
        else if ((temperature <= (setpoint - hyst))&&(flag_heat == 0)) {
            switchcounter++;
            if (switchcounter == 200) {
                HEAT = 1;
                flag_heat = 1;
                switchcounter = 0;
            }
        } else switchcounter = 0;

        TMR1L = 3;
        TMR1H = 217;
        TMR1IF = 0;
    }

    //прерывание TMR2
    // Tick ~ 5ms
    if (TMR2IF && TMR2IE) {
        CLRWDT();
        TMR2IE = 0;
        TMR2IF = 0;
        //чтоб мигало в режиме установки
        blinkcounter++;
        if (blinkcounter == 60) {
            flag_blink = !flag_blink;
            blinkcounter = 0;
        }
        //динамическая индикация
        if (flag_ind == 1) {
            dinind();
        }
        //проверка кнопок
        if (flag_ind == 0) {
            DIGIT_1 = DIGIT_2 = DIGIT_3 = DIGIT_4 = 0;
            outByte(pusto);
            SGA = SGB = SGC = SGD = SGE = SGF = SGG = 1;
            TRISA = 0b00001001;
            TRISC = 0b11100000;
            button_control();
            TRISA = 0b00001000;
            TRISC = 0b00100000;
        }
        flag_ind = !flag_ind;
        TMR2IE = 1;
    }
}

//===========================================================================
//                    ОСНОВНОЙ БЛОК ПРОГРАММЫ
//===========================================================================

void main() {
    init();
    CLRWDT();
    //инициализация флагов и режимов    
    flag_set = 0;
    flag_blink = 0;
    flag_heat = 0;
    display = 0;
    setcounter = 0;
    segcounter = 0;
    blinkcounter = 0;
    switchcounter = 0;
    setpoint_old = EEPROM_READ(0); // прочитать значение             
    setpoint = setpoint_old; //уставки из EEPROM
    temperature = 0;
    flag_ind = 1;
    HEAT = 0;
    PEIE = 1;
    GIE = 1; 

    for (;;) {
        //в режиме установки запрет нагрева
        if (flag_set == 1) {
            TMR1IE = 0;
            TMR1IF = 0;
            HEAT = 0;
            flag_heat = 0;
        } else TMR1IE = 1;
        //измерение температуры       
        if (flag_set == 0) {
            metering();
            display = temperature;
            temp = display;
            convert();
        }
        //-----------------------------
        //выбор меню установки уставки
        if (BitIsSet(inState.Short, 1)) {
            setcounter++;
            if (setcounter == 1) {
                flag_set = 1;
            }  
            //сброс меню 
            else if (setcounter > 1) {
                flag_set = 0;
                setcounter = 0;
            }
        }
        //-----------------------------
        //установка  температуры регулирования 
        if (flag_set == 1) {
            //увеличиваем температуру
            if ((BitIsSet(inState.Hold, 2))&&(setpoint < 125)) {
                setpoint++;
                flag_hold = 1;
                flag_blink = 0;
            }
            //уменьшаем температуру
            if ((BitIsSet(inState.Hold, 0))&&(setpoint > 0)) {
                setpoint--;
                flag_hold = 1;
                flag_blink = 0;
            }
            if ((BitIsClear(inState.Hold, 0))&&
                    (BitIsClear(inState.Hold, 2))) {
                flag_hold = 0;
            }
            temp = setpoint;
            convert();
        }
        // запись значения уставки температуры в EEPROM
        if ((setpoint_old != setpoint)&&(flag_set == 0)) {
            setpoint_old = setpoint;
            EEPROM_WRITE(0, setpoint_old);                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
        }
        //-----------------------------
        inState.Changed = 0x00;
        inState.Short = 0x00;
        __delay_ms(500);

    }
}
Миниатюры
sxema.jpg  
Вложения
Тип файла: rar thermostat18B20.X.rar (163.6 Кб, 3 просмотров)
GoshaGrek вне форума   Ответить с цитированием
Старый 19.08.2018, 19:30   #2
al.kl
Senior Member
 
Регистрация: 11.10.2011
Возраст: 23
Сообщений: 264
Вес репутации: 750/35
al.kl is a splendid one to beholdal.kl is a splendid one to beholdal.kl is a splendid one to beholdal.kl is a splendid one to beholdal.kl is a splendid one to beholdal.kl is a splendid one to beholdal.kl is a splendid one to behold
Отправить сообщение для al.kl с помощью ICQ
По умолчанию Re: вопрос по DS18B20&PIC16F690

На время тайм-слота обязательно запрещаем прерывания. Плюс обработка CRC.
Тогда проблем с битыми показаниями не будет.
al.kl вне форума   Ответить с цитированием
Старый 19.08.2018, 19:57   #3
GoshaGrek
Senior Member
 
Регистрация: 29.09.2011
Сообщений: 273
Вес репутации: 357/32
GoshaGrek is just really niceGoshaGrek is just really niceGoshaGrek is just really niceGoshaGrek is just really nice
По умолчанию Re: вопрос по DS18B20&PIC16F690

Цитата:
Сообщение от al.kl Посмотреть сообщение
На время тайм-слота обязательно запрещаем прерывания. Плюс обработка CRC.
Тогда проблем с битыми показаниями не будет.
Спасибо! как я раньше не обратил внимание С обработкой CRC пока не разобрался. С запретом прерываний сделал так...
вроде стало лучше....

Код:
//========================================================================
//              СЧИТЫВАНИЕ ТЕМПЕРАТУРЫ С 18В20
//========================================================================
void metering(void){
      //измерение температуры  - DS18B20
      reset();
      GIE = 0;
      write(Skip_ROM);
      write(Convert_T);
      GIE = 1;
       __delay_ms(DS18B20_CONV_TIME);
      GIE = 0;           
      reset();
      write(Skip_ROM);
      write(Read_scratchpad);          
      tempL = read();
      tempH = read();
      GIE = 1;
      //если положительная
      if(BitIsClear (tempH,4)){
      flag_minus = 0;
      tempL >>= 4;        
      tempH <<= 4;       
      temperature = tempL | tempH;        
       }
      //если отрицательная
      else if(BitIsSet(tempH,4)){
      flag_minus = 1;                            
      tmp = (tempH <<8)|tempL;        
      tmp = ~tmp + 1;
      tempL = tmp;
      tempH = tmp >> 8;          
      temperature = ((tempH & 7)<<4)|(tempL >>4);                           
      }    
}
GoshaGrek вне форума   Ответить с цитированием
Старый 19.08.2018, 22:27   #4
al.kl
Senior Member
 
Регистрация: 11.10.2011
Возраст: 23
Сообщений: 264
Вес репутации: 750/35
al.kl is a splendid one to beholdal.kl is a splendid one to beholdal.kl is a splendid one to beholdal.kl is a splendid one to beholdal.kl is a splendid one to beholdal.kl is a splendid one to beholdal.kl is a splendid one to behold
Отправить сообщение для al.kl с помощью ICQ
По умолчанию Re: вопрос по DS18B20&PIC16F690

Немного не так.
Вы сейчас запрещаете прерывание на чтение/запись всех 8-ми байтов, а это слишком долго. Нужно делать запрет на время формирования тайм-слота. Тогда запрет будет максимум на 60 us.


PS: Для справки. Время между тайм-слотами не ограничено и может быть сколь угодно длительным. Главное - выдержать временные интервалы самого тайм-слота.
al.kl вне форума   Ответить с цитированием
Старый 20.08.2018, 20:04   #5
GoshaGrek
Senior Member
 
Регистрация: 29.09.2011
Сообщений: 273
Вес репутации: 357/32
GoshaGrek is just really niceGoshaGrek is just really niceGoshaGrek is just really niceGoshaGrek is just really nice
По умолчанию Re: вопрос по DS18B20&PIC16F690

Цитата:
Сообщение от al.kl Посмотреть сообщение
Немного не так.
Вы сейчас запрещаете прерывание на чтение/запись всех 8-ми байтов, а это слишком долго. Нужно делать запрет на время формирования тайм-слота. Тогда запрет будет максимум на 60 us.
ааааааа....
Я правильно понимаю что как то так?

Каждый тайм слот вроде вне прерывания...
На резет надо запрещать кстати, или нет- кто какого мнения?

Код:
void write(char WRT)
{
    char i,Cmd;
    Cmd = WRT;
    Port_18B20_input; // set pin# to input (1)
    for(i = 0; i < 8; i++)
    {
        if((Cmd & (1<<i))!= 0)
        {   
            GIE = 0;
            // write 1
            Port_18B20_output; // set pin# to output (0)
            Port_18B20 = 0; // set pin# to low (0)
            __delay_us(DS18B20_PULLUP_TIME); // 1 wire require time delay
            Port_18B20_input; // set pin# to input (release the bus)
            __delay_us(DS18B20_WAIT_TIME); // 1 wire require time delay
            GIE = 1;
        } 
        else  {
            GIE = 0;
            //write 0
            Port_18B20_output; // set pin# to output (0)
            Port_18B20 = 0; // set pin# to low (0)
            __delay_us(DS18B20_WAIT_TIME); // 1 wire require time delay
            Port_18B20_input; // set pin# to input (release the bus)
            GIE =1;
        }
    }
}
//--------------------------------------------------------------------------  
unsigned char read()
{
    char i,result = 0;
    Port_18B20_input; // TRIS is input(1)
    for(i = 0; i < 8; i++)
    {
        GIE = 0;
        Port_18B20_output; // TRIS is output(0)
        Port_18B20 = 0; // genarate low pluse for 2us
        __delay_us(DS18B20_PULLUP_TIME);
        Port_18B20_input; // TRIS is input(1) release the bus
        if(Port_18B20 != 0) {
            result |= 1<<i;
        }
        __delay_us(DS18B20_WAIT_TIME); // wait for recovery time
        GIE = 1;
    }
    temp_result = result;   
    return result;
}
GoshaGrek вне форума   Ответить с цитированием
Старый 20.08.2018, 20:26   #6
siargy
Senior Member
 
Аватар для siargy
 
Регистрация: 03.07.2007
Адрес: Минск
Возраст: 39
Сообщений: 868
Вес репутации: 1338/63
siargy has much to be proud ofsiargy has much to be proud ofsiargy has much to be proud ofsiargy has much to be proud ofsiargy has much to be proud ofsiargy has much to be proud ofsiargy has much to be proud ofsiargy has much to be proud ofsiargy has much to be proud ofsiargy has much to be proud of
Exclamation Re: вопрос по DS18B20&PIC16F690

Код:
EEPROM_WRITE(0, setpoint_old);
так, к слову.
гдето раньше обсуждали, что это не здорово - писать постоянно изменяемый параметр в одну и туже ячейку.
__________________
Построил тепличку, посеял литопсы, вырастил кактусы
siargy вне форума   Ответить с цитированием
Старый 20.08.2018, 21:24   #7
GoshaGrek
Senior Member
 
Регистрация: 29.09.2011
Сообщений: 273
Вес репутации: 357/32
GoshaGrek is just really niceGoshaGrek is just really niceGoshaGrek is just really niceGoshaGrek is just really nice
По умолчанию Re: вопрос по DS18B20&PIC16F690

Цитата:
Сообщение от siargy Посмотреть сообщение
Код:
EEPROM_WRITE(0, setpoint_old);
так, к слову.
гдето раньше обсуждали, что это не здорово - писать постоянно изменяемый параметр в одну и туже ячейку.
я тоже помню что обсуждали где то...
просто по даташитам давно не лазил, какой там ресурс eeproma в этой серии процев
в 16F84 был небольшой... Но вроде ж изменились времена
GoshaGrek вне форума   Ответить с цитированием
Старый 20.08.2018, 22:09   #8
GoshaGrek
Senior Member
 
Регистрация: 29.09.2011
Сообщений: 273
Вес репутации: 357/32
GoshaGrek is just really niceGoshaGrek is just really niceGoshaGrek is just really niceGoshaGrek is just really nice
По умолчанию Re: вопрос по DS18B20&PIC16F690

Я ничего не путаю? вроде как минимум миллион циклов...
Миниатюры
Screenshot-4.jpg  
GoshaGrek вне форума   Ответить с цитированием
Старый 20.08.2018, 22:19   #9
DmitrijVDN
Senior Member
 
Регистрация: 09.04.2010
Сообщений: 789
Вес репутации: 1418/53
DmitrijVDN has much to be proud ofDmitrijVDN has much to be proud ofDmitrijVDN has much to be proud ofDmitrijVDN has much to be proud ofDmitrijVDN has much to be proud ofDmitrijVDN has much to be proud ofDmitrijVDN has much to be proud ofDmitrijVDN has much to be proud ofDmitrijVDN has much to be proud ofDmitrijVDN has much to be proud of
По умолчанию Re: вопрос по DS18B20&PIC16F690

Цитата:
Сообщение от GoshaGrek Посмотреть сообщение
Я ничего не путаю? вроде как минимум миллион циклов...
не ничего, главное ссылку4 под таблицей не читать
DmitrijVDN вне форума   Ответить с цитированием
Старый 20.08.2018, 23:06   #10
al.kl
Senior Member
 
Регистрация: 11.10.2011
Возраст: 23
Сообщений: 264
Вес репутации: 750/35
al.kl is a splendid one to beholdal.kl is a splendid one to beholdal.kl is a splendid one to beholdal.kl is a splendid one to beholdal.kl is a splendid one to beholdal.kl is a splendid one to beholdal.kl is a splendid one to behold
Отправить сообщение для al.kl с помощью ICQ
По умолчанию Re: вопрос по DS18B20&PIC16F690

Цитата:
На резет надо запрещать кстати, или нет- кто какого мнения?
На сам импульс сброса не нужно (если он будет увеличен, ничего страшного не произойдёт). На все остальные части, естественно, нужно, ибо они критичны ко времени.
al.kl вне форума   Ответить с цитированием
Старый 20.08.2018, 23:17   #11
GoshaGrek
Senior Member
 
Регистрация: 29.09.2011
Сообщений: 273
Вес репутации: 357/32
GoshaGrek is just really niceGoshaGrek is just really niceGoshaGrek is just really niceGoshaGrek is just really nice
По умолчанию Re: вопрос по DS18B20&PIC16F690

Цитата:
Сообщение от al.kl Посмотреть сообщение
На сам импульс сброса не нужно (если он будет увеличен, ничего страшного не произойдёт). На все остальные части, естественно, нужно, ибо они критичны ко времени.
Спасибо! я так и понял...
короче сделал как в посте #5 - все вроде работает.
И в симуляторе и в железе, правда в железе не гонял долго так как влом ночью то)))
Завтра при свободе попробую

На счет проверки crc пока не врубился зачем оно надо и как его делать.
Но по ходу дойду...
GoshaGrek вне форума   Ответить с цитированием
Старый 20.08.2018, 23:21   #12
GoshaGrek
Senior Member
 
Регистрация: 29.09.2011
Сообщений: 273
Вес репутации: 357/32
GoshaGrek is just really niceGoshaGrek is just really niceGoshaGrek is just really niceGoshaGrek is just really nice
По умолчанию Re: вопрос по DS18B20&PIC16F690

Цитата:
Сообщение от DmitrijVDN Посмотреть сообщение
не ничего, главное ссылку4 под таблицей не читать
и че там противоречивого написано то? Или я в английском не шибко силен, или не до конца въехал... Но там вроде про то речь идет что при слишком частом запись перепись можно и не дожить до 1М циклов, а будет минимум 100к и там же ссылка на таблицу
GoshaGrek вне форума   Ответить с цитированием
Старый 20.08.2018, 23:24   #13
al.kl
Senior Member
 
Регистрация: 11.10.2011
Возраст: 23
Сообщений: 264
Вес репутации: 750/35
al.kl is a splendid one to beholdal.kl is a splendid one to beholdal.kl is a splendid one to beholdal.kl is a splendid one to beholdal.kl is a splendid one to beholdal.kl is a splendid one to beholdal.kl is a splendid one to behold
Отправить сообщение для al.kl с помощью ICQ
По умолчанию Re: вопрос по DS18B20&PIC16F690

Цитата:
На счет проверки crc пока не врубился зачем оно надо
На всякий случай. От неправильного чтения защититься, например при помехах, или длинном проводе.
Тем более, у Вас регулятор, а не обычный градусник-показометр.
al.kl вне форума   Ответить с цитированием
Старый 21.08.2018, 00:08   #14
DmitrijVDN
Senior Member
 
Регистрация: 09.04.2010
Сообщений: 789
Вес репутации: 1418/53
DmitrijVDN has much to be proud ofDmitrijVDN has much to be proud ofDmitrijVDN has much to be proud ofDmitrijVDN has much to be proud ofDmitrijVDN has much to be proud ofDmitrijVDN has much to be proud ofDmitrijVDN has much to be proud ofDmitrijVDN has much to be proud ofDmitrijVDN has much to be proud ofDmitrijVDN has much to be proud of
По умолчанию Re: вопрос по DS18B20&PIC16F690

енто я к тому шо для 84го параметр D120 заявлялся минимум 1М
DmitrijVDN вне форума   Ответить с цитированием
Старый 21.08.2018, 08:10   #15
GoshaGrek
Senior Member
 
Регистрация: 29.09.2011
Сообщений: 273
Вес репутации: 357/32
GoshaGrek is just really niceGoshaGrek is just really niceGoshaGrek is just really niceGoshaGrek is just really nice
По умолчанию Re: вопрос по DS18B20&PIC16F690

Цитата:
Сообщение от DmitrijVDN Посмотреть сообщение
енто я к тому шо для 84го параметр D120 заявлялся минимум 1М
А какой тогда выход то?
В program flash писать? Или менять ячейки?
Я лет 5 назад работал в одной конторе. Где среди прочего делали приборы, в которых использовался PIC16F630 , и по логике работы устройства там каждый день (а все это относилось к автотракторной технике) некоторая информация считывалась переписывалась в eeprom от 5 до 10 раз. При чем сии девайсы выпускались в общей сложности лет 7 в количестве 60-100 в месяц. И за все годы вроде не было отказов, связанных именно с отказом eeprom
Навскидку даже если брать 100К циклов - то это при каждодневной(!!!)эксплуатации и такой вот нагрузке на eeprom это минимум 25 лет....
а если это термометр, который (иногда, возможно) может использоваться как термостат - то там даже 5 раз в сутки на хрен уставку переписывать
То даже при 100К циклах (в худшем случае) и круглосуточной работе это десятки лет , или нет?
GoshaGrek вне форума   Ответить с цитированием
Старый 21.08.2018, 09:23   #16
siargy
Senior Member
 
Аватар для siargy
 
Регистрация: 03.07.2007
Адрес: Минск
Возраст: 39
Сообщений: 868
Вес репутации: 1338/63
siargy has much to be proud ofsiargy has much to be proud ofsiargy has much to be proud ofsiargy has much to be proud ofsiargy has much to be proud ofsiargy has much to be proud ofsiargy has much to be proud ofsiargy has much to be proud ofsiargy has much to be proud ofsiargy has much to be proud of
По умолчанию Re: вопрос по DS18B20&PIC16F690

самый простой метод - писать значение в первую по порядку свободную ячейку, читать первую с конца, при исчерпывании всех доступных ячеек перетирать FF.

я в код не сильно вчитывался. но там при изменении параметра может не один раз переписыватся епром? т.е. несколько раз подряд нажали кнопку и несколько раз подряд перепишется еепром?
__________________
Построил тепличку, посеял литопсы, вырастил кактусы
siargy вне форума   Ответить с цитированием
Старый 21.08.2018, 09:51   #17
Рак
Senior Member
 
Регистрация: 02.04.2008
Адрес: Кременчуг
Возраст: 32
Сообщений: 1,321
Вес репутации: 2246/74
Рак has a reputation beyond reputeРак has a reputation beyond reputeРак has a reputation beyond reputeРак has a reputation beyond reputeРак has a reputation beyond reputeРак has a reputation beyond reputeРак has a reputation beyond reputeРак has a reputation beyond reputeРак has a reputation beyond reputeРак has a reputation beyond reputeРак has a reputation beyond repute
По умолчанию Re: вопрос по DS18B20&PIC16F690

У нас используется одна плата с dsPIC30, где каждые 10 минут записывается значение мото-часов. Как только значение ячейки дошло до 60000, писаться начинает в соседнюю и так дальше на сколько памяти не жалко. При чтении обратная процедура. А на 8000ч по регламенту у нас замена платы
Для надежности запись идет каждые 5 минут, но в 2 разные страницы EEPROM (которые не могут стереться одной коммандой) Ну и плюс контрольная сумма для определения корректного значения при старте.
Для теста в макетной плате время писалось каждыю минуту, за 3 месяца было сделано примерно 130000 перезаписей при ресурсе 100000, то сбоев не было. Долще не гоняли.
Рак вне форума   Ответить с цитированием
Старый 21.08.2018, 15:51   #18
GoshaGrek
Senior Member
 
Регистрация: 29.09.2011
Сообщений: 273
Вес репутации: 357/32
GoshaGrek is just really niceGoshaGrek is just really niceGoshaGrek is just really niceGoshaGrek is just really nice
По умолчанию Re: вопрос по DS18B20&PIC16F690

Цитата:
Сообщение от siargy Посмотреть сообщение
самый простой метод - писать значение в первую по порядку свободную ячейку, читать первую с конца, при исчерпывании всех доступных ячеек перетирать FF.

я в код не сильно вчитывался. но там при изменении параметра может не один раз переписыватся епром? т.е. несколько раз подряд нажали кнопку и несколько раз подряд перепишется еепром?
у меня в коде так сделано - если старое значение не совпадает с новым - то при выходе из меню значение переписывается. Если одинаковое, то никаких переписей нет
вроде как по логике то правильно...

Код:
  // запись значения уставки температуры в EEPROM
        if ((setpoint_old != setpoint)&&(flag_set == 0)) {
            setpoint_old = setpoint;
            EEPROM_WRITE(0, setpoint_old);
GoshaGrek вне форума   Ответить с цитированием
Старый 22.08.2018, 00:28   #19
al.kl
Senior Member
 
Регистрация: 11.10.2011
Возраст: 23
Сообщений: 264
Вес репутации: 750/35
al.kl is a splendid one to beholdal.kl is a splendid one to beholdal.kl is a splendid one to beholdal.kl is a splendid one to beholdal.kl is a splendid one to beholdal.kl is a splendid one to beholdal.kl is a splendid one to behold
Отправить сообщение для al.kl с помощью ICQ
По умолчанию Re: вопрос по DS18B20&PIC16F690

Проще проверить с реальным значением.


Код:
/*********************************************************************/
void EE_Write(unsigned int addr, void* pData, unsigned char size){
    unsigned char *p=(unsigned char *)pData;
    while(size--){
        if(EEPROM_READ(addr+size)!=*p)    EEPROM_WRITE(addr+size, *p);
        p++;
    }
}
/*********************************************************************/



/*********************************************************************/
void EE_Read(unsigned int addr, void* pData, unsigned char size){
    unsigned char *p=(unsigned char *)pData;
    while(size--){
        *p++ = EEPROM_READ(addr+size);
    }
}
/*********************************************************************/
al.kl вне форума   Ответить с цитированием
Старый 22.08.2018, 19:18   #20
GoshaGrek
Senior Member
 
Регистрация: 29.09.2011
Сообщений: 273
Вес репутации: 357/32
GoshaGrek is just really niceGoshaGrek is just really niceGoshaGrek is just really niceGoshaGrek is just really nice
По умолчанию Re: вопрос по DS18B20&PIC16F690

Цитата:
Сообщение от al.kl Посмотреть сообщение
Проще проверить с реальным значением.


Код:
/*********************************************************************/
void EE_Write(unsigned int addr, void* pData, unsigned char size){
    unsigned char *p=(unsigned char *)pData;
    while(size--){
        if(EEPROM_READ(addr+size)!=*p)    EEPROM_WRITE(addr+size, *p);
        p++;
    }
}
/*********************************************************************/



/*********************************************************************/
void EE_Read(unsigned int addr, void* pData, unsigned char size){
    unsigned char *p=(unsigned char *)pData;
    while(size--){
        *p++ = EEPROM_READ(addr+size);
    }
}
/*********************************************************************/
В смысле с реальным? В подобных случаях есть два значения - то что было до изменения , и после.
Если они не совпадают- в eeprom пишется новое значение. При выключении питания устройства оно сохраняется. При включении - считывается....
GoshaGrek вне форума   Ответить с цитированием
Старый 23.08.2018, 10:54   #21
al.kl
Senior Member
 
Регистрация: 11.10.2011
Возраст: 23
Сообщений: 264
Вес репутации: 750/35
al.kl is a splendid one to beholdal.kl is a splendid one to beholdal.kl is a splendid one to beholdal.kl is a splendid one to beholdal.kl is a splendid one to beholdal.kl is a splendid one to beholdal.kl is a splendid one to behold
Отправить сообщение для al.kl с помощью ICQ
По умолчанию Re: вопрос по DS18B20&PIC16F690

Цитата:
Сообщение от GoshaGrek Посмотреть сообщение
В смысле с реальным?
В прямом. С реальным значением, находящемся в ячейки EEPROM.
Прочитали, сравнили, записали (если разные значения).
al.kl вне форума   Ответить с цитированием
Старый 23.08.2018, 11:32   #22
GoshaGrek
Senior Member
 
Регистрация: 29.09.2011
Сообщений: 273
Вес репутации: 357/32
GoshaGrek is just really niceGoshaGrek is just really niceGoshaGrek is just really niceGoshaGrek is just really nice
По умолчанию Re: вопрос по DS18B20&PIC16F690

Цитата:
Сообщение от al.kl Посмотреть сообщение
В прямом. С реальным значением, находящемся в ячейки EEPROM.
Прочитали, сравнили, записали (если разные значения).
ну так так и делается. )
тут еще вот что интересно.
Погонял в железе - с запретом прерываний как в посте 5, все вроде работает, но все равно при резком изменении температуры - например поднес на сантиметр до датчика паяльник, или резко в горячую воду- все равно бывает что выкидывает ложные показания.
Увеличил задержку на конвертацию - от 750мс до 1сек - пропало
тут вот в чем вопрос - по умолчанию в этом девайсе стоит 12 битное преобразование. Так?
А как сделать 9 ? че то пока не пойму. Мне то точность достаточна 1град, дробные части мерять не надо.
По даташиту вроде как на 9 битах наименьшее время измерения
GoshaGrek вне форума   Ответить с цитированием
Старый 28.08.2018, 10:00   #23
siargy
Senior Member
 
Аватар для siargy
 
Регистрация: 03.07.2007
Адрес: Минск
Возраст: 39
Сообщений: 868
Вес репутации: 1338/63
siargy has much to be proud ofsiargy has much to be proud ofsiargy has much to be proud ofsiargy has much to be proud ofsiargy has much to be proud ofsiargy has much to be proud ofsiargy has much to be proud ofsiargy has much to be proud ofsiargy has much to be proud ofsiargy has much to be proud of
По умолчанию Re: вопрос по DS18B20&PIC16F690

Цитата:
Увеличил задержку на конвертацию - от 750мс до 1сек - пропало
там же можно кідать слот проверкі завершенія преобразованія
__________________
Построил тепличку, посеял литопсы, вырастил кактусы
siargy вне форума   Ответить с цитированием
Старый 28.08.2018, 17:21   #24
Ученый
Senior Member
 
Регистрация: 27.02.2007
Адрес: Москва
Возраст: 68
Сообщений: 584
Вес репутации: 1705/65
Ученый has a brilliant futureУченый has a brilliant futureУченый has a brilliant futureУченый has a brilliant futureУченый has a brilliant futureУченый has a brilliant futureУченый has a brilliant futureУченый has a brilliant futureУченый has a brilliant futureУченый has a brilliant futureУченый has a brilliant future
По умолчанию Re: вопрос по DS18B20&PIC16F690

Цитата:
Сообщение от GoshaGrek Посмотреть сообщение
А как сделать 9 ? че то пока не пойму. Мне то точность достаточна 1град, дробные части мерять не надо.
По даташиту вроде как на 9 битах наименьшее время измерения
Записать в Configuration Register значение 00011111.
Команда 0x4E (Write Scratchpad) пишет 3 байта - Thigh, Tlow и ConfigReg.
Стр. 7 и 10 DS.
__________________
Не знать - не стыдно, стыдно не учиться.
Ученый вне форума   Ответить с цитированием
Старый 28.08.2018, 23:11   #25
al.kl
Senior Member
 
Регистрация: 11.10.2011
Возраст: 23
Сообщений: 264
Вес репутации: 750/35
al.kl is a splendid one to beholdal.kl is a splendid one to beholdal.kl is a splendid one to beholdal.kl is a splendid one to beholdal.kl is a splendid one to beholdal.kl is a splendid one to beholdal.kl is a splendid one to behold
Отправить сообщение для al.kl с помощью ICQ
По умолчанию Re: вопрос по DS18B20&PIC16F690

Цитата:
Сообщение от GoshaGrek Посмотреть сообщение
А как сделать 9 ? че то пока не пойму. Мне то точность достаточна 1град, дробные части мерять не надо.
Ну и откиньте тупо их, эти дробные. Программно.
В чём проблема ?
al.kl вне форума   Ответить с цитированием
Ответ


Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 
Опции темы
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Вопрос по ПИД в инерциальной, сильношумящей системе. FlashBack Общетехнические вопросы 4 29.04.2011 17:06
Вопрос по прерываниям RB7-RB4 KSB31 Продукция MICROCHIP 4 15.08.2010 23:53
PIC16F84 TMR0 Вопрос по времени unkn0wn Вопросы начинающих 12 06.10.2008 04:34
Вопрос по Altium Designer Iptash Печатный монтаж 2 14.09.2008 14:57
вопрос по PICC EXT_INT Вопросы начинающих 13 26.08.2008 07:53


Часовой пояс GMT +3, время: 17:22.


Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd. Перевод: zCarot