⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ds1821_1.c

📁 PIC HiTech_C_Mike_Pearces_DS1821_thermostatwith Dallas DS1821 Programmer and schematic. Tested on P
💻 C
字号:
//************************************************************************
//                        DS1821_1.C
//                          V1.00
//  Programmer for configuring the Dallas DS1821 Thermostat devices
//  Hardware consists of a LCD driven by a PCF8577P I2C Driver, two push
//  Button switches (Select and Change), a couple of transistors for 
//  selecting the power supply mode for the DS1821, a socket to accept
//  a ds1821 directly on the board, an external connector for flying leads,
//  a battery and voltage regulator, a few misc resistors, caps, etc and 
//  a PIC12C509 to control the whole thing.
//
// Author: Michael Pearce
//       Chemistry Department, University of Canterbury.
//
// Started: 28 May 1999
//
//************************************************************************
//                       VERSION INFORMATION
//************************************************************************
// Version 1.00 - 28 May 1999
//   Start of the project.
//************************************************************************

#include <pic.h>

#define MAXTEMPERATURE  120
#define MINTEMPERATURE   55

#define LCD_KEYPAD            //-- If using on the LCDKEYPAD Board

#define	XTAL_FREQ	8MHZ

#define BITNUM(adr, bit)       ((unsigned)(&adr)*8+(bit))

#ifdef LCD_KEYPAD
 #define PORT PORTD
 #define TRIS TRISD
#else
 #ifdef _16C64
  #define PORT PORTB
  #define TRIS TRISB
 #endif
#endif


//************ DEFINE OTHER I/O PORTS ****************
// SCL    = PORTB/GPIO 0
// SDA    = PORTB/GPIO 1
// SW1    = PORTB/GPIO 2
// SW2    = PORTB/GPIO 3
// selpwr = PORTB/GPIO 4
// 1wire  = PORTB/GPIO 5

#ifdef _12C50x
 static bit SCL      @ BITNUM(GPIO,0);
 static bit SCL_TRIS @ BITNUM(TRIS,0);
 static bit SDA      @ BITNUM(GPIO,1);
 static bit SDA_TRIS @ BITNUM(TRIS,1);
 static bit SW1      @ BITNUM(GPIO,2);
 static bit SW1_DIR  @ BITNUM(TRIS,2);
 static bit SW2      @ BITNUM(GPIO,3);
 static bit SW2_DIR  @ BITNUM(TRIS,3);
 static bit SPWR     @ BITNUM(GPIO,4);
 static bit SPWR_DIR @ BITNUM(TRIS,4);
 static bit D_PIN    @ BITNUM(GPIO,5);
 static bit D_TRIS   @ BITNUM(TRIS,5);
#endif
#ifdef _16C64
 static bit SCL      @ BITNUM(PORT,0);
 static bit SCL_TRIS @ BITNUM(TRIS,0);
 static bit SDA      @ BITNUM(PORT,1);
 static bit SDA_TRIS @ BITNUM(TRIS,1);
 static bit SW1      @ BITNUM(PORT,2);
 static bit SW1_DIR  @ BITNUM(TRIS,2);
 static bit SW2      @ BITNUM(PORT,3);
 static bit SW2_DIR  @ BITNUM(TRIS,3);
 static bit SPWR     @ BITNUM(PORT,4);
 static bit SPWR_DIR @ BITNUM(TRIS,4);
 static bit D_PIN    @ BITNUM(PORT,5);
 static bit D_TRIS   @ BITNUM(TRIS,5);
 
#endif

#ifdef _16F84
 static bit SCL      @ BITNUM(PORTA,0);
 static bit SCL_TRIS @ BITNUM(TRISA,0);
 static bit SDA      @ BITNUM(PORTA,1);
 static bit SDA_TRIS @ BITNUM(TRISA,1);
 static bit SW1      @ BITNUM(PORTA,2);
 static bit SW1_DIR  @ BITNUM(TRISA,2);
 static bit SW2      @ BITNUM(PORTA,3);
 static bit SW2_DIR  @ BITNUM(TRISA,3);
 static bit SPWR     @ BITNUM(PORTA,4);
 static bit SPWR_DIR @ BITNUM(TRISA,4);
 static bit D_PIN    @ BITNUM(PORTB,4);
 static bit D_TRIS   @ BITNUM(TRISB,4);
#endif


#include "delay.h"
#include "delay.c"

#include "m_i2c_1.c"
#include "1wire002.c"
 

//************ DEFINE CHARACTERS *****************
                         //          A
#define LA   0x80        //        ****
#define LB   0x40        //     F *    *  B
#define LC   0x20        //       *  G *
#define LD   0x10        //        ****
#define LE   0x08        //     E *    *  C
#define LF   0x04        //       *    *
#define LG   0x02        //        ****   * DOT
#define LDOT 0x01        //          D


