• AVR Freaks

Hot!PIC12F1572 Shortest Delay Possible & Noise when line is driven low

Page: 12345 > Showing page 1 of 5
Author
momiccioli
Starting Member
  • Total Posts : 44
  • Reward points : 0
  • Joined: 2019/07/18 06:05:48
  • Location: Massachusetts
  • Status: offline
2020/09/27 06:41:36 (permalink)
0

PIC12F1572 Shortest Delay Possible & Noise when line is driven low

I am working on 1-Wire project using a Dallas DS18B20 temp probe.  Which requires some strict polling.  I am able to do this on an Arduino but would prefer not to go in that direction. If I push the PIC12F1572 to 32Mghz I am able to get between 2-3us using a macro.  I was thinking I should be able to get closer to the 1us.  I don't have any timers running since they aren't fast enough for this use.  So is this the best I can squeeze ut of the PIC12F1572 or are there settings I am missing?
 
I am also seeing noise when I drive the line low to send a zero.  I don't have that issue when the line is high because the DS18B20 requires a pull up resistor.  Any thoughts on how best to address that? 
 
I have a simple toggle program that I have been experimenting with.  It started as an MPLABx project file but I consolidated to a single file to simplify experimentation.
 
Any help would be appreciated. thank you.
 
//Generated Main Source File
#pragma config FOSC = INTOSC // ->INTOSC oscillator; I/O function on CLKIN pin
#pragma config WDTE = OFF // Watchdog Timer Enable->WDT disabled
#pragma config PWRTE = OFF // Power-up Timer Enable->PWRT disabled
#pragma config MCLRE = ON // MCLR Pin Function Select->MCLR/VPP pin function is MCLR
#pragma config CP = OFF // Flash Program Memory Code Protection->Program memory code protection is disabled
#pragma config BOREN = ON // Brown-out Reset Enable->Brown-out Reset enabled
#pragma config CLKOUTEN = OFF // Clock Out Enable->CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin

// CONFIG2
#pragma config WRT = OFF // Flash Memory Self-Write Protection->Write protection off
#pragma config PLLEN = OFF // PLL Enable->4x PLL disabled
#pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable->Stack Overflow or Underflow will cause a Reset
#pragma config BORV = LO // Brown-out Reset Voltage Selection->Brown-out Reset Voltage (Vbor), low trip point selected.
#pragma config LPBOREN = OFF // Low Power Brown-out Reset enable bit->LPBOR is disabled
#pragma config LVP = OFF // Low-Voltage Programming Enable->High-voltage on MCLR/VPP must be used for programming

#define INPUT 1
#define OUTPUT 0
#define HIGH 1
#define LOW 0
#define ANALOG 1
#define DIGITAL 0
#define PULL_UP_ENABLED 1
#define PULL_UP_DISABLED 0
#define IO_RA4_TRIS TRISAbits.TRISA4
#define IO_RA4_LAT LATAbits.LATA4
#define IO_RA4_PORT PORTAbits.RA4
#define IO_RA4_WPU WPUAbits.WPUA4
#define IO_RA4_OD ODCONAbits.ODA4
#define IO_RA4_ANS ANSELAbits.ANSA4
#define IO_RA4_SetHigh() do { LATAbits.LATA4 = 1; } while(0)
#define IO_RA4_SetLow() do { LATAbits.LATA4 = 0; } while(0)
#define IO_RA4_Toggle() do { LATAbits.LATA4 = ~LATAbits.LATA4; } while(0)
#define IO_RA4_GetValue() PORTAbits.RA4
#define IO_RA4_SetDigitalInput() do { TRISAbits.TRISA4 = 1; } while(0)
#define IO_RA4_SetDigitalOutput() do { TRISAbits.TRISA4 = 0; } while(0)
#define IO_RA4_SetPullup() do { WPUAbits.WPUA4 = 1; } while(0)
#define IO_RA4_ResetPullup() do { WPUAbits.WPUA4 = 0; } while(0)
#define IO_RA4_SetPushPull() do { ODCONAbits.ODA4 = 0; } while(0)
#define IO_RA4_SetOpenDrain() do { ODCONAbits.ODA4 = 1; } while(0)
#define IO_RA4_SetAnalogMode() do { ANSELAbits.ANSA4 = 1; } while(0)
#define IO_RA4_SetDigitalMode() do { ANSELAbits.ANSA4 = 0; } while(0)
#define _XTAL_FREQ 32000000

