📄 ds1821_1.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 + -