#define NUM0  LA+LB+LC+LD+LE+LF    //-- '0'
#define NUM1  LB+LC                //-- '1'
#define NUM2  LA+LB+LG+LE+LD       //-- '2'
#define NUM3  LA+LB+LC+LD+LG       //-- '3'
#define NUM4  LF+LG+LB+LC          //-- '4'
#define NUM5  LA+LF+LG+LC+LD       //-- '5'
#define NUM6  LA+LF+LE+LD+LC+LG    //-- '6'
#define NUM7  LA+LB+LC             //-- '7'
#define NUM8  LA+LB+LC+LD+LE+LF+LG //-- '8'
#define NUM9  LA+LB+LC+LF+LG       //-- '9'

#define MINUS LG                   //-- '-'      - Negative
#define THIGH LB+LC+LE+LF+LG       //-- 'H'      - High Level
#define TLOW  LF+LE+LD             //-- 'L'      - Low Level
#define PROG  LF+LE+LG+LB+LA       //-- 'P'      - Program
#define DOT   LDOT     //-- '.' The Dot Shows current Position for altering

const char Digits[]={NUM0,NUM1,NUM2,NUM3,NUM4,NUM5,NUM6,NUM7,NUM8,NUM9};


//************ DEFINE TIMINGS ********************
#define _TPC  100             //-- ns for Mode Toggle Low before pulses (MIN)
#define _TCP  100             //-- ns for toggle clock 16  (MIN)
#define _TCL  100             //-- ns for toggle clock pulse low (MIN)
#define _TCH  100             //-- ns for toggle clock pulse High (MIN)
#define _TT    10             //-- ns for Transition time (ESTIMATED)


//************** VARIABLES **************
char TempH=0xFF;              //-- High Thermo setting
char TempL=0xFF;              //-- Low thermo setting
char TempS=0xFF;              //-- Status register setting
char ValueType=THIGH;         //-- Indicates the current displayed type
char EditPosition=0;          //-- Selects current digit to edit
char DisplayBuff[5];          //-- 4 characters on display so 4 in buffer
char count;
char Hundreds,Tens,Ones;      //-- Editable Areas
char temp;

bit  HighLowTemp;           //-- High or Low temperature now displayed
bit  Negative;              //-- Indicates a negative value is present

//************ Functions *************
void ToggleMode(void);        //-- Toggle the Thermostat/1-wire mode
void ReadCurrent(void);       //-- Read data from the chip
void WriteCurrent(void);      //-- Write data to the chip
void DisplayCurrent(void);    //-- Display data on the display
void DoUserIO(void);          //-- Do adjustmets at users request


//************************************************************************
//                             main
//************************************************************************
void main(void)
{
	HighLowTemp=1;
	Negative=0;
 //-- Init ports --
 SW1_DIR=1;          //-- Keys are inputs
 SW2_DIR=1;
 SPWR=1;             //-- Power to device is on
 SPWR_DIR=0;         //   and set as ouput

 #ifdef _16C64
  OPTION=0xFF;
  INTCON=0x00;
  PSPMODE=0;
 #endif


 ToggleMode();                //-- Force DS1821 into Programming Mode
 ReadCurrent();               //-- Read Current Temperature settings
 while(1)
 {
  DisplayCurrent();            //-- Display current settings
  DoUserIO();                  //-- read keys and do what is required
 }
}
//*********** END OF main

//************************************************************************
//                          ToggleMode
//
// Force's DS1821 into Programming Mode.
// Hold DQ pin High, Lower Power Pin, then Toggle DQ 16 times then release
//
//************************************************************************
void ToggleMode(void)
{
 D_PIN=0;
 D_TRIS=1;            //-- Set DQ high (external pull up)
 SPWR=0;              //-- Lower the power Line
 DelayUs(_TPC);       //-- Delay for DS1821 to sort out what is happening
 for(count=16;count>0;count--)
 {
  D_TRIS=0;           //-- Lower the  DQ pin
  DelayUs(_TCL);      //-- Minimum delay required for low
  D_TRIS=1;           //-- Raise the pin
  DelayUs(_TCH + _TT);//-- Minimum High Time + Transition time
 }
 SPWR=1;              //-- Raise the power pin
 DelayUs(_TCP);       //-- Rise time for the Power Pin
 DelayUs(_TCP);       //-- Bit extra to make sure things have settled

}
//*********** END OF ToggleMode

//************************************************************************
//                          ReadCurrent
//
// Read Current Temperature settings from the thermo device
//************************************************************************
void ReadCurrent(void)
{
 D_Reset();          //-- Reset the Bus
 D_Write(0xA1);      //-- Issue Read Temp High Command
 TempH=D_Read();     //-- Read the "High Temp"

 D_Reset();          //-- Reset the Bus
 D_Write(0xA2);      //-- Issue Read Temp Low Command
 TempL=D_Read();     //-- Read the "Low Temp"

 D_Reset();          //-- Reset the bus
 D_Write(0xAC);      //-- Issue Read Status Command
 TempS=D_Read();     //-- read the status Byte

}
//*********** END OF ReadCurrent

