Terry Richards / FP_1WThermometer

Files at this revision

API Documentation at this revision

Comitter:
trichards1138
Date:
Fri May 30 18:31:15 2014 +0000
Commit message:
Final code for One Wire Thermometer MBED control program not using MBED library

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
owInterface.h Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r 8b2fe06d6a2e main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Fri May 30 18:31:15 2014 +0000
@@ -0,0 +1,228 @@
+#include "owInterface.h"
+#include <stdio.h>
+
+unsigned char write_data[3];
+unsigned char address[8];
+int searchJunction;        // so we can set to it -1 somewhere
+
+int owReset() 
+{
+    int result = 0;    // sample presence pulse result
+    clr_owPin();
+    delay_us(480);
+    set_owPin();
+    read_owPin();   //just to set direction
+    delay_us(70);
+    result = read_owPin();
+    delay_us(410);   
+    return result;
+}
+
+void writeBit(int bit)
+{
+    bit = bit & 0x01;
+    
+    if (bit)
+    {
+        // Write '1' bit
+        clr_owPin();
+        delay_us(6);
+        set_owPin();
+        read_owPin();
+        delay_us(64);
+    }
+    else
+    {
+        // Write '0' bit
+        clr_owPin();
+        delay_us(60);
+        set_owPin();
+        read_owPin();
+        delay_us(10);
+    }
+}
+//
+// Read a bit. Port and bit is used to cut lookup time and provide
+// more certain timing.
+//
+int readBit() 
+{
+    int result;    
+    clr_owPin();
+    delay_us(6);
+    set_owPin();
+    read_owPin();
+    delay_us(9);
+    if( read_owPin() )
+        result = 1;
+    else
+        result = 0;
+    result = read_owPin();
+    delay_us(55);
+       
+    return result;
+}
+
+//
+// Write a byte. The writing code uses the active drivers to raise the
+// pin high, if you need power after the write (e.g. DS18S20 in
+// parasite power mode) then set 'power' to 1, otherwise the pin will
+// go tri-state at the end of the write to avoid heating in a short or
+// other mishap.
+//
+void ow_writeByte(int data) 
+{
+    // Loop to write each bit in the byte, LS-bit first
+    for (int loop = 0; loop < 8; loop++)
+    {
+        writeBit(data & 0x01);
+        
+        // shift the data byte for the next bit
+        data >>= 1;
+    }
+}
+
+//
+// Read a byte
+//
+int ow_readByte() 
+{
+    int result = 0;
+    
+    for (int loop = 0; loop < 8; loop++)
+    {
+        // shift the result to get it ready for the next bit
+        result >>= 1;
+        
+        // if result is one, then set MS bit
+        if (readBit()) result |= 0x80;
+    }
+    
+    return result;
+}
+
+void resetAndSelectRom(void)
+{
+    if( owReset() )
+        printf("DS18D20 device not present\r\n");
+    else {
+        ow_writeByte( 0xCC );   //Only dealing with one
+    }   //device, so use "SkipROM" command
+}
+
+void Get_Temp(void)
+{
+    unsigned char data[10];
+    bool signBit = false;
+    resetAndSelectRom();    //
+    ow_writeByte( 0x44 );   //Convert
+    while( !read_owPin() )
+        delay_us(1000*5);  //delay 5 Millisec
+    resetAndSelectRom();
+    ow_writeByte( 0xBE );   //read scratchpad
+ //   printf("read = ");
+    for (int i = 0; i < 9; i++) 
+    {               
+        // we need all bytes which includes CRC check byte
+        data[i] = ow_readByte();
+ //       printf("%x ", (int)data[i]);
+    }
+ //   printf("\r\n");
+       
+    if (data[1] & 0x80) signBit = true;
+        
+    int read_temp = (data[1] << 8) + data[0];
+    if (signBit)
+    {
+        read_temp = (read_temp ^ 0xFFFF) + 1;    // two's complement
+        read_temp *= -1;
+    }
+    
+    int resolution = (data[4] & 0x60) >> 5; // mask off bits 6,5 and move to 1,0
+    switch (resolution)
+    {
+        case 0:    // 0.5 deg C increments
+            read_temp &= 0xFFF8;                // bits 2,1,0 are undefined
+            printf("9 bit resolution ...\r\n");
+            break;
+        case 1:     // 0.25 deg C increments
+            read_temp &= 0xFFFC;                // bits 1,0 are undefined
+            printf("10 bit resolution ...\r\n");
+            break;
+        case 2:  // 0.125 deg C increments
+            read_temp &= 0xFFFE;                // bit 0 is undefined
+            printf("11 bit resolution ...\r\n");
+            break;
+        case 3:  // 0.0625 deg C increments
+            printf("12 bit resolution ...\r\n");
+            break;
+    }
+    float realTemp = (float)read_temp/16 ;
+    float realTempF = ((realTemp * 9) / 5) + 32;
+                 
+    printf("Temperature in deg C: %f \r\n", realTemp); 
+    printf("Temperature in deg F: %f \r\n", realTempF);
+}     
+    
+void set_Resolution(int res)
+{
+    // as the write to the configuration register involves a write to the
+    // high and low alarm bytes, need to read these registers first
+    // and copy them back on the write
+    
+    unsigned char read_data[9];
+    resetAndSelectRom();
+    ow_writeByte( 0xBE );   //read scratchpad
+   // pc.printf("read = ");
+    for (int i = 0; i < 9; i++) 
+    {               
+        // we need all bytes which includes CRC check byte
+        read_data[i] = ow_readByte();   //Get the 8-bytes +CRC
+    //    pc.printf("%x ", (int)read_data[i]);
+    }
+   // pc.printf("\r\n");
+    
+    // copy alarm and config data to write data
+    for (int k = 2; k < 5; k++)
+    {
+        write_data[k - 2] = read_data[k];
+    }
+    int config = write_data[2]; //Get current config
+    config &= 0x9F;     //Isolate the resolution bits
+    config ^= (res << 5);   //Set the new ones
+    write_data[2] = config; //write it in the array to send
+    
+    resetAndSelectRom();
+    ow_writeByte( 0x4E );   //write scratchpad
+    for (int k = 0; k < 3; k++)
+    {
+       ow_writeByte(write_data[k]); //Write back out the 
+    }                           //first three bytes to set Resol
+    owReset();      //reset to end transaction early
+}
+
+int get_res(void)
+{
+    int choice=0;
+    printf("Resolution choices are: 9-bit=0, 10-bit=1, 11-bit=2, 12-bit=3\r\n"); 
+    printf("What resolution would you like (0,1,2,3):\r\n");
+    choice = getchar() - 48;  //get input char and turn it into an int
+    if( (choice >= 0) && (choice < 4) )  //is it within scope?
+        return choice;  //yes, return it
+    else {
+        printf("Invalid Selection:  I've selected 12-bit for you\r\n");
+        return 3;       //no, return default (12-bit)
+    }
+}
+
+int main(void)
+{
+    read_owPin();   //set direction input
+    init_timer();   //set up timer for 1us tick
+    set_Resolution(get_res());  //12-bit
+     while( 1 ) {
+        Get_Temp();     //Go get the temp
+        delay_us(1000*5000);    //Wait 5 sec before 
+    }                           //repeating
+}
+
diff -r 000000000000 -r 8b2fe06d6a2e owInterface.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/owInterface.h	Fri May 30 18:31:15 2014 +0000
@@ -0,0 +1,70 @@
+
+#ifndef __owInterface_h
+#define __owInterface_h
+
+//For testing the One-Wire (OW) ports below
+//#define OWPORT  1     //test port (LED)
+//#define OWPIN   20
+
+//Selects the direction and pin for the main One Wire input/output
+#define OWFIOPIN (*(volatile unsigned int *)(0x2009C000 | ((OWPORT*0x20)+0x10) | 4 ))
+#define OWFIODIR (*(volatile unsigned int *)(0x2009C000 | (OWPORT*0x20)))
+//Provides a test pin near the OW to test the OW output
+#define TESTFIOPIN (*(volatile unsigned int *)(0x2009C000 | ((TESTPRT*0x20)+0x10) | 4 ))
+#define TESTFIODIR (*(volatile unsigned int *)(0x2009C000 | (TESTPRT*0x20)))
+
+//MBED pin 25 resolves to port 2 pin 1
+#define OWPORT  2
+#define OWPIN   1
+//MBED pin 26 is near 25 for testing
+#define TESTPRT 2
+#define TESTPIN 0
+
+//Set the selected Pin to one
+void __inline__ set_owPin(void)
+{
+    OWFIODIR |= 1 << OWPIN;   //Set pin direction to output
+    OWFIOPIN |= 1 << OWPIN;   //Set pin state (1)
+}
+//Set the selected pin to zero
+void __inline__ clr_owPin(void)
+{
+    OWFIODIR |= 1 << OWPIN;   //Set pin direction to output
+    OWFIOPIN &= ~(1 << OWPIN);//Clear pin state (0)
+}
+//Reads the pin, but also sets direction to input
+int __inline__ read_owPin(void)
+{
+    OWFIODIR &= ~(1<<OWPIN);  //Set pin direction to input
+    return ((OWFIOPIN>>OWPIN)&0x1);   //Return the pin state
+}
+//Test pin to see the write bits on the OW
+int __inline__ read_testPin(void)
+{
+    TESTFIODIR &= ~(1<<TESTPIN);
+    return ((TESTFIOPIN>>TESTPIN)&0x1);
+}
+//Timer control registers
+#define TIMER3_TCR  (*(volatile unsigned int *)(0x40094004))
+#define TIMER3_TC   (*(volatile unsigned int *)(0x40094008))
+#define TIMER3_PR   (*(volatile unsigned int *)(0x4009400C))
+#define TIMER3_CTCR (*(volatile unsigned int *)(0x40094070))
+#define PWRCTL_PCONP (*(volatile unsigned int *)(0x400FC0C4))
+#define SYS_CLK     96000000
+
+void init_timer(void)
+{
+   PWRCTL_PCONP |= 1<<23;   //Power up timer3
+   TIMER3_CTCR = 0;         //set to timer (not counter)
+   TIMER3_TCR = 0x2;        //Put timer in reset
+   TIMER3_PR = ((SYS_CLK / 4000000) - 1); //One us per tick
+   TIMER3_TCR = 0x1;        //enable timer
+}
+//Delay for "dly_us" us (microSeconds)
+void __inline__ delay_us(unsigned int dly_us)
+{
+    unsigned int startt = TIMER3_TC;
+    while ((TIMER3_TC-startt) < dly_us) ;
+}
+
+#endif
\ No newline at end of file