|
|
View previous topic :: View next topic |
Author |
Message |
edbfmi1
Joined: 18 Jul 2006 Posts: 103
|
SPI with MAX7219 and MAX31855 |
Posted: Tue Sep 06, 2016 10:00 am |
|
|
Hello all,
I have a project that uses an MAX31855 temperature sensor IC and an MAX7219 display driver.
I am using the PIC 16F1939 IC on this project and using the Hardware SPI port. The CCS Compiler Version I am using is 4.140
My problem is that I can get the MAX7219 to work using setup_spi.
Code: | setup_spi(SPI_MASTER | SPI_MODE_1 | SPI_CLK_DIV_64); |
.
.
.
Code: |
void readMAX()
{
output_low(TEMP);
delay_us(10);
TempByte3=spi_read(0);
TempByte2=spi_read(0);
TempByte1=spi_read(0);
TempByte0=spi_read(0);
delay_us(10);
output_high(TEMP);
} |
And I can get the MAX31855 to work using #use spi
Code: | #use spi(FORCE_HW, BITS=8, idle=1) |
.
.
.
Code: |
void maxsend() //send routine for max7219
{
output_low(DISP_OUT);
spi_xfer(address); //send address
spi_xfer(data); //send data
output_high(DISP_OUT);
}
|
But I can't figure out how to get them both to work using either "spi setup" or "#use spi"
Any help would be appreciated.
Thanks
Last edited by edbfmi1 on Tue Sep 06, 2016 12:40 pm; edited 2 times in total |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Tue Sep 06, 2016 10:05 am |
|
|
post a schematic of how it is connected -
clearly indicating what device pins go to what pic pins
PLUS your fuses -
since the chip uses "pin select" and you could be in trouble
on that point too.
the 1939 is NOT a trivial part for fuse setup
first and foremost you are trying to "set up" with a
mangled mashup of the HARD setup with the SOFT one.
Not very kosher. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19520
|
|
Posted: Tue Sep 06, 2016 11:07 am |
|
|
This is where using streams with #use is useful.
The Max 31855 is using mode 2. It's also accepting a much faster clock than the Max 7219.
Now key is that you can switch modes by just doing a transfer with both chip selects disabled. You don't tell us your clock rate, so we can't tell how fast you are actually clocking the 7219.
So (something like):
Code: |
#use spi(SPI1, MASTER, baud=100000, MODE=1, bits=8, stream=MAX7219)
#use spi(SPI1, MASTER, MODE=2, bits=8, stream=MAX31855)
//Then to talk to the 7219
spi_xfer(MAX7219,0); //switches the stream to mode 1
output_low(TEMP);
delay_us(10);
TempByte3=spi_xfer(MAX7219,0);
TempByte2=spi_xfer(MAX7219,0);
TempByte1=spi_xfer(MAX7219,0);
TempByte0=spi_xfer(MAX7219,0);
delay_us(10);
output_high(TEMP);
//or for the 31855
spi_xfer(MAX31855,0); //switches the stream to mode 2
output_low(DISP_OUT);
spi_xfer(MAX31855,address); //send address
spi_xfer(MAX31855,data); //send data
output_high(DISP_OUT);
|
By sending the dummy byte before dropping the chip select, the bus gets switched to the required mode and speed. Using streams, allows the spi_xfer to know how things have to be setup.
You will have to tweak the baud rate to match the /64 rate.
By default #use gives the fastest rate supported by the hardware. |
|
|
edbfmi1
Joined: 18 Jul 2006 Posts: 103
|
|
Posted: Tue Sep 06, 2016 11:08 am |
|
|
Sorry I don't have the schematic readily available. But I do have the PIC connected as follows:
RC5(SDO) going to the MAX7219 DIN
RC4(SDI) going to the MAX31855 SO
RC3(SCK) going to the CLOCK pin on both ICs.
RC6 for the Chip Select on the MAX7219
RC7 for the chip select on the MAX31855.
I would like to use the Hard setup since I have the Chips wired to the pins on the PIC to take advantage of the this feature on the PIC.
I wrote 2 simple programs, one for the MAX7219 and one for the MA31855 based on the CCS Code Library.
Like I posted earlier, the both work independently but they use two different ways to setup the SPI port and I can't figure out how to convert either of them to work with the other SPI setup.
Here is the entire code for the MAX7219 Display Chip
Code: |
#include <16f1938.H>
#fuses XT, NOWDT, NOPROTECT, NOBROWNOUT, NOPUT // Set fuses
#use delay(clock = 4000000)
#use spi(FORCE_HW, BITS=8, idle=1)
#define DISP PIN_C6 // Chip Select for Display on SPI Bus
int8 address; // address sent to MAX7219
int8 data; // data sent to MAX7219
void maxsend() // send routine for max7219 to update display
{
output_low(DISP);
spi_xfer(address); //send address
spi_xfer(data); //send data
output_high(DISP);
}
void maxsetup() //configure MAX7219 registers
{
address=0x09, data=0x00, maxsend(); // Decode Mode: 0 = no decode
address=0x0a, data=0x01, maxsend(); // Brightness: 0 = dim, f = brightest
address=0x0b, data=0x03, maxsend(); // Number of Digits: 3 = 4 Digits, 7 = 8 Digits
address=0x0f, data=0x00, maxsend(); // Test Register: 0 = Normal, 1 = Test Operation
address=0x0c, data=0x01, maxsend(); // Shutdown: 0 = Shutdown, 1 = Normal Operation
}
void main()
{
delay_cycles(1);
output_high(DISP);
maxsetup();
while(1)
{
address=0x01, data=(51), maxsend();
address=0x02, data=(121 | 128); maxsend();
address=0x03, data=(109 | 128), maxsend();
address=0x04, data=(48), maxsend();
delay_ms(500);
address=0x01, data=(51), maxsend();
address=0x02, data=(121); maxsend();
address=0x03, data=(109), maxsend();
address=0x04, data=(48), maxsend();
delay_ms(500);
delay_cycles(1);
}
} |
And here is the code for the MAX31855 Temperature Chip
Code: | #include <16F1938.h>
#fuses XT, NOWDT, NOPROTECT, NOBROWNOUT, NOPUT // Set fuses
#use delay(clock=4000000)
#define TEMP PIN_C7 // Chip Select for MAX31855 Temperature IC
int1 Fvdd=0,Fgnd=0,Fopen=0,fault=0;
int8 TempByte3,TempByte2,TempByte1,TempByte0;
int16 Probe_Temp;
int16 Probe_Temp_F;
int16 Chip_Temp;
int16 Chip_Temp_F;
/*******************************************************************************
//Read SPI data
*******************************************************************************/
void readMAX()
{
output_low(TEMP);
delay_us(10);
TempByte3=spi_read(0);
TempByte2=spi_read(0);
TempByte1=spi_read(0);
TempByte0=spi_read(0);
delay_us(10);
output_high(TEMP);
}
/*******************************************************************************
//Fault detection.
//Returns >0 if FAULT. If necessary do a bitwise analisys to check fault source
*******************************************************************************/
int tempFault()
{
fault=TempByte2&0x01; // pelos menos uma falha
Fvdd=(TempByte0>>2)&0x01;
Fgnd=(TempByte0>>1)&0x01;
Fopen=TempByte0&0x01;
return (fault*1+Fvdd*2,Fgnd*4,Fopen*8);
}
/*******************************************************************************
//Read thermocouple temperature
//Returns returns signed temperature in ºC approximately
*******************************************************************************/
int16 readExtTemp()
{
int8 aux;
int16 temp1;
aux=TempByte2>>2;
temp1=TempByte3;
temp1<<=6;
temp1+=aux;
Probe_Temp = temp1/4;
Probe_Temp_F = (Probe_Temp*9/5)+32;
return temp1/=4;
}
/*******************************************************************************
//Read internal temperature
//Returns signed temperature in ºC approximately
*******************************************************************************/
int16 readIntTemp()
{
int8 aux;
int16 temp2;
temp2=TempByte1;
temp2<<=4;
aux=TempByte0>>4;
temp2=TempByte1<<4;
temp2+=aux;
Chip_Temp = temp2/16;
Chip_Temp_F = (Chip_Temp*9/5)+32;
return temp2/=16;
}
void main()
{
Setup_spi(SPI_MASTER );
while(TRUE)
{
do
{
readMAX();
}while(tempFault()!=0);
readExtTemp();
readIntTemp();
delay_ms(500);
}
} |
|
|
|
edbfmi1
Joined: 18 Jul 2006 Posts: 103
|
|
Posted: Tue Sep 06, 2016 12:14 pm |
|
|
Thanks for the help so far.
I made a mistake when I originally listed the code. I had the MAX7219 and MAX31855 reversed.
I rewrote the two sample programs per Ttelmah suggestions and once again they both worked independently but when I merged them into one the display does not function properly.
Below are the two independent programs and then the merged program.
Can anyone see what I am missing here.
Temp Code MAX31855 (Works) Code: | #include <16F1938.h>
#fuses XT, NOWDT, NOPROTECT, NOBROWNOUT, NOPUT // Set fuses
#use delay(clock=4000000)
#use spi(SPI1, MASTER, baud=100000, MODE=1, bits=8, stream=MAX31855)
#define TEMP PIN_C7 // Chip Select for MAX31855 Temperature IC
int1 Fvdd=0,Fgnd=0,Fopen=0,fault=0;
int8 TempByte3,TempByte2,TempByte1,TempByte0; // Data from MAX31855
int8 address; // address sent to MAX7219
int8 data; // data sent to MAX7219
int16 Probe_Temp;
int16 Probe_Temp_F;
int16 Chip_Temp;
int16 Chip_Temp_F;
/*******************************************************************************
//Read SPI data From MAX31855
*******************************************************************************/
void readMAX()
{
spi_xfer(MAX31855,0); //switches the stream to mode 2
output_low(TEMP);
delay_us(10);
TempByte3=spi_xfer(MAX31855,0);
TempByte2=spi_xfer(MAX31855,0);
TempByte1=spi_xfer(MAX31855,0);
TempByte0=spi_xfer(MAX31855,0);
delay_us(10);
output_high(TEMP);
}
/*******************************************************************************
//Fault detection.
//Returns >0 if FAULT. If necessary do a bitwise analisys to check fault source
*******************************************************************************/
int tempFault()
{
fault=TempByte2&0x01; // Checks general fault bit
Fvdd=(TempByte0>>2)&0x01; // Checks Probe to Vdd Fault
Fgnd=(TempByte0>>1)&0x01; // Checks Probe to ground Fault
Fopen=TempByte0&0x01; // Checks Probe Open Fault
return (fault*1+Fvdd*2,Fgnd*4,Fopen*8); // Returns 0 if no fault, else returns fault code
}
/*******************************************************************************
//Read thermocouple temperature
//Returns returns signed temperature in ºC approximately
*******************************************************************************/
int16 readExtTemp()
{
int8 aux;
int16 temp1;
aux=TempByte2>>2;
temp1=TempByte3;
temp1<<=6;
temp1+=aux;
Probe_Temp = temp1/4;
Probe_Temp_F = (Probe_Temp*9/5)+32;
return temp1/=4;
}
/*******************************************************************************
//Read internal temperature
//Returns signed temperature in ºC approximately
*******************************************************************************/
int16 readIntTemp()
{
int8 aux;
int16 temp2;
temp2=TempByte1;
temp2<<=4;
aux=TempByte0>>4;
temp2=TempByte1<<4;
temp2+=aux;
Chip_Temp = temp2/16;
Chip_Temp_F = (Chip_Temp*9/5)+32;
return temp2/=16;
}
void main()
{
delay_cycles(1);
// output_high(DISP);
output_high(TEMP);
// maxsetup();
while(TRUE)
{
do
{
readMAX();
}while(tempFault()!=0);
readExtTemp();
readIntTemp();
delay_ms(500);
}
} |
Display Code MAX7219 (Works) Code: | #include <16f1938.H>
#fuses XT, NOWDT, NOPROTECT, NOBROWNOUT, NOPUT // Set fuses
#use delay(clock = 4000000)
#use spi(SPI1, MASTER, MODE=2, bits=8, stream=MAX7219)
#define DISP PIN_C6 // Chip Select for Display on SPI Bus
int8 address; // address sent to MAX7219
int8 data; // data sent to MAX7219
void maxsend() // send routine for max7219 to update display
{
spi_xfer(MAX7219,0); //switches the stream to mode 1
output_low(DISP);
spi_xfer(MAX7219,address); //send address
spi_xfer(MAX7219,data); //send data
output_high(DISP);
}
void maxsetup() //configure MAX7219 registers
{
address=0x09, data=0x00, maxsend(); // Decode Mode: 0 = no decode
address=0x0a, data=0x01, maxsend(); // Brightness: 0 = dim, f = brightest
address=0x0b, data=0x03, maxsend(); // Number of Digits: 3 = 4 Digits, 7 = 8 Digits
address=0x0f, data=0x00, maxsend(); // Test Register: 0 = Normal, 1 = Test Operation
address=0x0c, data=0x01, maxsend(); // Shutdown: 0 = Shutdown, 1 = Normal Operation
}
void main()
{
delay_cycles(1);
output_high(DISP);
maxsetup();
while(1)
{
address=0x01, data=(51), maxsend();
address=0x02, data=(121 | 128); maxsend();
address=0x03, data=(109 | 128), maxsend();
address=0x04, data=(48), maxsend();
delay_ms(500);
address=0x01, data=(51), maxsend();
address=0x02, data=(121); maxsend();
address=0x03, data=(109), maxsend();
address=0x04, data=(48), maxsend();
delay_ms(500);
delay_cycles(1);
}
} |
Combined Temp MAX31855 works but display MAX7219 Does not show correct output Code: | #include <16F1938.h>
#fuses XT, NOWDT, NOPROTECT, NOBROWNOUT, NOPUT // Set fuses
#use delay(clock=4000000)
#use spi(SPI1, MASTER, baud=100000, MODE=1, bits=8, stream=MAX31855)
#use spi(SPI1, MASTER, MODE=2, bits=8, stream=MAX7219)
#define TEMP PIN_C7 // Chip Select for MAX31855 Temperature IC
#define DISP PIN_C6 // Chip Select for Display on SPI Bus
int1 Fvdd=0,Fgnd=0,Fopen=0,fault=0;
int8 TempByte3,TempByte2,TempByte1,TempByte0; // Data from MAX31855
int8 address; // address sent to MAX7219
int8 data; // data sent to MAX7219
int16 Probe_Temp;
int16 Probe_Temp_F;
int16 Chip_Temp;
int16 Chip_Temp_F;
/**********************************************************************************
// Send Update Display, MAX7219
**********************************************************************************/
void maxsend() // send routine for max7219 to update display
{
spi_xfer(MAX7219,0); //switches the stream to mode 1
output_low(DISP);
spi_xfer(MAX7219,address); //send address
spi_xfer(MAX7219,data); //send data
output_high(DISP);
}
/**********************************************************************************
// Initialize Display, MAX7219
**********************************************************************************/
void maxsetup() //configure MAX7219 registers
{
address=0x09, data=0x00, maxsend(); // Decode Mode: 0 = no decode
address=0x0a, data=0x01, maxsend(); // Brightness: 0 = dim, f = brightest
address=0x0b, data=0x03, maxsend(); // Number of Digits: 3 = 4 Digits, 7 = 8 Digits
address=0x0f, data=0x00, maxsend(); // Test Register: 0 = Normal, 1 = Test Operation
address=0x0c, data=0x01, maxsend(); // Shutdown: 0 = Shutdown, 1 = Normal Operation
}
/*******************************************************************************
//Read SPI data From MAX31855
*******************************************************************************/
void readMAX()
{
spi_xfer(MAX31855,0); //switches the stream to mode 2
output_low(TEMP);
delay_us(10);
TempByte3=spi_xfer(MAX31855,0);
TempByte2=spi_xfer(MAX31855,0);
TempByte1=spi_xfer(MAX31855,0);
TempByte0=spi_xfer(MAX31855,0);
delay_us(10);
output_high(TEMP);
}
/*******************************************************************************
//Fault detection.
//Returns >0 if FAULT. If necessary do a bitwise analisys to check fault source
*******************************************************************************/
int tempFault()
{
fault=TempByte2&0x01; // Checks general fault bit
Fvdd=(TempByte0>>2)&0x01; // Checks Probe to Vdd Fault
Fgnd=(TempByte0>>1)&0x01; // Checks Probe to ground Fault
Fopen=TempByte0&0x01; // Checks Probe Open Fault
return (fault*1+Fvdd*2,Fgnd*4,Fopen*8); // Returns 0 if no fault, else returns fault code
}
/*******************************************************************************
//Read thermocouple temperature
//Returns returns signed temperature in ºC approximately
*******************************************************************************/
int16 readExtTemp()
{
int8 aux;
int16 temp1;
aux=TempByte2>>2;
temp1=TempByte3;
temp1<<=6;
temp1+=aux;
Probe_Temp = temp1/4;
Probe_Temp_F = (Probe_Temp*9/5)+32;
return temp1/=4;
}
/*******************************************************************************
//Read internal temperature
//Returns signed temperature in ºC approximately
*******************************************************************************/
int16 readIntTemp()
{
int8 aux;
int16 temp2;
temp2=TempByte1;
temp2<<=4;
aux=TempByte0>>4;
temp2=TempByte1<<4;
temp2+=aux;
Chip_Temp = temp2/16;
Chip_Temp_F = (Chip_Temp*9/5)+32;
return temp2/=16;
}
void main()
{
delay_cycles(1);
output_high(DISP);
output_high(TEMP);
maxsetup();
while(TRUE)
{
do
{
readMAX();
}while(tempFault()!=0);
readExtTemp();
readIntTemp();
address=0x01, data=(51), maxsend();
address=0x02, data=(121 | 128); maxsend();
address=0x03, data=(109 | 128), maxsend();
address=0x04, data=(48), maxsend();
delay_ms(500);
address=0x01, data=(51), maxsend();
address=0x02, data=(121); maxsend();
address=0x03, data=(109), maxsend();
address=0x04, data=(48), maxsend();
delay_ms(500);
delay_cycles(1);
delay_ms(500);
}
} |
|
|
|
edbfmi1
Joined: 18 Jul 2006 Posts: 103
|
|
Posted: Tue Sep 06, 2016 2:31 pm |
|
|
Here is something else I have noticed:
If I remark out the lines that contain any reference to Code: | spi_xfer(MAX31855,0) |
and remark out the line Code: |
#use spi(SPI1, MASTER, MODE=1, bits=8, baud=100000, stream=MAX31855) |
The display works properly.
If I then unremark only the line Code: |
#use spi(SPI1, MASTER, MODE=1, bits=8, baud=100000, stream=MAX31855) |
The display stops working again.
I am missing something on how the #use spi pre-processor directive works but I can't figure it out |
|
|
edbfmi1
Joined: 18 Jul 2006 Posts: 103
|
|
Posted: Tue Sep 06, 2016 2:58 pm |
|
|
SOLVED!!
I looked into the MODE and realized that I can get them both to work if I configure the #USE SPI pre-processor directives as follows. Code: |
#use spi(SPI1, MASTER, MODE=0, bits=8, stream=MAX31855)
#use spi(SPI1, MASTER, MODE=0, bits=8, stream=MAX7219) |
Also since I am only running the PIC at 4Mhz I can leave the "baud" rate off and run them as fast as possible.
Now onto the next part of the development. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19520
|
|
Posted: Wed Sep 07, 2016 1:29 am |
|
|
I based the mode number on his previous code, which had IDLE set to high. Without setting anything else, this is mode2. I must admit I thought it strange that Maxim would have chips using different mode numbers (most manufacturers tend to stick to one standard), but didn't bother to check it!... |
|
|
Gabriel
Joined: 03 Aug 2009 Posts: 1067 Location: Panama
|
|
Posted: Wed Sep 07, 2016 11:25 am |
|
|
Just a heads up, although a slight tangent:
The MAX31855 requires external linearization for low temps I.E. -80C.
at -80C without external linearization, this chip reads -40C...which is bad.
I never checked what the hot side was like since i didnt need it.
Maxim was nice and sent me the formulas they recommend and a little online testing app to confirm your math.
I "hijacked" the Driver thread on the library with a linearized driver that works well in my -80C application....
G _________________ CCS PCM 5.078 & CCS PCH 5.093 |
|
|
edbfmi1
Joined: 18 Jul 2006 Posts: 103
|
|
Posted: Thu Mar 22, 2018 2:06 pm |
|
|
Well, we finally have gone into production on this unit and now I am running into problems with 10% failure rate with the display.
When I look at the data being sent to the display driver in the maxsend() subroutine in a watch window the correct data is being sent to the correct address but the display shows garbage.
In case anybody is up for a challenge I have attached the entire program.
Any help would be greatly appreciated.
I am using PCM Compiler V4.140 and MPLAB IDE v 8.92
Code: | #include <16F1518.h>
#include <24LC64.c>
#fuses XT, NOWDT, PROTECT, BROWNOUT, PUT // Set fuses
//#fuses XT, NOWDT, NOPROTECT, BROWNOUT, NOPUT // Set fuses USE these fuses for Debugging with PicKit3
#use delay(clock=4000000)
#use spi(SPI1, MASTER, MODE=0, bits=32, stream=MAX31855)
#use spi(SPI1, MASTER, MODE=0, bits=8, stream=MAX7219)
// Display digit assignments
#define Low 0
#define SPI_MODE_1 (SPI_L_TO_H)
#define V_MONITOR PIN_A0 // Voltage Monitoring Inpit
#define LIGHT_IN PIN_A1 // Monitor Ambient Light Input
#define HEARTBEAT PIN_A2 // Heart Beat LED
#define FAN_RY PIN_A3 // Fan Relay Output
#define STEP_2_PB PIN_A4 // STEP_2 Push Button Input
#define STEP_1_PB PIN_A5 // STEP_1 Push Button Input
#define DOWN_PB PIN_B0 // DOWN Arrow Push Button Input
#define UP_PB PIN_B1 // UP Arrow Push Button Input
#define CALI_IN PIN_B2 // Calibrate Input
#define FUEL_RY PIN_B3 // FUEL Relay Output
//PIN_B4 Not Used
#define HIGH_LED PIN_B5 // HIGH TEMP LED Output
// PIN_B6 Reserved for ICSP_CLOCK
// PIN_B7 Reserved for ICSP_DATA
// PIN_C0 I2C DATAfs
// PIN_C1 I2C CLOCK
// PIN_C2 Available
// PIN_C3 SPI CLOCKGC
// PIN_C4 SPI DATA IN
// PIN_C5 SPI DATA OUT
#define TEMP PIN_C7 // Chip Select for MAX31855 Temperature IC
#define DISP PIN_C6 // Chip Select for Display on SPI Bus
int1 Fvdd=0,Fgnd=0,Fopen=0,fault=0;
int8 TempByte3,TempByte2,TempByte1,TempByte0; // Data from MAX31855
int8 address; // address sent to MAX7219
int8 data; // data sent to MAX7219
int8 ColonOn; // "Or'd" with the timer to flash colon
int8 AMBIENT; // Ambient Light Input Dark = 255, Bright Light = 0
int8 VOLTAGE; // Input Voltage Level
int8 ten_ms_timer; // milisecond timer
int8 tenths_timer; // tenth of a second timer
int8 sec_timer; // seconds timer
signed min_timer; // minute timer
int8 hour_timer; // hour timer
int8 FanOnTimer; // Second timer to set the delay before Fuel Turns on
int8 msd_code; // thousands
int8 lsd2_code; // hunsdreds
int8 lsd1_code; // tens
int8 lsd_code; // ones
int8 msd_value; // value of the msd
int8 lsd2_value; // value of the lsd2
int8 lsd1_value; // value of the lsd1
int8 lsd_value; // value of the lsd
int8 temp_msd_code; // temperature thousands
int8 temp_lsd2_code; // temperature hunsdreds
int8 temp_lsd1_code; // temperature tens
int8 temp_lsd_code; // temperature ones
// int8 time_msd_code; // time thousands
// int8 time_lsd2_code; // time hunsdreds
// int8 time_lsd_code; // time ones
// int16 Timer1Preset; // Preset setting for Timer1
signed int16 Probe_Temp;
signed int16 Probe_Temp_F; // Unsigned Probe Temperature, used for display
signed int16 Probe_Temp_Signed; // Signed value of Probe Temp used for arithmetic
signed int16 StartTemp; // Used to see if Temp is rising at start up
int16 Chip_Temp;
int16 Chip_Temp_F;
signed int16 TempSetPoint; // The current temperature set point
int16 FanUpOffset; // The Fan Off Offset going up amount
int16 FanDownOffset; // The Fan On Offset going down
int16 FuelOffset; // The Fuel On Offset amount
int16 FuelOnTimer; // Used to check for temperature rise of 10 degrees within 30 seconds
int16 StartTimer; // Used to blank the display after 2 Seconds if STEP_1_PB is not pressed
int16 TimerPausedTimer; // Used to see if STEP_1_PB is pressed twice within 1 second
int16 HeartBeatTimer; // Timer to pulse heartbeat
int16 CoolSet; // Cool down setting
int16 Debounce_STEP_1_PB; // Counter for Debounicing STEP_1_PB
int16 Debounce_STEP_2_PB; // Counter for Debounicing STEP_2_PB
int16 Debounce_UP_PB; // Counter for Debounicing UP_PB
int16 Debounce_DOWN_PB; // Counter for Debounicing DOWN_PB
int16 data1; // Used to read eeProm
int16 data2; // Used to read eeProm
int16 CountDownTimer; // Timer value in HHMM where HH max is 24 and MM max is 60
// That is, the high byte is hours and low byte is minutes
int8 StatusBits1; // Status Bits - first bank
#bit LoadTimeDisplay = StatusBits1.0 // Used to tell when to update the time display
#bit TimerDone = StatusBits1.1 // Set when timer has counted down to zero
#bit FuelChange = StatusBits1.2 // Set when fuel changing
#bit ProbeFailed = StatusBits1.3 // Set when Probe Failed
#bit LowVoltage = StatusBits1.4 // Set when AC Line Voltage is too low
#bit LowTemp = StatusBits1.5 // Set when negative bit is set
#bit FanStart = StatusBits1.6 // Set when the Fan is first turmed on
#bit FuelStart = StatusBits1.7 // Set wehn Fuel first starts
int8 StatusBits2;
#bit TimerPaused = StatusBits2.0 // Set when timer is paused
#bit CheckPause = StatusBits2.1 // Toggled to run the Pause routine
#bit PausedTemp = StatusBits2.2 // Used to update the Temperature when Timer is Paused
#bit LoPorDisp = StatusBits2.3 // Set when Lo Por is displayed
#bit FanDownChange = StatusBits2.4 // Set when changing Fan Down Set point
#bit TempReached = StatusBits2.5 // Set if initial temperature rise is met
#bit NegTemp = StatusBits2.6 // Set when negative temperature is read
int8 ButtonsPressed;
#bit STEP_1_Pressed = ButtonsPressed.0 // True when button 1 pressed
#bit STEP_1_Held = ButtonsPressed.1 // True when button 1 held for more than 1/2 second
#bit STEP_2_Pressed = ButtonsPressed.2 // True when button 2 pressed
#bit STEP_2_Held = ButtonsPressed.3 // True when button 2 held for more than 1/2 second
#bit UP_Pressed = ButtonsPressed.4 // True when UP button pressed
#bit UP_Held = ButtonsPressed.5 // True when UP button held for more than 1/2 second
#bit DOWN_Pressed = ButtonsPressed.6 // True when DOWN button pressed
#bit DOWN_Held = ButtonsPressed.7 // True when DOWN button held for more than 1/2 second
/**********************************************************************************
// Setup the timer2
**********************************************************************************/
#separate
#int_TIMER2
void TIMER2_Interrupt_Servicing(void) // 10ms interrupt
{
HeartBeatTimer++;
if(HeartBeatTimer == 50)
{
if((TimerPaused == True)&&(PausedTemp == False)) // Update Temp if timer Paused
{
PausedTemp = True;
}
output_toggle(HEARTBEAT);
HeartBeatTimer = 0;
}
if((TimerPaused == True)&&(TimerPausedTimer < 100)&&(STEP_2_Pressed == False))
{
TimerPausedTimer++;
}
if((TimerPaused == True)&&(STEP_2_Pressed == True)&&(TimerPausedTimer >= 10)&&(TimerPausedTimer <= 99))
{
reset_cpu();
}
if(TimerPaused == False)
{
TimerPausedTimer = 0;
}
if ((TimerPausedTimer >=100)&&(STEP_2_Pressed == True))
{
TimerPaused = False;
}
delay_cycles(1); // NOP
if(TimerDone == True)
{
ColonOn = 128;
}
delay_cycles(1);
CheckPause = 1; // Check pause routine ever .1seconds
if(TimerPaused == False)
{
ten_ms_timer--; // Increment milisecond timer
}
if(ten_ms_timer == 0) //
{
delay_cycles(1);
if((FanOnTimer <= 100)&&(input_state(FAN_RY)))
{
FanOnTimer++;
}
if((FuelStart == True)&(FuelOnTimer <= 300))
{
FuelOnTimer++;
}
if((StartTimer <= 20))
{
StartTimer++;
}
tenths_timer++; // Increment tenths of a second timer
ten_ms_timer = 10; // and reset milisecond timer
}
if(tenths_timer == 5)
{
if((ColonOn == 0)&&(TimerDone == False))
{
LoadTimeDisplay = true; // Refresh the Time display
ColonOn = 128; // Set the value to "or" with the display to flash timer colon
}
}
if(tenths_timer == 10)
{
if(ColonOn == 128)
{
LoadTimeDisplay = true; // Refresh the Time display
ColonOn = 0; // Set the value to "or" with the display to flash timer colon
}
if((TimerDone == False)&&(ProbeFailed == False))
{
sec_timer--; // Increment second timer
}
tenths_timer = 0; // and reset tenths timer
if(TimerDone == False)
{
ColonOn = 0; // Set the value to "or" with the display to flash timer colon
}
}
if((TimerDone == False)&&(ProbeFailed == False))
{
if(sec_timer == 00)
{
sec_timer = 60; // and reset seconds timer
min_timer--; // Decrement the minute timer
if(min_timer >=0)
{
CountDownTimer=make16(hour_timer, min_timer); // Puts hour in highbyte and minute in low byte
}
}
if((min_timer < 0 ) && (hour_timer >=1))
{
min_timer = 59; // and rest hour timer
hour_timer--; // Decrement the hour timer
CountDownTimer=make16(hour_timer, min_timer); // Puts hour in highbyte and minute in low byte
}
}
if((min_timer == 0) && (hour_timer == 0)) // Countdown Finished
{
delay_cycles(1);
TimerDone = True;
}
if(input_state(STEP_1_PB) == True) // Step 1 Not Pressed
{
delay_cycles(1);
STEP_1_Pressed = False; // True when button 1 pressed
STEP_1_Held = False; // True when button 1 held for more than 1/2 second
Debounce_STEP_1_PB = 0; // Reset Debounce
}
else // Step 1 Pressed
{
delay_cycles(1);
STEP_1_Pressed = True; // True when button 1 pressed
Debounce_STEP_1_PB++; // Increment Debounce
if(Debounce_STEP_1_PB >= 50) // See if it was held for 1/2 second
{
Debounce_STEP_1_PB = 50;
STEP_1_Held = True;
}
}
if(input_state(STEP_2_PB) == True) // Step 2 Not Pressed
{
delay_cycles(1);
STEP_2_Pressed = False; // True when button 1 pressed
STEP_2_Held = False; // True when button 1 held for more than 1/2 second
Debounce_STEP_2_PB = 0; // Reset Debounce
}
else // Step 2 Pressed
{
delay_cycles(1);
STEP_2_Pressed = True; // True when button 1 pressed
Debounce_STEP_2_PB++; // Increment Debounce
if(Debounce_STEP_2_PB >= 50) // See if it was held for 1/2 second
{
Debounce_STEP_2_PB = 50;
STEP_2_Held = True;
}
}
if(input_state(UP_PB) == True) // Up Not Pressed
{
delay_cycles(1);
UP_Pressed = False; // True when button 1 pressed
UP_Held = False; // True when button 1 held for more than 1/2 second
Debounce_UP_PB = 0; // Reset Debounce
}
else // Up Pressed
{
delay_cycles(1);
UP_Pressed = True; // True when button 1 pressed
Debounce_UP_PB++; // Increment Debounce
if(Debounce_UP_PB >= 50) // See if it was held for 1/2 second
{
Debounce_UP_PB = 50;
UP_Held = True;
}
}
if(input_state(DOWN_PB) == True) // Down Not Pressed
{
delay_cycles(1);
DOWN_Pressed = False; // True when button 1 pressed
DOWN_Held = False; // True when button 1 held for more than 1/2 second
Debounce_DOWN_PB = 0; // Reset Debounce
}
else // Down Pressed
{
delay_cycles(1);
DOWN_Pressed = True; // True when button 1 pressed
Debounce_DOWN_PB++; // Increment Debounce
if(Debounce_DOWN_PB >= 50) // See if it was held for 1/2 second
{
Debounce_DOWN_PB = 50;
DOWN_Held = True;
}
}
}
/**********************************************************************************
// Read the Analog Ports
**********************************************************************************/
void read_analog()
{
set_adc_channel(0); // VOLTAGE LEVEL INPUT Channel 0;
delay_ms(1);
VOLTAGE = read_adc();
if(input_state(FAN_RY)&&input_state(FUEL_RY))
{
if(VOLTAGE <= 46-AMBIENT)
{
LowVoltage = True;
}
if (VOLTAGE >= 50-AMBIENT)
{
LowVoltage = False;
}
}
else if (input_state(FAN_RY))
{
if(VOLTAGE <= 49-AMBIENT)
{
LowVoltage = True;
}
if (VOLTAGE >= 56-AMBIENT)
{
LowVoltage = False;
}
}
else
{
if(VOLTAGE <= 56-AMBIENT)
{
LowVoltage = True;
}
if (VOLTAGE >= 63-AMBIENT)
{
LowVoltage = False;
}
}
delay_cycles(1);
set_adc_channel(1); // Ambient Light Analog Channel 1
delay_ms(1);
AMBIENT = read_adc();
delay_cycles(1);
if (AMBIENT <= 75)
{
AMBIENT = 15;
}
else if(AMBIENT <= 123)
{
AMBIENT = 11;
}
else if(AMBIENT <= 171)
{
AMBIENT = 7;
}
else if(AMBIENT <= 219)
{
AMBIENT = 3;
}
else
{
AMBIENT = 1;
}
delay_cycles(1);
}
/**********************************************************************************
// Send Update Display, MAX7219
**********************************************************************************/
void maxsend() // send routine for max7219 to update display
{
spi_xfer(MAX7219,0); //switches the stream to mode 0
delay_us(10);
output_low(DISP);
delay_us(10);
spi_xfer(MAX7219,address); //send address
// delay_us(10);
spi_xfer(MAX7219,data); //send data
// delay_us(10);
output_high(DISP);
// delay_us(10);
}
/**********************************************************************************
// Initialize Display, MAX7219
**********************************************************************************/
void maxsetup() //configure MAX7219 registers
{
address=0x09, data=0x00, maxsend(); // Decode Mode: 0 = no decode
address=0x0a, data=0x01, maxsend(); // Brightness: 0 = dim, f = brightest
address=0x0b, data=0x07, maxsend(); // Number of Digits: 3 = 4 Digits, 7 = 8 Digits
address=0x0f, data=0x00, maxsend(); // Test Register: 0 = Normal, 1 = Test Operation
address=0x0c, data=0x01, maxsend(); // Shutdown: 0 = Shutdown, 1 = Normal Operation
}
/*******************************************************************************
//Read SPI data From MAX31855
*******************************************************************************/
void readMAX()
{
int32 MAXread;
spi_xfer(MAX31855,0); //switches the stream to mode 0
output_low(TEMP);
delay_us(10);
MAXread=spi_xfer(MAX31855,0);
// delay_us(10);
output_high(TEMP);
// delay_us(10);
TempByte3=MAXread>>24 & 0xff;
TempByte2=MAXread>>16 & 0xff;
TempByte1=MAXread>>8 & 0xff;
TempByte0=MAXread & 0xff;
}
/*******************************************************************************
//Fault detection.
//Returns >0 if FAULT. If necessary do a bitwise analisys to check fault source
*******************************************************************************/
int tempFault()
{
fault=TempByte2&0x01; // Checks general fault bit
Fvdd=(TempByte0>>2)&0x01; // Checks Probe to Vdd Fault
Fgnd=(TempByte0>>1)&0x01; // Checks Probe to ground Fault
Fopen=TempByte0&0x01; // Checks Probe Open Fault
return (fault*1+Fvdd*2,Fgnd*4,Fopen*8); // Returns 0 if no fault, else returns fault code
}
/*******************************************************************************
//Read thermocouple temperature
//Returns returns signed temperature in ºC approximately
*******************************************************************************/
signed int16 readExtTemp()
{
delay_cycles(1);
signed int16 temp1;
temp1 = make16(TempByte3,TempByte2);
if (!bit_test(temp1,15)) // Positive or zero degrees celsius
{
delay_cycles(1);
temp1>>=2; // Shift out the 2 lower bits (Fault, Reserved)
Probe_Temp = temp1>>2; // Shift out the decimal bits
Probe_Temp_F = (Probe_Temp*9/5) + 32;
Probe_Temp_Signed = Probe_Temp_F;
delay_cycles(1);
NegTemp = False;
return;
}
else // Negative degrees celsius
{
delay_cycles(1);
temp1=~temp1; // Take ones compliment
temp1>>=2; // Shift out the 2 lower bits (Fault, Reserved)
temp1+=1;
Probe_Temp = (temp1>>2); // Shift out the decimal bits
Probe_Temp = Probe_Temp*-1; // Change the sign for C to F conversion
Probe_Temp_F = (Probe_Temp*9/5) + 32;
Probe_Temp_Signed = Probe_Temp_F;
if (Probe_Temp_F >=0)
{
NegTemp = False;
}
else
{
Probe_Temp_F = Probe_Temp_F*-1; // Change the sign for display purposes
NegTemp = True;
}
delay_cycles(1);
return;
}
}
/*
int16 readExtTemp()
{
int16 aux;
int16 temp1;
delay_cycles(1);
temp1=TempByte3>>7;
delay_cycles(1);
if(temp1 == 1) // Check for signbit set which means negative
{
delay_cycles(1);
LowTemp = True;
Probe_Temp_F = 32;
}
else
{
delay_cycles(1);
LowTemp = False;
aux=TempByte2>>2;
temp1=TempByte3;
temp1<<=6;
temp1+=aux;
Probe_Temp = temp1/4;
Probe_Temp_F = (Probe_Temp*9/5)+32;
}
delay_cycles(1);
return temp1/=4;
}
*/
/*******************************************************************************
//Read internal temperature
//Returns signed temperature in ºC approximately
*******************************************************************************/
int16 readIntTemp()
{
int8 aux;
int16 temp2;
temp2=TempByte1;
temp2<<=4;
aux=TempByte0>>4;
temp2=TempByte1<<4;
temp2+=aux;
Chip_Temp = temp2/16;
Chip_Temp_F = (Chip_Temp*9/5)+32;
return temp2/=16;
}
/*******************************************************************************
// Convert numbers to 7-Segment display code
*******************************************************************************/
#separate
void display_update(int digit_code, int8 &digit_value)
{
delay_cycles(1);
switch(digit_code)
{
case 0:
digit_value = 126; // dig_0
break;
case 1:
digit_value = 48; // dig_1
break;
case 2:
digit_value = 109; // dig_2
break;
case 3:
digit_value = 121; // dig_3
break;
case 4:
digit_value = 51; // dig_4
break;
case 5:
digit_value = 91; // dig_5
break;
case 6:
digit_value = 95; // dig_6
break;
case 7:
digit_value = 112; // dig_7
break;
case 8:
digit_value = 127; // dig_8
break;
case 9:
digit_value = 123; // dig_9
break;
case 10:
digit_value = 0; // dig_blank
break;
case 11:
digit_value = 0b01110011; // dig_P
break;
case 12:
digit_value = 0b01010000; // dig_r
break;
case 13:
digit_value = 0b00011100; // dig_u
break;
case 14:
digit_value = 0b01010100; // dig_n
break;
case 15:
digit_value = 0b00111001; // dig_C
break;
case 16:
digit_value = 0b01000000; // dig_-
break;
case 17:
digit_value = 0b01111001; // dig_E
}
}
/*******************************************************************************
// Convert the timer value into the specific digits
*******************************************************************************/
void GetDigitsTimer(int16 preset) // Separates the passed value into the specific digits
{
int8 hours, minutes, minhigh, hourhigh, val;
hours = make8(preset, 1);
minutes = make8(preset, 0);
delay_cycles(1);
hourhigh = 0;
minhigh = 0;
val = hours;
while (Val >= 10)
{
Val -= 10;
hourhigh++;
}
msd_code = hourhigh;
lsd2_code = val;
val = minutes;
while (Val >= 10)
{
Val -= 10;
minhigh++;
}
lsd1_code = minhigh;
lsd_code = val;
}
/*******************************************************************************
// Convert the temperature value into the specific digits
*******************************************************************************/
void GetDigitsTemp(int16 preset) // Separates the passed value into the specific digits
{
int8 tens, huns, thous;
int16 val;
tens = 0;
huns = 0;
thous = 0;
val = preset;
while (Val >= 1000)
{
Val -= 1000;
thous++;
}
while (Val >= 100)
{
Val -= 100;
huns++;
}
while (Val >= 10)
{
Val -= 10;
tens++;
}
msd_code = thous;
lsd2_code = huns;
lsd1_code = tens;
lsd_code = val;
}
/*******************************************************************************
// Update the Temperature Display
*******************************************************************************/
void UpdateTempDisplay(int16 preset)
{
if(LoPorDisp == False)
{
display_update(lsd_code, lsd_value);
address=0x05, data=(lsd_value), maxsend();
if ((preset)<10)
{
address=0x06, data=(0), maxsend();
}
else
{
display_update(lsd1_code, lsd1_value);
address=0x06, data=(lsd1_value); maxsend();
}
if ((preset)<100)
{
if ((FuelChange == True)||(FanDownChange == True)||(NegTemp == True))
{
address=0x07, data=(1), maxsend();
address=0x08, data=(0), maxsend();
}
else
{
address=0x07, data=(0), maxsend();
}
}
else
{
display_update(lsd2_code, lsd2_value);
address=0x07, data=(lsd2_value), maxsend();
}
if ((preset)<1000)
{
if (((FuelChange == True)||(NegTemp == True)||(FanDownChange == True))&&(preset > 99))
{
address=0x08, data=(1), maxsend();
}
else
{
address=0x08, data=(0), maxsend();
}
}
else
{
display_update(msd_code, msd_value);
address=0x08, data=(msd_value), maxsend();
}
}
else
{
delay_cycles(1);
LoPorDisp = False;
}
}
/*******************************************************************************
// Update the Time Display
*******************************************************************************/
void UpdateTimeDisplay()
{
delay_cycles(1);
int8 hours, minutes;
hours = make8(CountDownTimer, 1);
minutes = make8(CountDownTimer, 0);
delay_cycles(1);
address=0x0a, data=AMBIENT, maxsend(); // Brightness: 0 = dim, f = brightest
delay_cycles(1);
if ((LowVoltage == True)&&(ColonOn == 0))
{
delay_cycles(1);
address=0x08, data=0, maxsend(); // Send " "
address=0x07, data=14, maxsend(); // Send "L"
address=0x06, data=29, maxsend(); // Send "o"
address=0x05, data=0, maxsend(); // Send " "
address=0x04, data=103, maxsend(); // Send "P"
address=0x03, data=29, maxsend(); // Send "o"
address=0x02, data=5, maxsend(); // Send "r"
address=0x01, data=0, maxsend(); // Send " "
LoPorDisp = True;
delay_cycles(1);
}
else
{
display_update(lsd_code, lsd_value);
address=0x01, data=(lsd_value), maxsend();
if (((minutes)<10)&&(hours == 0))
{
address=0x02, data=(0 | ColonOn), maxsend();
}
else
{
display_update(lsd1_code, lsd1_value);
address=0x02, data=(lsd1_value | ColonOn); maxsend();
}
if ((hours > 0) && (hours < 10))
{
display_update(lsd2_code, lsd2_value);
address=0x03, data=(lsd2_value | ColonOn), maxsend();
address=0x04, data=0, maxsend();
}
else if (hours == 0)
{
address=0x03, data=(0 | ColonOn), maxsend();
address=0x04, data=0, maxsend();
}
else
{
display_update(lsd2_code, lsd2_value);
address=0x03, data=(lsd2_value | ColonOn), maxsend();
display_update(msd_code, msd_value);
address=0x04, data=(msd_value), maxsend();
}
}
}
/*******************************************************************************
// Temperature Change Routine
*******************************************************************************/
void TempChange()
{
delay_cycles(1);
address=0x0a, data=AMBIENT, maxsend(); // Brightness: 0 = dim, f = brightest
// Send "Burn Easy"
address=0x04, data=91, maxsend(); // Send "S"
address=0x03, data=79, maxsend(); // Send "E"
address=0x02, data=15, maxsend(); // Send "t"
address=0x01, data=0, maxsend(); // Send " "
GetDigitsTemp(TempSetPoint);
temp_msd_code = msd_code; // temperature thousands
temp_lsd2_code = lsd2_code; // temperature hunsdreds
temp_lsd1_code = lsd1_code; // temperature tens
temp_lsd_code = lsd_code; // temperature ones
delay_cycles(1);
UpdateTempDisplay(TempSetPoint);
while ((STEP_1_Pressed == True)||(STEP_2_Pressed == True))
{
delay_cycles(1);
}
/*******************************************************************
// Adjust Temperature Setpoint
*******************************************************************/
while (STEP_2_Pressed == False)
{
delay_cycles(1);
while((UP_Pressed) && (TempSetPoint < 2000))
{
TempSetPoint++;
delay_cycles(1);
GetDigitsTemp(TempSetPoint); // Get the Digits for the Preset Temp
UpdateTempDisplay(TempSetPoint);
if(Up_Held == True)
{
delay_ms(25);
}
else
{
delay_ms(250);
}
}
while((DOWN_Pressed) && (TempSetPoint > 500))
{
TempSetPoint--;
delay_cycles(1);
GetDigitsTemp(TempSetPoint); // Get the Digits for the Preset Temp
UpdateTempDisplay(TempSetPoint);
if(Down_Held == True)
{
delay_ms(25);
}
else
{
delay_ms(250);
}
}
}
delay_cycles(1);
write_ext_eeprom(3,TempSetPoint);
write_ext_eeprom(4,TempSetPoint>>8);
delay_cycles(1);
While (Step_2_Pressed == True)
{
delay_cycles(1);
}
/*******************************************************************
// Adjust Fan Up Offset
*******************************************************************/
while (STEP_2_Pressed == False)
{
address=0x0a, data=AMBIENT, maxsend(); // Brightness: 0 = dim, f = brightest
// Send "Burn Easy"
address=0x04, data=71, maxsend(); // Send "F"
address=0x03, data=119, maxsend(); // Send "A"
address=0x02, data=21, maxsend(); // Send "n"
address=0x01, data=62, maxsend(); // Send "U"
GetDigitsTemp(FanUpOffset);
temp_msd_code = msd_code; // temperature thousands
temp_lsd2_code = lsd2_code; // temperature hunsdreds
temp_lsd1_code = lsd1_code; // temperature tens
temp_lsd_code = lsd_code; // temperature ones
delay_cycles(1);
UpdateTempDisplay(FanUpOffset);
delay_cycles(1);
while((UP_Pressed) && (FanUpOffset < 200))
{
FanUpOffset++;
delay_cycles(1);
GetDigitsTemp(FanUpOffset); // Get the Digits for the Preset Temp
UpdateTempDisplay(FanUpOffset);
if(Up_Held == True)
{
delay_ms(25);
}
else
{
delay_ms(250);
}
}
while((DOWN_Pressed) && (FanUpOffset > 50))
{
FanUpOffset--;
delay_cycles(1);
GetDigitsTemp(FanUpOffset); // Get the Digits for the Preset Temp
UpdateTempDisplay(FanUpOffset);
if(Down_Held == True)
{
delay_ms(25);
}
else
{
delay_ms(250);
}
}
}
delay_cycles(1);
write_ext_eeprom(5,FanUpOffset);
write_ext_eeprom(6,FanUpOffset>>8);
delay_cycles(1);
While (Step_2_Pressed == True)
{
delay_cycles(1);
StartTimer = 0;
}
/*******************************************************************
// Adjust Fan Down Offset
*******************************************************************/
while (STEP_2_Pressed == False)
{
FanDownChange = True;
address=0x0a, data=AMBIENT, maxsend(); // Brightness: 0 = dim, f = brightest
// Send "Burn Easy"
address=0x04, data=71, maxsend(); // Send "F"
address=0x03, data=119, maxsend(); // Send "A"
address=0x02, data=21, maxsend(); // Send "n"
address=0x01, data=61, maxsend(); // Send "d"
GetDigitsTemp(FanDownOffset);
temp_msd_code = msd_code; // temperature thousands
temp_lsd2_code = lsd2_code; // temperature hunsdreds
temp_lsd1_code = lsd1_code; // temperature tens
temp_lsd_code = lsd_code; // temperature ones
delay_cycles(1);
UpdateTempDisplay(FanDownOffset);
delay_cycles(1);
if(FanDownOffset > 100)
{
temp_msd_code = 1; // Send "-"
}
else
{
temp_msd_code = 0; // Send " "
temp_lsd2_code = 1; // Send "-"
}
UpdateTempDisplay(FanDownOffset);
delay_cycles(1);
while((UP_Pressed) && (FanDownOffset < 200))
{
FanDownOffset++;
delay_cycles(1);
GetDigitsTemp(FanDownOffset); // Get the Digits for the Preset Temp
UpdateTempDisplay(FanDownOffset);
if(Up_Held == True)
{
delay_ms(25);
}
else
{
delay_ms(250);
}
}
while((DOWN_Pressed) && (FanDownOffset > 50))
{
FanDownOffset--;
delay_cycles(1);
GetDigitsTemp(FanDownOffset); // Get the Digits for the Preset Temp
UpdateTempDisplay(FanDownOffset);
if(Down_Held == True)
{
delay_ms(25);
}
else
{
delay_ms(250);
}
}
}
delay_cycles(1);
write_ext_eeprom(7,FanDownOffset);
write_ext_eeprom(8,FanDownOffset>>8);
delay_cycles(1);
FanDownChange = False;
delay_cycles(1);
While (Step_2_Pressed == True)
{
delay_cycles(1);
StartTimer = 0;
}
/*******************************************************************
// Adjust Fuel Offset
*******************************************************************/
while (STEP_2_Pressed == False)
{
FuelChange = True;
address=0x0a, data=AMBIENT, maxsend(); // Brightness: 0 = dim, f = brightest
// Send "Burn Easy"
address=0x04, data=71, maxsend(); // Send "F"
address=0x03, data=62, maxsend(); // Send "U"
address=0x02, data=79, maxsend(); // Send "E"
address=0x01, data=14, maxsend(); // Send "L"
GetDigitsTemp(FuelOffset);
temp_msd_code = msd_code; // temperature thousands
temp_lsd2_code = lsd2_code; // temperature hunsdreds
temp_lsd1_code = lsd1_code; // temperature tens
temp_lsd_code = lsd_code; // temperature ones
delay_cycles(1);
if(FuelOffset > 100)
{
temp_msd_code = 1; // Send "-"
}
else
{
temp_msd_code = 0; // Send " "
temp_lsd2_code = 1; // Send "-"
}
UpdateTempDisplay(FuelOffset);
delay_cycles(1);
while((UP_Pressed) && (FuelOffset < 200))
{
FuelOffset++;
delay_cycles(1);
GetDigitsTemp(FuelOffset); // Get the Digits for the Preset Temp
UpdateTempDisplay(FuelOffset);
if(Up_Held == True)
{
delay_ms(25);
}
else
{
delay_ms(250);
}
}
while((DOWN_Pressed) && (FuelOffset > 50))
{
FuelOffset--;
delay_cycles(1);
GetDigitsTemp(FuelOffset); // Get the Digits for the Preset Temp
UpdateTempDisplay(FuelOffset);
if(Down_Held == True)
{
delay_ms(25);
}
else
{
delay_ms(250);
}
}
}
delay_cycles(1);
write_ext_eeprom(9,FuelOffset);
write_ext_eeprom(10,FuelOffset>>8);
delay_cycles(1);
FuelChange = False;
delay_cycles(1);
While (Step_2_Pressed == True)
{
delay_cycles(1);
StartTimer = 0;
}
/*******************************************************************
// Adjust Cool Down Set point
*******************************************************************/
while (STEP_2_Pressed == False)
{
address=0x0a, data=AMBIENT, maxsend(); // Brightness: 0 = dim, f = brightest
delay_cycles(1);
address=0x04, data=78, maxsend(); // Send "C"
address=0x03, data=126, maxsend(); // Send "O"
address=0x02, data=126, maxsend(); // Send "O"
address=0x01, data=14, maxsend(); // Send "L"
GetDigitsTemp(CoolSet);
temp_msd_code = msd_code; // temperature thousands
temp_lsd2_code = lsd2_code; // temperature hunsdreds
temp_lsd1_code = lsd1_code; // temperature tens
temp_lsd_code = lsd_code; // temperature ones
delay_cycles(1);
UpdateTempDisplay(CoolSet);
delay_cycles(1);
while((UP_Pressed) && (CoolSet < TempSetPoint))
{
CoolSet++;
delay_cycles(1);
GetDigitsTemp(CoolSet); // Get the Digits for the Preset Temp
UpdateTempDisplay(CoolSet);
if(Up_Held == True)
{
delay_ms(25);
}
else
{
delay_ms(250);
}
}
while((DOWN_Pressed) && (CoolSet > 34))
{
CoolSet--;
delay_cycles(1);
GetDigitsTemp(CoolSet); // Get the Digits for the Preset Temp
UpdateTempDisplay(CoolSet);
if(Down_Held == True)
{
delay_ms(25);
}
else
{
delay_ms(250);
}
}
}
delay_cycles(1);
write_ext_eeprom(11,CoolSet);
write_ext_eeprom(12,CoolSet>>8);
delay_cycles(1);
address=0x0a, data=AMBIENT, maxsend(); // Brightness: 0 = dim, f = brightest
// Send "Burn Easy"
address=0x08, data=127, maxsend(); // Send "B"
address=0x07, data=28, maxsend(); // Send "u"
address=0x06, data=5, maxsend(); // Send "r"
address=0x05, data=21, maxsend(); // Send "n"
address=0x04, data=79, maxsend(); // Send "E"
address=0x03, data=119, maxsend(); // Send "A"
address=0x02, data=91, maxsend(); // Send "S"
address=0x01, data=59, maxsend(); // Send "y"
}
/******************************************************************************************
// Display Probe Temperature
******************************************************************************************/
void DisplayProbeTemp(int16 PassedTemp)
{
if (LowTemp == True)
{
delay_cycles(1);
address=0x08, data=0, maxsend(); // Send " "
address=0x07, data=0, maxsend(); // Send " "
address=0x06, data=14, maxsend(); // Send "L"
address=0x05, data=29, maxsend(); // Send "0"
delay_cycles(1);
}
else
{
delay_cycles(1);
GetDigitsTemp(PassedTemp);
temp_msd_code = msd_code; // temperature thousands
temp_lsd2_code = lsd2_code; // temperature hunsdreds
temp_lsd1_code = lsd1_code; // temperature tens
temp_lsd_code = lsd_code; // temperature ones
UpdateTempDisplay(Probe_Temp_F);
}
}
void PreloadSetPoints()
{
delay_cycles(1);
hour_timer = 2;
min_timer = 0;
CountDownTimer=make16(hour_timer, min_timer);
write_ext_eeprom(1,CountDownTimer);
write_ext_eeprom(2,CountDownTimer>>8);
delay_cycles(1);
TempSetPoint = 1400;
write_ext_eeprom(3,TempSetPoint);
write_ext_eeprom(4,TempSetPoint>>8);
delay_cycles(1);
FanUpOffSet = 100;
write_ext_eeprom(5,FanUpOffset);
write_ext_eeprom(6,FanUpOffset>>8);
FanDownOffSet = 25;
write_ext_eeprom(7,FanDownOffset);
write_ext_eeprom(8,FanDownOffset>>8);
delay_cycles(1);
FuelOffSet = 75;
write_ext_eeprom(9,FuelOffset);
write_ext_eeprom(10,FuelOffset>>8);
delay_cycles(1);
CoolSet = 350;
write_ext_eeprom(11,CoolSet);
write_ext_eeprom(12,CoolSet>>8);
delay_cycles(1);
}
void ReadStoredSetpoints()
{
delay_cycles(1);
data1 = read_ext_eeprom(1);
data2 = read_ext_eeprom(2);
data2 = data2<<8;
CountDownTimer = data2+data1;
delay_cycles(1);
data1 = read_ext_eeprom(3);
data2 = read_ext_eeprom(4);
data2 = data2<<8;
TempSetPoint = data2+data1;
delay_cycles(1);
data1 = read_ext_eeprom(5);
data2 = read_ext_eeprom(6);
data2 = data2<<8;
FanUpOffset = data2+data1;
delay_cycles(1);
data1 = read_ext_eeprom(7);
data2 = read_ext_eeprom(8);
data2 = data2<<8;
FanDownOffset = data2+data1;
delay_cycles(1);
data1 = read_ext_eeprom(9);
data2 = read_ext_eeprom(10);
data2 = data2<<8;
FuelOffset = data2+data1;
delay_cycles(1);
data1 = read_ext_eeprom(11);
data2 = read_ext_eeprom(12);
data2 = data2<<8;
CoolSet = data2+data1;
delay_cycles(1);
}
/*******************************************************************************
// Main Program starts here
*******************************************************************************/
void main()
{
SETUP_CCP1(CCP_OFF);
init_ext_eeprom();
output_high(DISP);
output_high(TEMP);
maxsetup();
address=0x01, data=127, maxsend(); // send "8"
address=0x02, data=112, maxsend(); // send "7"
address=0x03, data=95, maxsend(); // send "6"
address=0x04, data=91, maxsend(); // send "5"
address=0x05, data=51, maxsend(); // send "4"
address=0x06, data=121, maxsend(); // send "3"
address=0x07, data=109, maxsend(); // send "2"
address=0x08, data=48, maxsend(); // send "1"
delay_ms(500);
delay_cycles(1);
// output_high(DISP);
// output_high(TEMP);
SETUP_ADC_PORTS(sAN0 | sAN1);
SETUP_ADC(adc_clock_div_8);
// maxsetup();
ten_ms_timer = 0; // milisecond timer
tenths_timer = 0; // tenth of a second timer
sec_timer = 0; // seconds timer
min_timer = 0; // minute timer
hour_timer = 0; // hour timer
SETUP_TIMER_2(T2_DIV_BY_4,249,10); // 10ms interrupts
enable_interrupts(INT_TIMER2);
enable_interrupts(GLOBAL);
StatusBits1 = 0;
StatusBits2 = 0;
ButtonsPressed = 0;
// hour_timer = 00;
// min_timer = 2;
sec_timer = 60;
ten_ms_timer = 10;
TimerDone = True;
TempSetPoint = 1400;
FanUpOffset = 100;
FuelOffset = 75;
FanOnTimer = 0;
FuelOnTimer = 0;
StartTimer = 0;
StartTemp = 0;
HeartBeatTimer = 0;
CountDownTimer=make16(hour_timer, min_timer); // Puts hour in highbyte and minute in low byte
delay_ms(100);
/************************************************************************************************
// Preload setpoints if Cali is Jumpered
************************************************************************************************/
if(input_state(CALI_IN) == Low) // CALI_IN is jumpered so preload timers and eeprom
{
PreloadSetPoints();
}
/************************************************************************************************
// Read Stored setpoints
************************************************************************************************/
ReadStoredSetpoints();
delay_cycles(1);
/***********************************************************************************************
// Temperature Change Requested at startup by holding down both Step Buttons at startup
***********************************************************************************************/
if ((STEP_1_Pressed == True) && (STEP_2_Pressed == True))
{
delay_cycles(1);
read_analog();
TempChange(); // Temperature Change Routine
}
/***********************************************************************************************
// Beginning of main program. Initial start sequence
***********************************************************************************************/
while (STEP_1_Pressed == False)
{
readMAX();
if(tempFault() == 0)
{
if(StartTimer < 20)
{
read_analog();
address=0x0a, data=AMBIENT, maxsend(); // Brightness: 0 = dim, f = brightest
// Send "Burn Easy"
address=0x08, data=127, maxsend(); // Send "B"
address=0x07, data=28, maxsend(); // Send "u"
address=0x06, data=5, maxsend(); // Send "r"
address=0x05, data=21, maxsend(); // Send "n"
address=0x04, data=79, maxsend(); // Send "E"
address=0x03, data=119, maxsend(); // Send "A"
address=0x02, data=91, maxsend(); // Send "S"
address=0x01, data=59, maxsend(); // Send "y"
}
else
{
address=0x01, data=0, maxsend();
address=0x02, data=0, maxsend();
address=0x03, data=0, maxsend();
address=0x04, data=0, maxsend();
address=0x05, data=0, maxsend();
address=0x06, data=0, maxsend();
address=0x07, data=0, maxsend();
address=0x08, data=0, maxsend();
}
}
if (tempFault() != 0) // Send "Prob FAIL"
{
address=0x08, data=103, maxsend(); // Send "P"
address=0x07, data=5, maxsend(); // Send "r"
address=0x06, data=29, maxsend(); // Send "o"
address=0x05, data=31, maxsend(); // Send "b"
address=0x04, data=71, maxsend(); // Send "F"
address=0x03, data=119, maxsend(); // Send "A"
address=0x02, data=48, maxsend(); // Send "I"
address=0x01, data=14, maxsend(); // Send "L"
delay_ms(500);
// Send "BLANK DISPLAY"
address=0x01, data=0, maxsend();
address=0x02, data=0, maxsend();
address=0x03, data=0, maxsend();
address=0x04, data=0, maxsend();
address=0x05, data=0, maxsend();
address=0x06, data=0, maxsend();
address=0x07, data=0, maxsend();
address=0x08, data=0, maxsend();
delay_ms(500);
ProbeFailed = True;
output_low(FAN_RY);
output_low(FUEL_RY);
}
}
if ((StartTimer >= 20)&&(STEP_1_Pressed == True))
{
readMAX();
read_analog();
address=0x0a, data=AMBIENT, maxsend(); // Brightness: 0 = dim, f = brightest
// Send "Burn Easy"
address=0x08, data=127, maxsend(); // Send "B"
address=0x07, data=28, maxsend(); // Send "u"
address=0x06, data=5, maxsend(); // Send "r"
address=0x05, data=21, maxsend(); // Send "n"
address=0x04, data=79, maxsend(); // Send "E"
address=0x03, data=119, maxsend(); // Send "A"
address=0x02, data=91, maxsend(); // Send "S"
address=0x01, data=59, maxsend(); // Send "y"
while (STEP_1_Pressed == True)
{
delay_cycles(1);
}
while (Step_1_Pressed == False)
{
read_analog();
address=0x0a, data=AMBIENT, maxsend(); // Brightness: 0 = dim, f = brightest
delay_cycles(1);
}
}
/************************************************************************************************
// Main Program main loop after startup sequence
************************************************************************************************/
while(TRUE) // Begin main loop after inital setup
{
readMAX();
while (tempFault() != 0) // Send "Prob FAIL"
{
address=0x08, data=103, maxsend(); // Send "P"
address=0x07, data=5, maxsend(); // Send "r"
address=0x06, data=29, maxsend(); // Send "o"
address=0x05, data=31, maxsend(); // Send "b"
address=0x04, data=71, maxsend(); // Send "F"
address=0x03, data=119, maxsend(); // Send "A"
address=0x02, data=48, maxsend(); // Send "I"
address=0x01, data=14, maxsend(); // Send "L"
delay_ms(500);
if(STEP_2_PRESSED == True)
{
reset_cpu();
}
// Send "BLANK DISPLAY"
address=0x01, data=0, maxsend();
address=0x02, data=0, maxsend();
address=0x03, data=0, maxsend();
address=0x04, data=0, maxsend();
address=0x05, data=0, maxsend();
address=0x06, data=0, maxsend();
address=0x07, data=0, maxsend();
address=0x08, data=0, maxsend();
delay_ms(500);
ProbeFailed = True;
output_low(FAN_RY);
output_low(FUEL_RY);
if(STEP_2_PRESSED == True)
{
reset_cpu();
}
}
// if (tempFault() == 0) // Probe is good
// {
// ProbeFailed = False;
// }
delay_cycles(1);
/*********************************************************************************************
// Set Timer Preset
*********************************************************************************************/
if((STEP_1_Pressed == True)&&(TimerDone==True) && (STEP_2_Pressed == False))
{
address=0x08, data=91, maxsend(); // Send "S"
address=0x07, data=79, maxsend(); // Send "E"
address=0x06, data=15, maxsend(); // Send "t"
address=0x05, data=0, maxsend(); // Send " "
address=0x04, data=0, maxsend(); // Send " "
address=0x03, data=0, maxsend(); // Send " "
address=0x02, data=0, maxsend(); // Send " "
address=0x01, data=0, maxsend(); // Send " "
delay_cycles(1);
// TimerDone = False;
// ColonOn == 128;
GetDigitsTimer(CountDownTimer); // Get the Digits for the Timer
hour_timer = make8(CountDownTimer, 1);
min_timer = make8(CountDownTimer, 0);
UpdateTimeDisplay();
delay_ms(250);
while (STEP_2_Pressed == False)
{
delay_cycles(1);
while((UP_Pressed) && (hour_timer < 24))
{
delay_cycles(1);
if (min_timer == 0)
{
delay_cycles(1);
min_timer = 30;
CountDownTimer=make16(hour_timer, min_timer);
}
else
{
delay_cycles(1);
min_timer = 0;
hour_timer = hour_timer + 1;
CountDownTimer=make16(hour_timer, min_timer);
}
delay_cycles(1);
GetDigitsTimer(CountDownTimer); // Get the Digits for the Timer
UpdateTimeDisplay();
delay_ms(250);
}
while((DOWN_Pressed) && (hour_timer > 0))
{
delay_cycles(1);
if (min_timer == 30)
{
delay_cycles(1);
min_timer = 0;
CountDownTimer=make16(hour_timer, min_timer);
}
else
{
delay_cycles(1);
min_timer = 30;
hour_timer = hour_timer - 1;
CountDownTimer=make16(hour_timer, min_timer);
}
delay_cycles(1);
GetDigitsTimer(CountDownTimer); // Get the Digits for the Timer
UpdateTimeDisplay();
delay_ms(250);
}
}
delay_cycles(1);
write_ext_eeprom(1,CountDownTimer); // Store new CountDownTimer Value in eeProm
write_ext_eeprom(2,CountDownTimer>>8);
delay_cycles(1);
while(Step_2_Pressed == True)
{
delay_cycles(1);
}
TimerDone = False;
}
/**********************************************************************************
// Look for Pushbutton 1 pressed to Pause or Reset
**********************************************************************************/
if((TimerDone == False)&&(CheckPause == True))
{
CheckPause = False;
if ((Step_2_Pressed == True)&&(TimerPaused == False))
{
ColonOn = 128;
delay_cycles(1);
GetDigitsTimer(CountDownTimer);
UpdateTimeDisplay();
TimerPaused = True;
output_low(FAN_RY);
output_low(FUEL_RY);
}
}
/*********************************************************************************
// Update Temperature when timer paused
*********************************************************************************/
if ((TimerPaused == True)&&(PausedTemp == True))
{
PausedTemp = False;
readExtTemp();
DisplayProbeTemp(Probe_Temp_F);
}
/*********************************************************************************
// Run main furnace control program
*********************************************************************************/
if (LoadTimeDisplay == True)
{
delay_cycles(1);
if (TimerDone == False)
{
GetDigitsTimer(CountDownTimer); // Get the Digits for the Timer
UpdateTimeDisplay();
LoadTimeDisplay = False;
}
read_analog();
address=0x0a, data=AMBIENT, maxsend(); // Brightness: 0 = dim, f = brightest
delay_cycles(1);
/********************************************************************************
// Use this code to read the internal temperature
********************************************************************************/
// readIntTemp(); // Get the Chips Temperature
// GetDigitsTemp(Chip_Temp_F);
// temp_msd_code = msd_code; // temperature thousands
// temp_lsd2_code = lsd2_code; // temperature hunsdreds
// temp_lsd1_code = lsd1_code; // temperature tens
// temp_lsd_code = lsd_code; // temperature ones
// delay_cycles(1);
delay_cycles(1);
/**********************************************************************************
// Display Probe Temperature
**********************************************************************************/
readExtTemp();
DisplayProbeTemp(Probe_Temp_F);
/**********************************************************************************
// Fan and Burner Control
**********************************************************************************/
if((TimerDone == False)&&(TimerPaused == False))
{
delay_cycles(1);
if(Probe_Temp_F < TempSetPoint)
{
if(FanStart == False)
{
FanStart = True;
}
delay_cycles(1);
output_high(FAN_RY);
}
if(((input_state(FUEL_RY)) == False)&&(FuelStart == True) && (Probe_Temp_F < (TempSetPoint - FuelOffset)))
{
delay_cycles(1);
output_high(FUEL_RY);
FuelOnTimer = 0;
// StartTemp = Probe_Temp_F;
}
if(Probe_Temp_F >= (TempSetPoint))
{
delay_cycles(1);
output_low(FUEL_RY);
}
if(Probe_Temp_F >= (TempSetPoint + FanUpOffset)&&(input_state(HIGH_LED)==False))
{
delay_cycles(1);
output_low(FAN_RY);
output_high(HIGH_LED);
}
if(Probe_Temp_F <= (TempSetPoint + FanUpOffset - FanDownOffset))
{
delay_cycles(1);
output_high(Fan_RY);
output_low(HIGH_LED);
}
if((FuelOnTimer >=10)&&(TempReached == False)&&(Probe_Temp_Signed > (StartTemp + 10)))
{
delay_cycles(1);
TempReached = True;
}
if((input_state(FAN_RY))&&(FanOnTimer>=100))
{
delay_cycles(1);
if(FuelStart == False)
{
output_high(FUEL_RY);
StartTemp = Probe_Temp_Signed; // Initial temp when Fuel Starts
FuelStart = True;
FuelOnTimer = 0;
}
if((FuelOnTimer >= 300)&&(TempReached == False)&&(Probe_Temp_Signed <= (StartTemp +10))) // Temp rise fault
{
delay_cycles(1);
while (STEP_2_PRESSED == False)
{
output_low(FUEL_RY);
address=0x08, data=0, maxsend(); // Send " "
address=0x07, data=21, maxsend(); // Send "n"
address=0x06, data=29, maxsend(); // Send "o"
address=0x05, data=0, maxsend(); // Send " "
address=0x04, data=71, maxsend(); // Send "F"
address=0x03, data=62, maxsend(); // Send "U"
address=0x02, data=79, maxsend(); // Send "E"
address=0x01, data=14, maxsend(); // Send "L"
}
delay_cycles(1);
reset_cpu();
}
}
}
/**********************************************************************************
// Display Timer Done when countdown is fhinished
**********************************************************************************/
if (TimerDone == True)
{
address=0x08, data=127, maxsend(); // Send "B"
address=0x07, data=28, maxsend(); // Send "u"
address=0x06, data=5, maxsend(); // Send "r"
address=0x05, data=21, maxsend(); // Send "n"
address=0x04, data=61, maxsend(); // Send "d"
address=0x03, data=29, maxsend(); // Send "o"
address=0x02, data=21, maxsend(); // Send "n"
address=0x01, data=79, maxsend(); // Send "E"
LoadTimeDisplay = False;
output_low(FUEL_RY);
output_high(FAN_RY);
while ((TimerDone == True)&&(Probe_Temp_F >= CoolSet))
{
delay_cycles(1);
delay_ms(500);
address=0x08, data=127, maxsend(); // Send "B"
address=0x07, data=28, maxsend(); // Send "u"
address=0x06, data=5, maxsend(); // Send "r"
address=0x05, data=21, maxsend(); // Send "n"
address=0x04, data=61, maxsend(); // Send "d"
address=0x03, data=29, maxsend(); // Send "o"
address=0x02, data=21, maxsend(); // Send "n"
address=0x01, data=79, maxsend(); // Send "E"
delay_ms(500);
readMAX();
readExtTemp();
if(tempFault() != 0) // Send "Prob FAIL"
{
address=0x08, data=103, maxsend(); // Send "P"
address=0x07, data=5, maxsend(); // Send "r"
address=0x06, data=29, maxsend(); // Send "o"
address=0x05, data=31, maxsend(); // Send "b"
address=0x04, data=71, maxsend(); // Send "F"
address=0x03, data=119, maxsend(); // Send "A"
address=0x02, data=48, maxsend(); // Send "I"
address=0x01, data=14, maxsend(); // Send "L"
output_low(FAN_RY);
output_low(HIGH_LED);
if(STEP_2_Pressed == TRUE) reset_cpu();
}
else
{
output_high(FAN_RY);
address=0x04, data=78, maxsend(); // Send "C"
address=0x03, data=126, maxsend(); // Send "O"
address=0x02, data=126, maxsend(); // Send "O"
address=0x01, data=14, maxsend(); // Send "L"
delay_cycles(1);
GetDigitsTemp(Probe_Temp_F);
temp_msd_code = msd_code; // temperature thousands
temp_lsd2_code = lsd2_code; // temperature hunsdreds
temp_lsd1_code = lsd1_code; // temperature tens
temp_lsd_code = lsd_code; // temperature ones
UpdateTempDisplay(Probe_Temp_F);
}
delay_ms(500);
}
address=0x01, data=0, maxsend();
address=0x02, data=0, maxsend();
address=0x03, data=0, maxsend();
address=0x04, data=0, maxsend();
address=0x05, data=0, maxsend();
address=0x06, data=0, maxsend();
address=0x07, data=0, maxsend();
address=0x08, data=0, maxsend();
output_low(FUEL_RY);
output_low(FAN_RY);
output_low(HIGH_LED);
while (STEP_1_PRESSED == False)
{
delay_cycles(1);
}
reset_cpu();
}
}
delay_cycles(1);
}
} |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19520
|
|
Posted: Thu Mar 22, 2018 2:38 pm |
|
|
I'd not expect to be able to change the supported transfer length like this.
Leave both #use SPI setups using 32bit, and specify the number of bits to transfer in the individual spi_xfer commands.
so spi_xfer(STREAM, data, 8); for the device wanting 8bit transfers and then 32 for the device wanting 32bit transfers. |
|
|
edbfmi1
Joined: 18 Jul 2006 Posts: 103
|
|
Posted: Thu Mar 22, 2018 3:34 pm |
|
|
Thanks for the quick response!
I made the following changes. But still do not get the display to act properly.
Code: |
#use spi(SPI1, MASTER, MODE=0, bits=32, stream=MAX31855)
#use spi(SPI1, MASTER, MODE=0, bits=32, stream=MAX7219)
|
Code: |
/**********************************************************************************
// Send Update Display, MAX7219
**********************************************************************************/
void maxsend() // send routine for max7219 to update display
{
spi_xfer(MAX7219,0,8); //switches the stream to mode 0
delay_us(10);
output_low(DISP);
delay_us(10);
spi_xfer(MAX7219,address,8); //send address
// delay_us(10);
spi_xfer(MAX7219,data,8); //send data
// delay_us(10);
output_high(DISP);
// delay_us(10);
} |
Code: |
/*******************************************************************************
//Read SPI data From MAX31855
*******************************************************************************/
void readMAX()
{
int32 MAXread;
spi_xfer(MAX31855,0,32); //switches the stream to mode 0
output_low(TEMP);
delay_us(10);
MAXread=spi_xfer(MAX31855,0,32);
// delay_us(10);
output_high(TEMP);
// delay_us(10);
TempByte3=MAXread>>24 & 0xff;
TempByte2=MAXread>>16 & 0xff;
TempByte1=MAXread>>8 & 0xff;
TempByte0=MAXread & 0xff;
}
|
|
|
|
edbfmi1
Joined: 18 Jul 2006 Posts: 103
|
|
Posted: Thu Mar 22, 2018 3:45 pm |
|
|
I noticed in the Errata sheet for the PIC16F1518 that it says the following.
Could this be the problem? I really don't know how to check for the error or implement the workaround.
Quote: | 6.1 SPI Master mode
When the MSSP is used in SPI Master mode and
the CKE bit is clear (CKE = 0), the Buffer Full (BF)
bit and the MSSP Interrupt Flag (SSPIF) bit
becomes set half an SCK cycle early. If the user
software immediately reacts to either of the bits
being set, a write collision may occur as indicated
by the WCOL bit being set.
Work around
To avoid a write collision one of the following
methods should be used:
Method 1: Add a software delay of one SCK
period after detecting the
completed transfer (the BF bit or
SSPIF bit becomes set) and prior
to writing to the SSPBUF register.
Verify the WCOL bit is clear after
writing to SSPBUF. If the WCOL
bit is set, clear the bit in software
and rewrite the SSPBUF register.
Method 2: As part of the MSSP initialization
procedure, set the CKE bit
(CKE = 1). |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19520
|
|
Posted: Thu Mar 22, 2018 3:46 pm |
|
|
OK.
The fact it works with some units suggests something like a timing issue. I've seen displays where here is a wide variation in start-up times needed between different units. The SPI bus itself ought to be timing independant, but things like the delays needed between commands may differ. Check the data sheet, and in particular look at the 'worst case' timings needed. Does the code meet all of these?. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|