#define uSDelay asm("nop")

#include <xc.h>

void SYSTEM_Initialize(void);
void PIN_MANAGER_Initialize (void);
void PIN_MANAGER_IOC(void);
void OSCILLATOR_Initialize(void);
void WDT_Initialize(void);

void main(void) {
    SYSTEM_Initialize();
    TRISAbits.TRISA4 = 0;

    IO_RA4_SetDigitalMode();
    PULL_UP_ENABLED;
    while (1)
    {
        // Add your application code
        IO_RA4_Toggle();
        for(int x=0;x<100; x++) {uSDelay;}
    }
}

void SYSTEM_Initialize(void) {
    PIN_MANAGER_Initialize();
    OSCILLATOR_Initialize();
    WDT_Initialize();
}

void PIN_MANAGER_Initialize(void) {
    LATA = 0x00;
    TRISA = 0x2F;
    ANSELA = 0; //0x17;
    WPUA = 0x00;
    OPTION_REGbits.nWPUEN = 1;
    ODCONA = 0x00;
    SLRCONA = 0x37;
    INLVLA = 0x3F;
    APFCON = 0x00;
}

void OSCILLATOR_Initialize(void){
    // SCS FOSC; SPLLEN disabled; IRCF 16MHz_HF;
    //OSCCON = 0x78;
    OSCCON = 0b11110000;
    // TUN 0;
    OSCTUNE = 0x00;
    // SBOREN disabled; BORFS disabled;
    BORCON = 0x00;
}

void WDT_Initialize(void){
   // WDTPS 1:65536; SWDTEN OFF;
    //WDTCON = 0x16;
    WDTCON = 0b00010110;
}

post edited by momiccioli - 2020/09/27 06:42:47
#1

99 Replies Related Threads

    Mysil
    Super Member
    • Total Posts : 3809
    • Reward points : 0
    • Joined: 2012/07/01 04:19:50
    • Location: Norway
    • Status: offline
    Re: PIC12F1572 Shortest Delay Possible & Noise when line is driven low 2020/09/27 07:45:02 (permalink)
    +1 (1)
    Hi,
    When a PIC16 is running with 32 MHz clock,
    then instruction cycle is 8 MHz, making one NOP instruction taking 1/8 microsecond,
    so the shortest delay you may insert into code will be that.
    The compiler have a builtin macro for that:     NOP();
    I have not looked into how many instruction cycles  IO_RA4_Toggle(); will need, 
    IO_RA4_SetHigh();     and IO_RA4_SetLow();  should both be possible in 1 instruction cycle each.
    The jump back of a:    while(1) {...}    loop will use 2 instruction cycles.
     
    You should be able to make approximate 1 MHz square wave output in a while loop without any delay macro, 
    then fill in with    NOP();   macros to delay for the timing you want.
     
    About noise on a Output pin transition:
    In my understanding, noise: undershoot, overshoot or similar, is not caused by the CMOS output driving the pin,
    instead may be caused by the transmission line connected to the pin, that is your wiring connecting the microcontroller to temperature sensor.
     
    Now, the Output drive transistors have some internal resistance, typically in the range between 50 to 100 ohm,
    and the wiring of your assembly have some capacitance, so there will be a limitation what rise time can be achieved.
     
    When studying signal shape with oscilloscope, then an additional transmission line is introduced,
    with additional capacitance.
    Make sure that your oscilloscope probe is trimmed correctly, or you may see strange effects that have nothing to do with your microcontroller and temperature sensor.
     
        Mysil
     
     
    #2
    momiccioli
    Starting Member
    • Total Posts : 44
    • Reward points : 0
    • Joined: 2019/07/18 06:05:48
    • Location: Massachusetts
    • Status: offline
    Re: PIC12F1572 Shortest Delay Possible & Noise when line is driven low 2020/09/27 08:33:32 (permalink)
    0
    So the NOP(); made a difference just using the toggle at 32Mhz I get 1.5us square wave.  At 16Mhz I get about 3.3us so double the duration which makes sense.
     
    while (1) {
       // Add your application code
       IO_RA4_Toggle();
       NOP();
    }


     
    If I call a Delay subroutine after the toggle Delay(10); It averages out to be about 2.6us.  and 5.6 at 16Mhz. 
    void Delay(int x) {
       for(x; x>0; x--) { NOP();}
    }
     
    The duration at 32Mhz is likely to be fast enough I expected to do much better especially at 32Mhz.  So now I have to ask how is an Arduino processor able to get a 1us delay?  Or is it really?  I have not put it on the scope but now I might have to.
     
    Thoughts?
     
     
    As for the noise I moved a wire on my bread board and it cleaned up significantly back to where I would expect for a bread board.
    #3
    upand_at_them
    Super Member
    • Total Posts : 681
    • Reward points : 0
    • Joined: 2005/05/16 07:02:38
    • Location: Pennsylvania
    • Status: offline
    Re: PIC12F1572 Shortest Delay Possible & Noise when line is driven low 2020/09/27 08:49:11 (permalink)
    0
    You're trying to poll the DS18B20 every 1us?  Did you read the datasheet parts mentioning "Conversion Time"?
    #4
    upand_at_them
    Super Member
    • Total Posts : 681
    • Reward points : 0
    • Joined: 2005/05/16 07:02:38
    • Location: Pennsylvania
    • Status: offline
    Re: PIC12F1572 Shortest Delay Possible & Noise when line is driven low 2020/09/27 08:53:53 (permalink)
    0
    If you need to read/write as fast as possible you need to be doing this in assembly.
     
    #5
    momiccioli
    Starting Member
    • Total Posts : 44
    • Reward points : 0
    • Joined: 2019/07/18 06:05:48
    • Location: Massachusetts
    • Status: offline
    Re: PIC12F1572 Shortest Delay Possible & Noise when line is driven low 2020/09/27 09:01:48 (permalink)
    -1 (1)
    I did read it and there are a few places where the data sheet indicated 1us recovery.  I am thinking that is an absolute minimum and if I am under 5us I should be fine.  I became perplexed that I was having a hard time getting there on the PIC12F1572.  I realize the chip is a low budget MCU I guess I over estimated it's capabilities?.  
     
    I did put an ATMEGA 328 on the scope and hit 1us delay on the first try.  So what's the major difference between that and the PIC12F1572 that makes it more of a challenge?  I do have a PIC16F167323 that I will give a run too.
    #6
    momiccioli
    Starting Member
    • Total Posts : 44
    • Reward points : 0
    • Joined: 2019/07/18 06:05:48
    • Location: Massachusetts
    • Status: offline
    Re: PIC12F1572 Shortest Delay Possible & Noise when line is driven low 2020/09/27 09:03:47 (permalink)
    0
    I don't know assembler well and I was hoping this would be simple enough I didn't need to do that.  I am rethinking that too?
     
    #7
    upand_at_them
    Super Member
    • Total Posts : 681
    • Reward points : 0
    • Joined: 2005/05/16 07:02:38
    • Location: Pennsylvania
    • Status: offline
    Re: PIC12F1572 Shortest Delay Possible & Noise when line is driven low 2020/09/27 09:23:43 (permalink)
    +2 (2)
    Why do you have the 1us requirement?  Can't you just use DS18B20 libraries and read every second?
    #8
    momiccioli
    Starting Member
    • Total Posts : 44
    • Reward points : 0
    • Joined: 2019/07/18 06:05:48
    • Location: Massachusetts
    • Status: offline
    Re: PIC12F1572 Shortest Delay Possible & Noise when line is driven low 2020/09/27 10:01:55 (permalink)
    0
    Well that's the easy way out and I could do that but it's more fun this way.  I want to learn more about developing on these MCUs and this looked like a straight forward challange.  I did notice in one lib that I saw the perocessor is running at 32Mhz and it just uses the standard __delay_us(); call.
    #9
    Mysil
    Super Member
    • Total Posts : 3809
    • Reward points : 0
    • Joined: 2012/07/01 04:19:50
    • Location: Norway
    • Status: offline
    Re: PIC12F1572 Shortest Delay Possible & Noise when line is driven low 2020/09/27 10:10:12 (permalink)
    0
    Hi,
    Loop control for a:     while(1);      loop, will take 2 instruction cycles for each iteration. 
    You may experiment with unrolling the loop further,  something like: 
        while (1)
        {   LATAbits.LATA4 = 1;
            LATAbits.LATA4 = 0;
            LATAbits.LATA4 = 1;
            LATAbits.LATA4 = 0;
        }

    With or without NOP(); instructions for delay in between.
     
    With XC8 compiler, there are options for optimization level 0, 1 or 2 available with the free license. 
    See 'Project Properties'  XC8 compiler settings in MPLAB X.
    Compiler may insert bank selection instructions between instructions generated from C statements.
    These will not be needed inside the loop, as long as only the same SFR register is accessed.
     
    You may look at assembly code generated by the compiler in listing report file.
     
        Mysil
    post edited by Mysil - 2020/09/27 12:36:27
    #10
    visenri
    Starting Member
    • Total Posts : 16
    • Reward points : 0
    • Joined: 2017/10/25 15:30:29
    • Location: 0
    • Status: offline
    Re: PIC12F1572 Shortest Delay Possible & Noise when line is driven low 2020/09/27 11:39:08 (permalink)
    +1 (1)
    First of all, I think there is no need for such a high precision timing for the DS18B20, the 1us timing is the absolute minimum that must be met, but it is never a good idea to use the limit value.
     
    Anyway, to get closer to bare-metal control easily without going into assembler, you can use built in functions (XC8) like __delay_us or_delay.
    You may also want to get rid of MCC HAL (IO_RA4_XXX), because those may take extra time (From my testing they do not, but it's a good idea to go as low level as possible if you want precise timing).
     
    For example:
     #define _XTAL_FREQ 32000000UL // must be defined somewhere

    LATAbits.LATA4 = 0;
    __delay_us(1);
    LATAbits.LATA4 = 1;

    will result in this machine code:
    movlb 0x2
    bcf porta, 0x4
    nop2
    nop2
    nop2
    nop2
    movlb 0x2
    bcf porta, 0x4

    You'll get a 1.25us low pulse (10 instruction cycles @32Mhz).
     
    If you want to control it precisely in cycles, using _delay will get you closer, because you can compensate the time taken to write to the port:
     LATAbits.LATA4 = 0;
    _delay(6);
    LATAbits.LATA4 = 1;

    translates into:
    movlb 0x2
    bcf porta, 0x4
    nop2
    nop2
    nop2
    movlb 0x2
    bcf porta, 0x4

    Giving exactly a 1us pulse (8 instruction cycles @32Mhz).
     
    The first method is the one I would use for this kind of application, because, timing specification is not so critical, and it will work no matter what frequency you use (provided it is high enough).
     
    The second method creates delays that are specified in cycles, so you can tune the delay to get exactly what you want, but will give you different times at different core frequencies.
     
    You can also use method 2 but calculate (with macros) the total number of cycles using _XTAL_FREQ and subtracting the cycles to do the port write, loop or anything else (and making sure those results are not negative). You'll get a more frequency independent version with higher control/precision.
     
     
    #11
    1and0
    Access is Denied
    • Total Posts : 11340
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: PIC12F1572 Shortest Delay Possible & Noise when line is driven low 2020/09/27 11:51:50 (permalink)
    +2 (2)
    Mysil
    I have not looked into how many instruction cycles  IO_RA4_Toggle(); will need, 

    momiccioli
    So the NOP(); made a difference just using the toggle at 32Mhz I get 1.5us square wave.  At 16Mhz I get about 3.3us so double the duration which makes sense.
     
    while (1) {
     // Add your application code
     IO_RA4_Toggle();
     NOP();
    }

    1.5 us at Fosc = 32 MHz is 12 instruction cycles.  That is one STUPID compiler!!! ;) 
     
    A loop to toggle a bit takes three (3) instruction cycles -- one to toggle the bit and two to branch, like this:
        asm("movlw 1 << 4");
        asm("banksel LATA");
        while (1) {
            asm("xorwf LATA");
        }

    post edited by 1and0 - 2020/09/27 11:53:36
    #12
    momiccioli
    Starting Member
    • Total Posts : 44
    • Reward points : 0
    • Joined: 2019/07/18 06:05:48
    • Location: Massachusetts
    • Status: offline
    Re: PIC12F1572 Shortest Delay Possible & Noise when line is driven low 2020/09/27 12:05:05 (permalink)
    0
    This is extremely useful it's giving more insight to the chip which is the reason I am doing it without libs.  I will play with these options.  As I get to the desired speed I will strip down all the unneeded code.
     
    Thank you for the hints I will post progress. 
    #13
    NorthGuy
    Super Member
    • Total Posts : 6350
    • Reward points : 0
    • Joined: 2014/02/23 14:23:23
    • Location: Northern Canada
    • Status: offline
    Re: PIC12F1572 Shortest Delay Possible & Noise when line is driven low 2020/09/27 12:54:31 (permalink)
    +3 (3)
    I read the datasheet and the conversion time is tCONV parameter is 750 ms (for 12-bit resolution) which is 750000 times longer than 1 us.
     
    For the communication protocol, there are time slots - a slot per bit. The duration of the time slot is between 60 and 120 us, which is also much longer than 1 us - tSLOT parameter. This means you will need about 8 ms (8000 us) just to read the temperature.
     
    DS18B20 is a very slow device.
     
    Even if you had to go to 1 us pulses (which the PIC certainly can do), your tests measure mostly the looping time, which has absolutely no relation to how precise you can bit-bang the pulses.
     
    #14
    upand_at_them
    Super Member
    • Total Posts : 681
    • Reward points : 0
    • Joined: 2005/05/16 07:02:38
    • Location: Pennsylvania
    • Status: offline
    Re: PIC12F1572 Shortest Delay Possible & Noise when line is driven low 2020/09/27 13:16:01 (permalink)
    +2 (2)
    NorthGuy
    I read the datasheet and the conversion time is tCONV parameter is 750 ms (for 12-bit resolution) which is 750000 times longer than 1 us.

     
    That's what I thought, too.  And then I reasoned that he must be doing something else with that 1us since he still hasn't fully described his task.
    #15
    ric
    Super Member
    • Total Posts : 28677
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: PIC12F1572 Shortest Delay Possible & Noise when line is driven low 2020/09/27 13:24:16 (permalink)
    +1 (1)
    momiccioli
    I am also seeing noise when I drive the line low to send a zero.  I don't have that issue when the line is high because the DS18B20 requires a pull up resistor.  Any thoughts on how best to address that? 

    Can you show a photo, or describe this "noise" a bit better?
    I suspect (as have others), that it is actually ringing on the transmission line.
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #16
    visenri
    Starting Member
    • Total Posts : 16
    • Reward points : 0
    • Joined: 2017/10/25 15:30:29
    • Location: 0
    • Status: offline
    Re: PIC12F1572 Shortest Delay Possible & Noise when line is driven low 2020/09/27 15:01:59 (permalink)
    0
    upand_at_them
    NorthGuy
    I read the datasheet and the conversion time is tCONV parameter is 750 ms (for 12-bit resolution) which is 750000 times longer than 1 us.

     
    That's what I thought, too.  And then I reasoned that he must be doing something else with that 1us since he still hasn't fully described his task.




    I'm no expert in the 1 wire protocol, but from what I've seen in the datasheet, the 1us is the minimum pulse required to start a read/write time slot, and, for read, it must be released "quickly" because the device will deliver data that must be read before 15us from the falling edge, 10us should be a good point to sample.
     
    datasheet
    Output data from the DS18B20 is valid for 15µs after the falling edge that initiated the read time slot. Therefore, the master must release the bus and then sample the bus state within 15µs from the start of the slot

    #17
    NorthGuy
    Super Member
    • Total Posts : 6350
    • Reward points : 0
    • Joined: 2014/02/23 14:23:23
    • Location: Northern Canada
    • Status: offline
    Re: PIC12F1572 Shortest Delay Possible & Noise when line is driven low 2020/09/27 16:48:07 (permalink)
    +4 (4)
    visenri
    I'm no expert in the 1 wire protocol, but from what I've seen in the datasheet, the 1us is the minimum pulse required to start a read/write time slot, and, for read, it must be released "quickly" because the device will deliver data that must be read before 15us from the falling edge, 10us should be a good point to sample.



    1 us is the minimum. This means that you must keep the line low for at least 1 us. Then you can release it, wait enough time for the pull-ups to pull the line high. Then you sample it. The whole operation must take no more than 15 us, but may take less if you wish, for example 3 us is ok. Then you do nothing for the rest of the slot. Thus, the margin is huge. Therefore you don't need 1 us precision, nor do you need something very quick. It's the opposite. your code will need delays.
    #18
    momiccioli
    Starting Member
    • Total Posts : 44
    • Reward points : 0
    • Joined: 2019/07/18 06:05:48
    • Location: Massachusetts
    • Status: offline
    Re: PIC12F1572 Shortest Delay Possible & Noise when line is driven low 2020/09/28 05:04:03 (permalink)
    0
    As Visenri has stated the recovery time is 1us (minimum).  Other timings required in various places are 5-6, 15, 60us and higher.  The reset is by far the easiest, what I found is that running at 4Mhz, I could not delay properly assuming that at 4Mhz (1Mhz C Instructions) I should be ok.  To my surprise, 4Mhz is not fast enough.
     
    So the loop exercise was purely to measure that the chip can produce 1us square wave which became difficult until I increased the speed to 32Mhz.  With a simple while loop I get a solid square wave with 2.7us period.  Which translates to 1.35us and consider the line of code required that looks correct and close enough. 
     

     
    while (1) {
        LATAbits.LATA4 = 0;
        __delay_us(1);
        LATAbits.LATA4 = 1;
        __delay_us(1);
    }
     
     
    I agree the loop has little do with reading the DS18B20.  I just needed to verify what I can get for a delay so I can code properly.  At one point I was having a hard time producing a 100us delay.  At that rate I would not be able to reliably read the sensor.
     
    My expectation was that I could do this at slower speeds.  An ATMEL 328p (Barebones Arduino) can do this at 16Mhz. However, I have to go to 32Mhgz on the PIC.  Why the difference, I am curious I gathered some of that from the information posted above but still not clear on that one.
     
    As for the DS18B20 I already have a working module on an Arduino with a 4 digit 7 segment LED.  I wanted to try this same exercise with the PIC, two shift registers and a 4 digit 7 segment LED.  I have the shift registers and LED working fine.  That was easy compared to the DS18B20.
     
    I made significant progress from last night; After doing a reset and then a ROM Search I am able to get the 64 bit identifier from a single DS18B20.  See the code below.  My next step will be to add some masking logic so I can identify multiple probes.  The info provided yesterday especially from Mysil has gotten me past my sticking point.
     
    As for the noise info I will post a little later today my scope is not connected to my laptop but I will get some examples to you.  
    Here is the code as it stands now, a little messy but I will tighten it up and comment better.  At one point I though the defines I was using was causing me issues for OW_HIGH and OW_LOW but since the speed improvements It does not seem to be an issue.
     
    Thoughts?

     
    //------------------------------------------------------------------------------
    // Discover
    // 28:36:CD:DB:39:20:1:D5: ROM 00010100 01101100 10110011 11011011 10011100 00000100 10000000 10101011
    // 28:60:36:CE:39:20:1:26: ROM 00010100 00000110 01101100 01110011 10011100 00000100 10000000 01100100
    //------------------------------------------------------------------------------
    void Discover(void){
        presant = 0;
        if (DSB_Reset() == 0){
            DSB_SendROM(0xF0);
            for (int i=0; i<64; i++){
                s1 = DSB_Read();
                s2 = DSB_Read();
                DSB_Write(s1);
                owb[i] = s1;
            }
        }
    }

    //-------------------------------------------------------------------------------------------------------------------------------
    // Reset the devices this is needed to reset all the devices or cancel a transaction.
    //-------------------------------------------------------------------------------------------------------------------------------
    unsigned char DSB_Reset(void){
        unsigned char x=2;
        OW_LOW;
        __delay_us(480);
        OW_HIGH;
        __delay_us(60);

        x = OW_READ;
        __delay_us(410);

        return x;
    }

    //-------------------------------------------------------------------------------------------------------------------------------
    //Search routine Read
    //-------------------------------------------------------------------------------------------------------------------------------
    unsigned char DSB_Read(void){
        unsigned char result;   
        OW_LOW;
        __delay_us(1);
        OW_HIGH;
        __delay_us(5);
        result = OW_READ;
        __delay_us(54);
        return result;
    }

    //-------------------------------------------------------------------------------------------------------------------------------
    //Search routine Write
    //-------------------------------------------------------------------------------------------------------------------------------
    void DSB_Write(unsigned char val){

        TRISAbits.TRISA4 = 0; // Output
        LATAbits.LATA4 = 0;
     
        if (val){
            //writing a bit '1'
            __delay_us(6); // delay 6 microsecond (us)
            LATAbits.LATA4 = 1; // Release the bus
            __delay_us(64); // delay 64 microsecond (us)
                                                      
        } else {
            //writing a bit '0'
            __delay_us(60); // delay 60 microsecond (us)
            LATAbits.LATA4 = 1; // Release the bus
            __delay_us(10); // delay 10 microsecond for recovery (us)
        }
        TRISAbits.TRISA4 = 1; // Output

    }

    //-------------------------------------------------------------------------------------------------------------------------------
    // Sends a ROM command to the devices.
    //-------------------------------------------------------------------------------------------------------------------------------
    void DSB_SendROM(unsigned char command){
        command = 0xF0; // hard coded for testing
        
        TRISAbits.TRISA4 = 0; // Output
        for(int i=0; i<8; i++){ // 8 bits per byte, loop 8 times, least significant bit
             LATAbits.LATA4 = 0; // go LOW to start a transmission
            __delay_us(1);

            if( (command >> i) & 1) {
                LATAbits.LATA4 = 1; // if the bit is a '1' the line will need to go back to HIGH
                __delay_us(59); // wait 60us, so the DS18B20 gets a read of HIGH or 1
            } else { // if the bit was a '0' the line will need to stay LOW fo 60us //go LOW to start a transmission
                __delay_us(59); // wait 60us, so the DS18B20 gets a read of LOW or 0
                LATAbits.LATA4 = 1;
            }
        }
        TRISAbits.TRISA4 = 1; // Return to input for reads.
    }

    post edited by momiccioli - 2020/09/28 05:13:54
    #19
    NorthGuy
    Super Member
    • Total Posts : 6350
    • Reward points : 0
    • Joined: 2014/02/23 14:23:23
    • Location: Northern Canada
    • Status: offline
    Re: PIC12F1572 Shortest Delay Possible & Noise when line is driven low 2020/09/28 06:14:44 (permalink)
    +3 (3)
    At 4 MHz Fosc (1 MHz Fcy), you get one instruction per 1 us, so if you want 1 us between pin changes, you don't need a delay (I would still use NOP() between changes). Clearly, if you engage in lengthy computations between the changes (such as "command >> i" on a CPU without barrel shifter), it will take many instruction and will extend your delay beyond specs. Still, you would get away with this if you did it during 59 us delay, not on your critical path.
     
    You probably can communicate with DS18B20 with oscillator as slow as 600 kHz Fosc, but the slower your clock, the harder you need to work to meet timing. And vise versa, if you get a fast CPU (such as PIC32MZ with 200 MHz Fcy), you will be able to bloat your code even more. That's why people like fast CPUs :)
    #20
    Page: 12345 > Showing page 1 of 5
    Jump to:
    © 2020 APG vNext Commercial Version 4.5