//************************************************************************
//                          WriteCurrent
//
// Write Current Temperature settings from the thermo device
//************************************************************************
void WriteCurrent(void)
{
 D_Reset();          //-- Reset the Bus
 D_Write(0x01);      //-- Issue Read Temp High Command
 D_Write(TempH);     //-- Read the "High Temp"

 D_Reset();          //-- Reset the Bus
 D_Write(0x02);      //-- Issue Read Temp Low Command
 D_Write(TempL);     //-- Read the "Low Temp"

 D_Reset();          //-- Reset the bus
 D_Write(0x0C);      //-- Issue Read Status Command
 D_Write(TempS);     //-- read the status Byte

}
//*********** END OF ReadCurrent


//************************************************************************
//                        DisplayCurrent
//Display current settings of the Buffer
//************************************************************************
void DisplayCurrent(void)
{
 char TempVal;
 //-- Decide if displying the High or Low temperature
 if(HighLowTemp)
 {
  TempVal=TempH;
 }
 else
 {
  TempVal=TempL;
 }
 //-- Convert and place into buffer the selected temperature
 // calc -ve / +ve and its value then split into digits
 if(TempVal & 0x80)
 {
  //-- Negative Number
  TempVal ^= 0xFF;       //-- Invert Bits to give the +ve Equivalent using XOR
  Negative=1;
 }
 else
 {
  //-- Positive Number
  Negative=0;
 }
 //-- Place into buffer the current menu option

 //-- Get Hundreds
 if(Negative)
 {
   //-- Put Minus sign on the Display since min is -55 degrees
   DisplayBuff[2]=MINUS;
   Hundreds=0;
   if(TempVal >=100) TempVal-=100; //-- Possible errored! - fake the correction
 }
 else
 {
  if(TempVal >=100)
  {
   Hundreds=TempVal / 100;
   TempVal-=(Hundreds*100);
   DisplayBuff[2]=Digits[Hundreds];  //-- Show the hundreds position (+125 Max)
  }
  else
  {
   DisplayBuff[2]=Digits[0];  //-- Show a zero in the position
  }
 }
 if(TempVal >=10)
 {
  Tens=TempVal / 10;
  TempVal-=(Tens*10);
  DisplayBuff[3]=Digits[Tens];
 }
 else
 {
  DisplayBuff[3]=Digits[0];  //-- Show a zero in the position
 }
 Ones=TempVal;
 DisplayBuff[4]=Digits[Ones];

 //-- Display current Mode --
 DisplayBuff[1]=ValueType;         //-- Indicates what is displayed

 //-- Display the currently EDIT selection by using the dot
 DisplayBuff[4-EditPosition]+=DOT;

 //-- Write the buffer to the LCD module for displaying
 DisplayBuff[0]=0;
 I2C_Send(0x74,DisplayBuff,5);
}
//*********** END OF DisplayCurrent

//************************************************************************
//                          DoUserIO
// read keys and do what is required
//************************************************************************
void DoUserIO(void)
{
 char done=0;
	//-- gets key press from user and makes the appropiate changes etc
 DelayMs(250);
 while(!done)
 {
  if(SW1=0)
  {
   //-- Check for Switch Bounce --
   DelayUs(10);
   if(SW1=0)
   {
    done=1;
   }
  }
  else
  {
   //-- Check for False Switching
   DelayUs(5)
   if(SW2=0)
   {
    done=2;
   }
  }
 }
 switch(done)
 {
  case 1:
   //-- Mode Switch --
   if((EditPosition++) > 2)
   {
    EditPosition=0;
    switch(ValueType)
    {
     case THIGH:
      ValueType=TLOW;
      HighLowTemp=0;
      break;

     case TLOW:
      ValueType=PROG;
      break;

     default:
     case PROG:
      ValueType=THIGH;
      HighLowTemp=1;
      break;
    }
   }
   break;

  case 2:
   //-- Setting Switch --
   if(ValueType==PROG)
   {
    WriteCurrent();
    break;
   }
   switch(EditPosition)
   {
    case 0:
     Ones++;
     if(Ones >=10)
     {
      Ones=0;
     }
     break;

    case 1:
     Tens++;
     if(Tens >=10)
     {
      Tens=0;
     }
     break;

    case 2:
     if(ValueType==PROG)
     {
      break;
     }
     //-- Special case due to negative numbers possibly being here --
     if(Negative)
     {
      Hundreds=0;     //-- Was Negative sign so change to a zero
      Negative=0;
     }
     else
     {
      Hundreds++;        //-- Increase to 1 or swap to -
      if(Hundreds >1)
      {
       Hundreds=0;
       Negative=1;
      }
     }
     break;
   }
   //-------- Rebuild the Number ---------
   temp=(Hundreds*100)+(Tens*10)+Ones;
   if(temp > MAXTEMPERATURE) temp=MAXTEMPERATURE;
   if(Negative)
   {
	   temp^=temp; //-- Invert to generate the negative Value
   }
   if(ValueType==THIGH)
   {
	   TempH=temp;
   }
   if(ValueType==TLOW)
   {
    TempL=temp;
   }
   break;
 }
}
//*********** END OF DoUserIO

//************************************************************************
//
//************************************************************************


//*********** END OF

//************************************************************************
//
//************************************************************************


//*********** END OF

//************************************************************************
//
//************************************************************************


//*********** END OF

//************************************************************************
//
//************************************************************************


//*********** END OF

//************************************************************************
//
//************************************************************************










⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -