Having trouble with Legacy interrupts (port from 26k22).

Beta Testing discussion on mikroC PRO for PIC.
Post Reply
Author
Message
davegsm82
Posts: 156
Joined: 29 Mar 2011 20:35

Having trouble with Legacy interrupts (port from 26k22).

#1 Post by davegsm82 » 02 Apr 2019 12:46

I've got a very large program that I've tried to port over from my project using an 18F26K22.

Everything works fine on the K22 using legacy interrupts (one level only, I don't need 2 level).

When I've tried to get it working on the K42 I'm just hitting a brick wall, my ISR is just called 'Interrupt()' as per the K22 and I assumed that since I've turned off the 'Multi Vector Enable bit' in config, and manually switched IPEN off by INTCON.B5 = 0 (because it doesn't exist in the 47K42 include file) that it would work as it did on the K22.

Unfortunately it doesn't, it never jumps to the ISR. Everything else seems to work ok, SPI, I2C and normal I/O for buttons and LED's, but timers or hardware interrupts don't fire the ISR.

Can anyone suggest something stupid that I'm missing? Once again, I'm tearing my hair out.

Regards, Dave.

User avatar
filip
mikroElektronika team
Posts: 11874
Joined: 25 Jan 2008 09:56

Re: Having trouble with Legacy interrupts (port from 26k22).

#2 Post by filip » 04 Apr 2019 08:13

Hi,

Can you please attach here the minimal project that represents this issue ?
Which version of the compiler are you using ?

Regards,
Filip.

davegsm82
Posts: 156
Joined: 29 Mar 2011 20:35

Re: Having trouble with Legacy interrupts (port from 26k22).

#3 Post by davegsm82 » 08 Apr 2019 23:23

filip wrote:Hi,

Can you please attach here the minimal project that represents this issue ?
Which version of the compiler are you using ?

Regards,
Filip.
Hi Filip.

Please find attached what is probably the minimal amount of code to show the issue, I apologise for the size of the code but it's cut down from the original 26K22 project on which I have tried to port it over from.

It consists of a 47K42, Nokia LCD display, UART1 to PC terminal, I2C2 to DS3231, 3x buttons.

I am using 7.3 Beta compiler.

There should be a Timer1 tick interrupt running that sets a flag as a system timer in the main loop, this doesn't work, none of the hardware interrupts work either IOC or INT. At the start of the interrupt routine you will see where I tried to use vectors but also failed.

None of the interrupts work in fact, the UART output is simply the 'main loop' repeated constantly.

Also I2C2 fails to work, If I leave in the code to read from DS3231 then the system hangs at this point. Scoping the PIC pins it looks like the clock pin never changes state even though I've set TRIS and ODCONB as per the help file specifically for the K42 series.

Lastly I know that my code is probably quite amateurish as this isn't my job and only a (very frustrating) hobby, also much of this code has followed me around for 5-6 years on various projects.

Regards, Dave.

Code: Select all

//--------------------IO Stuff-----------------------------------------

sbit Buzzer        at   LATC.B1;
sbit Buzzer_DIR    at   TRISC.B1;
sbit HV_drive      at   LATC.B2;
sbit HV_drive_DIR  at   TRISC.B2;
sbit Display_pwr       at  LATA.B4;
sbit Display_pwr_DIR   at  TRISA.B4;
sbit Backlight         at  LATA.B5;
sbit Backlight_DIR     at  TRISA.B5;
sbit MMC_pwr           at  LATC.B0;
sbit MMC_pwr_DIR       at  TRISC.B0;

sbit Button1           at  PORTB.B3;
//sbit Button2           at  portb.b1;
sbit Button2           at  PORTB.B0;
sbit Button3           at  PORTA.B2;

sbit Button1_dir       at  TRISB.B3;
//sbit Button2_dir       at  trisb.b1;
sbit Button2_dir       at  TRISB.B0;
sbit Button3_dir       at  TRISA.B2;

sbit Button1_op        at  LATB.B3;
//sbit Button2_op        at  latb.b1;
sbit Button2_op        at  LATB.B0;
sbit Button3_op        at  LATA.B2;


sbit PIN_LCD_CE_DIR at  TRISA.B6;   //Remember that RA6/7/ are transposed from normal pin order on 26k22.
sbit PIN_LCD_CE     at  LATA.B6;

sbit PIN_DC_DIR     at  TRISA.B7;
sbit PIN_DC         at  LATA.B7;

sbit PIN_SDIN_DIR   at  TRISC.B5;
sbit PIN_SDIN       at  LATC.B5;

sbit PIN_SCLK_DIR   at  TRISC.B3;
sbit PIN_SCLK       at  LATC.B3;

// End LCD module connections

int LCD_X  =   84;
int LCD_Y  =   48;
#define LcdOffset 4


float AUTOMESSUSV;

//-------------------DATA Bus addresses--------------------------------

char    Test_address = 0b00000000;

char    Seven_bit_CLOCK_address       = 0b01101000;            //DS3231  0x68       7-bit address version
char    Seven_bit_CLOCK_address_read  = 0b01101000;       //DS3231  0x68       7-bit address version
char    Seven_bit_CLOCK_address_Write = 0b01101000;      //DS3231

char    CLOCK_address_read = 0b11010001;       //DS3231  0xD0      8-bit address version
char    CLOCK_address_Write = 0b11010000;      //DS3231

//int    EEPROM_address_read =  0b10100111 ;  //For ATMEL 24C128
//int    EEPROM_address_write = 0b10100110 ;  //For ATMEL 24C128

//char    EEPROM_address_read =  0b10100001 ;  //For ATMEL 24LC256
//char    EEPROM_address_write = 0b10100000 ;  //For ATMEL 24LC256

int tones[10][2];

const char character[][6] = {
{0,66,36,255,90,36},         //0 Bluetooth Symbol
{0,254,131,129,131,254},     //1 Battery Empty
{0,254,195,193,195,254},     //2 20%
{0,254,227,225,227,254},     //3 40%
{0,254,243,241,243,254},     //4 60%
{0,254,251,249,251,254},     //5 80%
{0,254,255,255,255,254},     //6 100%
{0,60,36,36,66,255},         //7 Speaker Symbol
{31,21,17,248,168,136},      //8 EEPROM symbol
{0,0,6,9,9,6},               //9 Degree Symbol
{255,255,255,255,255,255},   //10 Full
{0,0,0,0,0,0},               //11 Blank
{0,31,8,151,168,72},         //12 uS
{0,6,1,147,169,78},          //13 mS
{0,8,4,250,33,248},          //14 /h
{0,14,63,251,63,14},         //15 GPS icon
{34,28,0,65,62,0},           //16 GPS Signal
{8,28,62,127,28,28},          //17 <- Arrow
{8,28,62,127,28,28},          //18 small x
{0,36,24,66,60,0},            //19 sound waves
{0,255,129,129,65,129},         //20 SD card 1/2
{129,193,85,85,127,0},          //21 SD card 2/2
{0,255,129,163,85,137},         //22 SD card ERROR 1/2
{149,163,85,85,127,0},          //23 SD card ERROR 2/2
{0,14,59,241,59,14},            //24 DGPS icon
{0,32,62,127,62,32},          //25 Bell icon
{32,58,119,46,32,0},          //26 Muted bell icon
{32,32,63,2,4,8},             //27 R/C icon
{16,16,32,32,0,0},             //28 R/C icon
{62,73,79,65,62,0,},          //29 Clock icon
};



//----------------Strings'n'tings-------------------------------
//char    RAMTEST[340];
char    DS1302_CLOCK_DATA[20]={0x00,0x00,0x00,0x01,0x00,0x00,0x14,0b10000000};
char    DS1302_TEMP_DATA[3]={0x00,0x00};
/*char    str[][10] = { "HELP" , "DUMP" , "CONTRAST=", "CLICK=LOW", "CLICK=HI", "CLICK=OFF", "CLICK=MAX", "BEEP",
"ERASE", "RESET", "POWER", "FACTORY", "VTUBE=", "AT" };*/
char    Record_header[17];
char    Record_Data[5];
char    EEPROM_Data[21];

char    Config_data[65];
char    DS1302_RAM_DATA[33]={0};   // was 31 elements, now 33.
char    txt[10];
char    TubeLeakage[10];
char    time_string[9];          // Holds time characters after conversion
char    temperature_string[9];   // Holds temperature characters after conversion
char    date_string[9];          // Holds date characters after conversion
char    char_string[22];         // Imcoming Data bytes from RS232
char    cmd_string[82];          // 40 bytes for ASCII commands
int     DO_AUTOMESS = 1;                  //tell system to calculate
int         AUTOMESS_GO = 0;                  //don't receive any more bytes.
char    AUTOMESS_string[7]; 
int     counter_array_minutes[61];
int     counter_array_Seconds[61];       // INT because may be large values
char    GPGGA_string[82];
char    GPS_string[6][82];          // 80 bytes for GPS position Data



//-----------------Variables-----------------------------------------

//-----------bits---------------------------------------------------------------
bit     button2Pressed;
bit     reinitLCD;
bit     initialised;
bit     Records_initialised, Record_header_set, Backlight_flash, autocontrast;//, buzzer_enable;
bit     HV_enable, warning_alarm , Warning_alarm_enable, BT_enable, EEPROM_backlight_enable;
bit     Warning_alarm_enable_temp;

bit     CRbit, CRLFbit, ClrAllBit, CRbit2, CRbit3, ClrAllBit2;
//------------Chars-------------------------------------------------------------

char    SD_logging_enable = 0;
char    LCD_TYPE = 0;
char    pos_row = 1;
char    pos_char = 19;
char    NewData = 0;
char    escape = 0,  option = 0, option_temp = 0, Res_count, seconds, count, day, month, year, minutes = 0x00, hours = 0x00; // Global date/time variables
char    flag1 = 0, flag2 = 0, flag3 = 0;
char    One_sec = 0, One_Min = 0;
char    RXBYTE = 0, RXBYTE2 = 0;
char    Buzzer_enable = 0;
char    Debug_sound_enable = 0;
char    Buzzer_enable_temp = 0;
char    MaxContrast = 220;
char    MinContrast = 140;
char    contrast = 0xaa;
char    ContrastOffset = 175;     // Defaults for
char    ContrastMultiplier = 9;   // Nokia Screen
char    PrevContrast = 0x00;
char    ch = 0;
char    loopy = 0;
char    I2c_byte = 0, I2c_byte2 = 0;

//-----------Floats-------------------------------------------------------------
float   vbat, bat_low = 3.15, bat_full = 4.2, SOC = 0.0, percent = 0.0;
float   AverageRC = 0;
float   DecayRC = 0.02;
float   AttackRC = 1.26;

int     NUMOERR = 0x00;
int     NUMFERR = 0x00;
int     RX2BYTES = 0x00;

int     Backlight_timer = 0;
int     Backlight_timer_backup = 0;
int     Backlight_timeout = 5;

int     posi = 0;
int     test1 = 0;
int     Screensaver = 0;
int     Screensaver_timeout = 10;
int     Screensaver_enable = 1;
int     uSvuR = 1;
int     Bigtime = 0;
int     button1counter = 0;
int     button3counter = 0;
int     Freq = 0;
int     Tone_duration = 0;
long int     Tone_period = 0xF830; // 0xF830 is 1KHz
int     Tone_period_High = 0;
int     Tone_period_low = 0;
int     mute = 0;
int     Pwr_counter = 0;
int     Mult1 = 1;
int     Div1 = 1;
int     t = 0;
int     v = 0;
int     VT = 0;
int     atvoltage = 0;
int     not_zero = 1;
int     count1;
int     AM = 0;
int     i = 0;  //******Edited out for MMC testing******
int     j = 0;
int     x=0;
int     HVloop;
int     I2c_EEPROM_present = 0;
int     I2c_DS3231_present = 0;
int     convert_value = 0;
int     end_of_file = 0;
int     sixtysecondaverage = 0;
int     cc2 = 0;
int     timeout = 5;
int     cw1 = 0;
int     cw2 = 0;
int     cw3 = 0;
int     cw4 = 0;  //Command Receive
int     cw5 = 0;  //GPS Receive
int     cw6 = 0;
int     col_pos_temp = 0;
int     col_pos = 0;
int     row_pos = 0;
int     one_ms = 0;
int     ten_ms = 0;
int     One_Second_count = 0;       //Seconds counter, starting from 0, counts to 59 and resets
int     One_Minute_count = 0;
int     One_hour_count = 0;
int     sixty_second_init = 0;
int     buzzer_repeat = 0;
int     average = 0;
int     loopcount = 0x00;
int     warnlevel = 50;
int     alarm_toggled_on = 0;
int     dp = 0, dp1 = 0;          //used in FloatToStr_NoExponent

int     onesecevent = 0;
int     onesecevent_backup = 0;
int     max_CPS = 0;
int     max_CPS_temp = 0;
int     fivesecaverage = 0;
int     fiveseccount = 0;
int     fivesec = 0;
int     Samples = 60;
int     sixtysecevent_backup = 0;
int     strln = 0;              // Used for length of string calculations.
unsigned int     Timer_Default = 0xb226;

int     Timer_sync_counter = 0;
int     q = 0;                    // Used for minutes array.
int     loopx = 0;                //

int     i_pos = 5;                // Used in LCD function
int     msg1 = 0;

int     result1 = 0;                 // Holds LOG values for position of data on LCD
int     CGPSS = 0;
float   usvvalue = 0.0;
float     sixtysecevent = 0;
float     sixtyminevent = 0;

const char ASCII[][5] = {
 {0x00, 0x00, 0x00, 0x00, 0x00} // 20     0
,{0x00, 0x00, 0x5f, 0x00, 0x00} // 21 !   1
,{0x00, 0x07, 0x00, 0x07, 0x00} // 22 "
,{0x14, 0x7f, 0x14, 0x7f, 0x14} // 23 #
,{0x24, 0x2a, 0x7f, 0x2a, 0x12} // 24 $
,{0x23, 0x13, 0x08, 0x64, 0x62} // 25 %
,{0x36, 0x49, 0x55, 0x22, 0x50} // 26 &
,{0x00, 0x05, 0x03, 0x00, 0x00} // 27 '
,{0x00, 0x1c, 0x22, 0x41, 0x00} // 28 (
,{0x00, 0x41, 0x22, 0x1c, 0x00} // 29 )
,{0x14, 0x08, 0x3e, 0x08, 0x14} // 2a *
,{0x08, 0x08, 0x3e, 0x08, 0x08} // 2b +
,{0x00, 0x50, 0x30, 0x00, 0x00} // 2c ,
,{0x08, 0x08, 0x08, 0x08, 0x08} // 2d -
,{0x00, 0x60, 0x60, 0x00, 0x00} // 2e .
,{0x20, 0x10, 0x08, 0x04, 0x02} // 2f /
,{0x3e, 0x51, 0x49, 0x45, 0x3e} // 30 0
,{0x00, 0x42, 0x7f, 0x40, 0x00} // 31 1
,{0x42, 0x61, 0x51, 0x49, 0x46} // 32 2
,{0x21, 0x41, 0x45, 0x4b, 0x31} // 33 3
,{0x18, 0x14, 0x12, 0x7f, 0x10} // 34 4
,{0x27, 0x45, 0x45, 0x45, 0x39} // 35 5
,{0x3c, 0x4a, 0x49, 0x49, 0x30} // 36 6
,{0x01, 0x71, 0x09, 0x05, 0x03} // 37 7
,{0x36, 0x49, 0x49, 0x49, 0x36} // 38 8
,{0x06, 0x49, 0x49, 0x29, 0x1e} // 39 9
,{0x00, 0x36, 0x36, 0x00, 0x00} // 3a :
,{0x00, 0x56, 0x36, 0x00, 0x00} // 3b ;
,{0x08, 0x14, 0x22, 0x41, 0x00} // 3c <
,{0x14, 0x14, 0x14, 0x14, 0x14} // 3d =
,{0x00, 0x41, 0x22, 0x14, 0x08} // 3e >
,{0x02, 0x01, 0x51, 0x09, 0x06} // 3f ?
,{0x32, 0x49, 0x79, 0x41, 0x3e} // 40 @
,{0x7e, 0x11, 0x11, 0x11, 0x7e} // 41 A
,{0x7f, 0x49, 0x49, 0x49, 0x36} // 42 B
,{0x3e, 0x41, 0x41, 0x41, 0x22} // 43 C
,{0x7f, 0x41, 0x41, 0x22, 0x1c} // 44 D
,{0x7f, 0x49, 0x49, 0x49, 0x41} // 45 E
,{0x7f, 0x09, 0x09, 0x09, 0x01} // 46 F
,{0x3e, 0x41, 0x49, 0x49, 0x7a} // 47 G
,{0x7f, 0x08, 0x08, 0x08, 0x7f} // 48 H
,{0x00, 0x41, 0x7f, 0x41, 0x00} // 49 I
,{0x20, 0x40, 0x41, 0x3f, 0x01} // 4a J
,{0x7f, 0x08, 0x14, 0x22, 0x41} // 4b K
,{0x7f, 0x40, 0x40, 0x40, 0x40} // 4c L
,{0x7f, 0x02, 0x0c, 0x02, 0x7f} // 4d M
,{0x7f, 0x04, 0x08, 0x10, 0x7f} // 4e N
,{0x3e, 0x41, 0x41, 0x41, 0x3e} // 4f O
,{0x7f, 0x09, 0x09, 0x09, 0x06} // 50 P
,{0x3e, 0x41, 0x51, 0x21, 0x5e} // 51 Q
,{0x7f, 0x09, 0x19, 0x29, 0x46} // 52 R
,{0x46, 0x49, 0x49, 0x49, 0x31} // 53 S
,{0x01, 0x01, 0x7f, 0x01, 0x01} // 54 T
,{0x3f, 0x40, 0x40, 0x40, 0x3f} // 55 U
,{0x1f, 0x20, 0x40, 0x20, 0x1f} // 56 V
,{0x3f, 0x40, 0x38, 0x40, 0x3f} // 57 W
,{0x63, 0x14, 0x08, 0x14, 0x63} // 58 X
,{0x07, 0x08, 0x70, 0x08, 0x07} // 59 Y
,{0x61, 0x51, 0x49, 0x45, 0x43} // 5a Z
,{0x00, 0x7f, 0x41, 0x41, 0x00} // 5b [
,{0x02, 0x04, 0x08, 0x10, 0x20} // 5c ¥
,{0x00, 0x41, 0x41, 0x7f, 0x00} // 5d ]
,{0x04, 0x02, 0x01, 0x02, 0x04} // 5e ^
,{0x40, 0x40, 0x40, 0x40, 0x40} // 5f _
,{0x00, 0x01, 0x02, 0x04, 0x00} // 60 `
,{0x20, 0x54, 0x54, 0x54, 0x78} // 61 a
,{0x7f, 0x48, 0x44, 0x44, 0x38} // 62 b
,{0x38, 0x44, 0x44, 0x44, 0x20} // 63 c
,{0x38, 0x44, 0x44, 0x48, 0x7f} // 64 d
,{0x38, 0x54, 0x54, 0x54, 0x18} // 65 e
,{0x08, 0x7e, 0x09, 0x01, 0x02} // 66 f
,{0x0c, 0x52, 0x52, 0x52, 0x3e} // 67 g
,{0x7f, 0x08, 0x04, 0x04, 0x78} // 68 h
,{0x00, 0x44, 0x7d, 0x40, 0x00} // 69 i
,{0x20, 0x40, 0x44, 0x3d, 0x00} // 6a j
,{0x7f, 0x10, 0x28, 0x44, 0x00} // 6b k
,{0x00, 0x41, 0x7f, 0x40, 0x00} // 6c l
,{0x7c, 0x04, 0x18, 0x04, 0x78} // 6d m
,{0x7c, 0x08, 0x04, 0x04, 0x78} // 6e n
,{0x38, 0x44, 0x44, 0x44, 0x38} // 6f o
,{0x7c, 0x14, 0x14, 0x14, 0x08} // 70 p
,{0x08, 0x14, 0x14, 0x18, 0x7c} // 71 q
,{0x7c, 0x08, 0x04, 0x04, 0x08} // 72 r
,{0x48, 0x54, 0x54, 0x54, 0x20} // 73 s
,{0x04, 0x3f, 0x44, 0x40, 0x20} // 74 t
,{0x3c, 0x40, 0x40, 0x20, 0x7c} // 75 u
,{0x1c, 0x20, 0x40, 0x20, 0x1c} // 76 v
,{0x3c, 0x40, 0x30, 0x40, 0x3c} // 77 w
,{0x44, 0x28, 0x10, 0x28, 0x44} // 78 x
,{0x0c, 0x50, 0x50, 0x50, 0x3c} // 79 y
,{0x44, 0x64, 0x54, 0x4c, 0x44} // 7a z
,{0x00, 0x08, 0x36, 0x41, 0x00} // 7b {
,{0x00, 0x00, 0x7f, 0x00, 0x00} // 7c |
,{0x00, 0x41, 0x36, 0x08, 0x00} // 7d }
,{0x10, 0x08, 0x08, 0x10, 0x08} // 7e ?
,{0x78, 0x46, 0x41, 0x46, 0x78} // 7f ?
,{0x00, 0x04, 0x0a, 0x04, 0x00} // 80 ?
};

const char two[] = "201";
const char stop[] = ".";
const char colon[] = ":";

static union {    //Union is used to convert a float into 4 discrete bytes
 float yf;        //so that values can be stored/retrieved from EEPROM
 char yc[4];      //Float goes into yf (float values are 4 bytes long)
                  //and those 4 bytes can be read from yc[x]
};



void Interrupt(){
//void Interrupt() iv 0x0018 ics ICS_OFF {  //Low Interrupt vector  "Invalid Interrupt address"
//void Interrupt() iv 0x0008 ics ICS_OFF {  //High Interrupt vector   Causes boot-looping



      int k = 2;
      int z = 0;

//-----------------clear USART errors-------------------------------------------------
//if (RCSTA2.OERR==1) {   // Overrun Error   voir parag 16.1.26 p273
if (U2ERRIR.U2RXFOIF==1) {   // FIFO OverFLOW Error   voir parag 16.1.26 p273
        U2CON1.U2ON = 0;
        //RCSTA2.CREN = 0 ;
        NUMOERR++;
        U2CON1.U2ON = 1;
        //RCSTA2.CREN = 1 ;
       }
//if(RCSTA2.FERR==1 ){  // Framing Error
 if(U2ERRIR.U2FERIF==1 ){  // Framing Error
        U2CON1.U2ON = 0;   //Clear ERROR by switching off USART momentarily.
        //RCSTA2.SPEN = 0 ;
        NUMFERR++;
        U2CON1.U2ON = 1;
        //RCSTA2.SPEN= 1 ;
       }

//-----------------Timer Interrupts---------------------------------------------

  if (TMR0IF_bit){         //--------timer 0 interrupt flag-----------------------------
       INTCON.TMR0IF = 0;  // clear the flag  --------Still Used for clicks or beeps---------------------------
       T0CON0.T0EN  = 0;  // Switch off the Timer
       INTCON.TMR0IE = 0;  // Disable the Interrupt until next click
                                  //--------Values are reloaded in RBIF below------------------
       if(warning_alarm == 0){   //--------Warning_alarm is set by warning alarm function
         buzzer = 0;            // Switch off PORTC bit2 BUZZER
       }
       if(backlight_flash){
        Backlight = 0;
       }


  }

  if (TMR1IF_bit){                //----------1ms timer----------------------
    TMR1IF_bit = 0;               //----------Used for system clock----------

    //---------------------For a 10ms tick, then values would be....--------
       TMR1H         = 0xB1;         // Delay for 8MHz
       TMR1L         = 0xf8;        //E0
    // }
     ten_ms++;
     flag1 = 1;

    //----------------------Important 1-sec functions here-------------------------------------------------------
    if (ten_ms >= 100){                                 // this counts to 1 second,
        ten_ms = 0;
        One_sec = 1;                                       //One_Sec INDICATES 1 sec
        Timer_sync_counter++;                              //Used for Timer sync function.

        AverageRC = AverageRC - (AverageRC * DecayRC );    // /AverageRCDivisor);

        //-------------------Storing data in seconds array----------------------------------------
        counter_array_seconds[One_Second_Count] = onesecevent; //onesecevent is number of interrupts that second and is placed into the array
        if(onesecevent > max_CPS_temp){                    // If the max counts that sec was more than preceeding
          max_CPS_temp = onesecevent;                      // then store that in Temp.
        }

        onesecevent = 0;                                   //Zero this seconds count
        One_Second_Count++;                                // ?


        sixtysecevent = 0;                                 //Zero the average count for 60s
        for (loopy=0;loopy<Samples;loopy++){               //Add up all the values in the array
         sixtysecevent += counter_array_Seconds[loopy];    //add up contents of array from 0 to 'samples'
        }
        //--------------------End of Storing data in Seconds Array--------------------------------
        //--------------------Storing data in minutes array---------------------------------------
        if(One_Second_Count > Samples ){                   //If more than 60s have elapsed
         One_min = 1;                                      //Flag 3 for Main control loop
         One_Second_Count = 0;                             //One_Second_Count is a rolling count.
         sixty_second_init = 1;                            //Indicate that 60 seconds has elapsed
         max_CPS = max_CPS_temp;                           //Store max CPS ready to save to file.
         max_CPS_temp = 0;                                 //Zero the temp max CPS ready to start again.
         Counter_array_minutes[One_minute_count] = sixtysecevent;    //Add the 60s total to another array
         One_Minute_count++;                               //Increment the array position.
         sixtyminevent = 0;                               //Zero 1 hour average
          if(loopx<(samples)){
           loopx++;                                        //'loopx' starts at zero and counts up for the 1 hour average
          }

          for (loopy=0;loopy<loopx;loopy++){               //Add up all the values in the array
           sixtyminevent += counter_array_minutes[loopy];  //add up contents of array from 0 to 'r'
          }
          sixtyminevent = sixtyminevent/loopx;             //Make an average, loopx never zero's, gets to 60 and stops.
         //---------------------End of Storing data in Seconds Array-----------------------------------

         if(One_minute_count > samples){
          One_minute_count = 0;                       //'One_minute_count' is the position in the 1 hour average array
         }                                            //and it rolls around back to zero
                                                      //but it doesn't reset.

        }

     } //---------------End of important 1 sec functions-------------------------
  }

//------------------------------------------------------------------------------
//---------------------Sound generator------------------------------------------
//------------------------------------------------------------------------------


  if (TMR6IF_bit){  //----TMR6 used for length of tone---------------------------
    TMR6IF_bit = 0;

    if(Tone_duration >= 1){ //if there's tone time remaining, subtract from Duration------
     Tone_duration--;  //Subtract from Duration------
     TMR3IE_bit = 1;   //Re-enable timer to start/continue sound------------
     TMR3ON_BIT = 1;
    }

    else{  //Load next tone here--------------------------------

      if(tones[0][0] >= 1){
       Tone_duration = tones[0][0]; //Play the tone in position 0-------
       Tone_period   = tones[0][1];
       tones[0][0] = 0x00;
       tones[0][1] = 0x00;

       tones[9][0] = 0x00;   //Blank the last tone in the array---------
       tones[9][1] = 0x00;
       if(tones[1][0] >= 1){       //If there's another tone in the array-----
        for(z=0;z<9;z++){         //Move it to the zero position.
         tones[z][0] = tones[z+1][0];
         tones[z][1] = tones[z+1][1];
        }
       }
       else{
        tones[0][0] = 0x00;  //If no other tones in array, Blank tone in Pos - 0.
        tones[0][1] = 0x00;
       }

       TMR6IE_BIT = 1;              //Start timer to play tone----------
       TMR3IE_BIT = 1;              //Start timer to Toggle Buzzer------
       TMR6ON_bit = 1;              //Switch on Timers.-----------------
       TMR3ON_bit = 1;

      }
      //----------------------------------------------------



     else{              //No more sound to play.
      TMR3ON_bit = 0;   //Stop the timer.
      TMR3IE_bit = 0;   //Disable sound generation interrupt
      TMR3IF_bit = 0;   //Clear the flag.

      TMR6ON_bit = 0;   //Stop the timer.
      TMR6IE_bit = 0;   //Diable this Interrupt so it doesn't run next time.
      TMR6IF_bit = 0;   //Clear it's flag too.
      Buzzer = 0;       //Sound is finished, turn off sounder.
     }
     //---------------------------------------------------
    }
  }

 if (TMR3IF_bit){
    TMR3IF_bit = 0;
    if(tone_duration){                   //If there's time left on this tone,
     TMR3H         = Tone_period >> 8 ;  //Load the time period value
     TMR3L         = tone_period;        //Into H and L.
     Buzzer = ~buzzer;                   //Toggle the sounder pin
    }
    else{                                //If sound has ended,
     Buzzer = 0;                         //Turn off the Buzzer.
    }

  }


//---------------Hardware Interrupts--------------------------------------------
  if(intcon.INT1IF){
  intcon.INT1IF = 0;
  }
 if(intcon.INT2IF){
 intcon.INT2IF = 0;
  }

  if(intcon.INT0IF){    //------Button 2 (Menu/PWR)-----------------
       intcon.INT0IF = 0;
       delay_ms(1);
       if(button2){
       Pwr_counter = 0;
        while(Button2 & Pwr_counter < 10){
         delay_ms(100);
         Pwr_counter++;
         if(Pwr_counter >= 10){
          //sleepy_time = 1;
          intcon.INT0IF = 0;
          break;
         }
        }

        if(pwr_counter <=9){
          button2Pressed = 1;
        }

       }

      }

     //-------------------------------------------------------------------------
     //------------------------PortB Interrupt for counts-----------------------
     //-------------------------------------------------------------------------

     //if(INTCON.RBIF){
     if(PIR0.IOCIF){                                     // Generic IOC Flag set (for any IOC change)
      IOCBF = 0;                                          // Clear whole register for testing ****
      //IOCBF.IOCBF4 = 0;                                   // CLEAR INTERRUPT FLAG
      onesecevent++;                                     // Counts the number of events that second.
      AverageRC = AverageRC + (1.0 * AttackRC);          // For RC averaging.
       if (buzzer_enable >= 1 && warning_alarm == 0) {   // If enabled using the Right button...
       //--------short click-------------------------
        switch(buzzer_enable){
           case 1 : {          //LOW
           TMR0H = 0xf8;
           TMR0L = 0x00;                  // RELOAD preset for timer register
           break;
           }
           case 2 : {          //Hi
           TMR0H = 0xee;
           TMR0L = 0x00;                  // RELOAD preset for timer register
           break;
           }
           case 3 : {          //BEEP
           TMR0H = 0xa6;
           TMR0L = 0x00;                  // RELOAD preset for timer register
           break;
           }
         }


       INTCON.TMR0IE = 1;           // enable the Interrupt to start timer
       INTCON.TMR0IF = 0;           // clear the flag
       T0CON0.T0EN = 1;            // Start the timer.

        buzzer = 1;                // Switch on the buzzer..
        if(backlight_flash){
         Backlight = 1;
        }

       }

     }

//------------------------------------------------------------------------------
//---------------------------USART Interrupt------------------------------------
//------------------------------------------------------------------------------

     if (PIR1.RC1IF){               //if a byte was received
       RXBYTE = UART1_Read();      //get the byte from the UART

       if(RXBYTE == 0x02){
        AUTOMESS_GO = 1;
       }

       if(AUTOMESS_GO){
        if(cw6 <= 5){                       //If Array isn't full
          AUTOMESS_string[cw6] = RXBYTE;   //store the received byte in the array
          cw6++;                           //increment the postition counter
        }
        if(cw6 == 6){                      //Once all 6 bytes received (bytes 0 to 5).
         DO_AUTOMESS = 1;                  //tell system to calculate
         AUTOMESS_GO = 0;                  //don't receive any more bytes.
        }

       }

      //------------TRAP a CR + LF by only setting CRLF bit----------------
      //------------if they are received consecutively.--------------------
       if(RXBYTE == 13){           //If the character is <CR> (enter key)
        if(CRbit == 1){           //if the <CR> indicator is already set
         ClrAllBit = 1;          //clear the array
        }
        CRbit = 1;
       }

       else if(RXBYTE == 10 && CRbit == 1){
        CRLFbit = 1;
       }
      //---------------------------------------------

       else{//then maybe an ELSE for everything else here...
        if(cw4 >= 40){               //If command is more than 40 chars
         ClrAllBit = 1;             //then clear the array
        }
        else if(cw4 <= 39){                //If Array isn't full
         //if(RXBYTE != 10 && RXBYTE != 13){           //Strip out LF and CR characters
          cmd_string[cw4] = RXBYTE;   //store the received byte in the array
          cw4++;                      //increment the postition counter
         //}

        }

       }   //end of the ELSE for Everything else.
      PIR1.RC1IF = 0;                //Clear the received byte indicator
      }
      //-----------------------------------------------------------------------

      if (PIR6.U2IF){               //if a byte was received
       RXBYTE2 = UART2_Read();            //get the byte from the UART
       //---------------------Received byte was a CR------------------------------
       if(RXBYTE2 == 13){                 //If the character is <CR> (enter key)...
        if(cw5 >= 1){                     //AND If position counter is greater or equal to one
         CRbit2 = 1;                      //set the CR indicator
         GPS_string[CGPSS][cw5] = 0x00;   //Add Null at end           ****
         GPS_string[CGPSS][81] = 0x01;    //Byte 81 is flag

        }
        cw5 = 0;                           //Go back to start of string  ****
        while(GPS_string[CGPSS][81] == 0x01 && k){                  //    ***
         CGPSS++;                          //String number CGPSS needs to be processed so...
         if(CGPSS >= 6){                   //Move to next string or reset to start
          CGPSS = 0;                       //Reset to String zero.
         }
         k--;                              //Don't get stuck in the loop.  ***
        }

       }
       //----------------------Recived by wasn't a CR or LF---------------------
       else{
         if(cw5 >= 80){                            //If command is more than 82 chars
          cw5 = 0;                                 //Then the string would overflow
         }                                         //So set Pos counter to 0.
         else if(cw5 <= 79){                       //If Array isn't full
          if(RXBYTE2 >= 32 && RXBYTE2 <= 127){     //Omit Control characters
           GPS_string[CGPSS][cw5] = RXBYTE2;       //store the received byte in the array
           cw5++;                                  //increment the postition counter
          }

         }
       }
      }
//--------------------------------------------------------------------------------------

}

void clear_array(int * array1, int elements){

  i = 0;
  while (i <=  elements ){
   array1[i] = 0;
   i++;
  }

}


//----------------Initialisation-------------------------------------

void Init_Main() {
  TRISA = 0b00000111 ;    //LCD_DC,LCD_CE,BL,LCD_PWR,MMC_CS,But3, HVin, BattIn.
  TRISB = 0b11011001 ;    //RS232 (x2), N/C, Tube counts, LCD+SD (x3), Button 2.
  TRISC = 0b10100000 ;    //Rs232 in, RS232 out,But1,SPI-DO,SPI-DI,SPI-CK,HV-OP,Sound.
  TRISD = 0b00000000 ;
  TRISE = 0b00000000 ;

  ANSELA = 0b00000011 ;   //Tube Volts, Battery Volts,*All other digital*
  ANSELB = 0b00000000 ;   //Nothing else analogue
  ANSELC = 0b00000000 ;   //Nothing else analogue
  ANSELD = 0b00000000 ;   //Nothing else analogue
  ANSELE = 0b00000000 ;   //Nothing else analogue
   NVMMD_bit = 1;
                      //-----in PMD, a '1' disables a module.
  PMD0 = 0b00111001 ; //Disable Peripheral module  SysClock,FVR,HVLV,CRC,NVM,CLKREF,IOC
  PMD1 = 0b11000000 ; //Disable Peripheral module  Timers
  PMD2 = 0b01100111 ; //Disable Peripheral Module  ADC/DAC
  PMD3 = 0b00000000 ; //Disable Peripheral Module  PWM's
  PMD4 = 0b11100000 ; //Disable Peripheral Module  complimentary waveform gen
  PMD5 = 0b00000000 ; //Disable Peripheral Module  UARTs, I2C and SPI
  PMD6 = 0b00111111 ; //Disable Peripheral Module  Logic cell and signal modulator
  PMD7 = 0b00000011 ; //Disable Peripheral Module  DMA


  //-------to use internal 8MHz clock, set clock freq to 8.000 in project options and...----
   OSCFRQ = 0b00000011;       //Set osc to 8MHz.


   intcon0             = 0x00;
   intcon0.GIE         = 1;    //Enable interrupts
   intcon0.INT0EDG     = 1;    //Button/GM Pulses positive going
   intcon0.b5          = 0;    //Interrupt Priority enable AKA 'IPEN'

  IOCAP = 0x00;
  IOCBP = 0x00;
  IOCCP = 0x00;
  IOCEP = 0x00;

  IOCAN = 0x00;
  IOCBN = 0x00;
  IOCCN = 0x00;
  IOCEN = 0x00;

//-----------Peripheral interrupts-------------------------------

  pie1         = 0x00; //TMR1 and TMR2 Disabled
  pie2         = 0x00;
  pie3         = 0x00;
  pie4         = 0x00;
  pie5         = 0x00;
  pie6         = 0x00;

  pie1.INT0IE  = 1;    //Enable PortB interrupt. (Int0 is button 2)
  pie3.U1IE    = 1;    //Enable USART1 receive
  pie3.TMR0IE  = 1;    //TMR0 Interrupt Enable     TMR0 is for clicks
  pie4.TMR1IE  = 1;    //TMR1 Interrupt Enable     TMR1 is for 1ms Sys clock
  pie6.U2IE    = 1;     //Enable USART2 Recieve
  
  CM1CON0 = 0x00;
  CM2CON0 = 0x00; //Turn off comparators.

 //-----------High/Low Priority interrupts-----------------------

/*ipr0          = 0x00;   //All interrupts low priority
    ipr1          = 0x00;   //All interrupts low priority
    ipr2          = 0x00;   //All interrupts low priority
    ipr3          = 0x00;   //All interrupts low priority
    ipr4          = 0x00;   //All interrupts low priority
    ipr5          = 0x00;   //All interrupts low priority
    ipr6          = 0x00;   //All interrupts low priority
    ipr7          = 0x00;   //All interrupts low priority
    ipr8          = 0x00;   //All interrupts low priority
    ipr9          = 0x00;   //All interrupts low priority
    ipr10         = 0x00;   //All interrupts low priority*/

/*ipr0          = 0xff;   //All interrupts high priority
    ipr1          = 0xff;   //All interrupts high priority
    ipr2          = 0xff;   //All interrupts high priority
    ipr3          = 0xff;   //All interrupts high priority
    ipr4          = 0xff;   //All interrupts high priority
    ipr5          = 0xff;   //All interrupts high priority
    ipr6          = 0xff;   //All interrupts high priority
    ipr7          = 0xff;   //All interrupts high priority
    ipr8          = 0xff;   //All interrupts high priority
    ipr9          = 0xff;   //All interrupts high priority
    ipr10         = 0xff;   //All interrupts high priority*/

  //--------------------------------------------------------------
  PIR0 = 0x00;     //Peripheral Interrupt Flags
  pir1 = 0x00;     // Flags, not config registers
  pir2 = 0x00;     // Flags, not config registers

  //ADCON0 = 0b00000011;  //  xxccccsg - c=channel s=start/stop g=go
  //ADCON1 = 0b00011001;  //  xx-+pppp - -/+=Reference cfg (Int=0/Ext=1) p=port config (A/D)
  ADCON2 = 0b10110000;  //  Right Justified - Aquisition time/clock & output format

  //----------------------------------------------------------
  ODCONA = 0x00;             //All port A Totem pole
  ODCONB = 0x00;             //Set I2C2 pins (RB1, RB2) as Open Collector, as per help file for I2C.
  ODCONB.B1 = 1;
  ODCONB.B2 = 1;
  ODCONC = 0x00;             //All port C Totem pole
  ODCOND = 0x00;             //All port D Totem pole
  ODCONE = 0x00;             //All port E Totem pole

  }

void Init_PWM(){
                 //pwm2
                 pwm1_init(3100);
                 pwm1_set_duty(50);
                 pwm1_start();
}


void Init_timers(){



//----------------------TMR0-------------------------------------------------
 //Timer0 Registers Prescaler= 32 - TMR0 Preset = 67 - Freq = 826.72 Hz - Period = 0.001210 seconds
  /*T0CON.T08BIT = 1; // bit 6 - 8 bit timer/counter
  T0CON.T0CS = 0;  // bit 5  TMR0 Clock Source Select bit...0 = Internal Clock (CLKO) 1 = Transition on T0CKI pin
  T0CON.T0SE = 0;  // bit 4 TMR0 Source Edge Select bit 0 = low/high 1 = high/low
  T0CON.PSA = 0;   // bit 3  Prescaler Assignment bit...0 = Prescaler is assigned to the Timer0
  T0CON.T0PS2 = 1;   // bits 2-0  PS2:PS0: Prescaler Rate Select bits
  T0CON.T0PS1 = 0;
  T0CON.T0PS0 = 0;

  TMR0L = 67;             // preset for timer register
  TMR0H = 0;*/

//----------------------TMR0-short click----------------------------------------------------

  T0CON0.b7 = 1;  // Enabled
  T0CON0.MD16 = 0;  // Operate as 8 bit timer
  T0CON0.b3 = 0;  // Enabled
  T0CON0.b2 = 0;  // Enabled
  T0CON0.b1 = 0;  // Enabled
  T0CON0.b0 = 0;  // Enabled


  T0CON1.T0CS2 = 0;   // bits 2-0  PS2:PS0: Prescaler Rate Select bits
  T0CON1.T0CS1 = 1;   // bits 2-0  PS2:PS0: Prescaler Rate Select bits   - Select HFINTOSC
  T0CON1.T0CS0 = 1;   // bits 2-0  PS2:PS0: Prescaler Rate Select bits
  T0CON1.ASYNC = 0;   // Synchronised to INTOSC
  T0CON1.T0CKPS3 = 1;
  T0CON1.T0CKPS2 = 0;   // bits 3-0  PS3:PS0: Prescaler Rate Select bits
  T0CON1.T0CKPS1 = 0;   // Select 1:1
  T0CON1.T0CKPS0 = 0;

  TMR0L = 0xFF;             // preset for timer register
  TMR0H = 0x06;

//-----------------------TMR1-1ms repeating for timing---------------------------------------

  T1CLK         = 0x02;            //  x,x,x,CS(5)  TMR1 Clock source = HFINTOSC   PG316
  T1CON         = 0x01;            //  x,x,CKPS1,CKPS0,x,/Sync,RD16,ON             PG314          //     TMR1ON,PRE,PRE,PRE,POST,POST,POST,POSTscalers
  TMR1IF_bit    = 0;               // Clear flag
  TMR1H         = 0xF8;            // For 8MHz
  TMR1L         = 0x30;

  //TMR1H         = 0xEC;     // For 20MHz
  //TMR1L         = 0x78;

  PIE4.TMR1IE         = 1;     // Enable TMR1 interrupt
  T1CON.TMR1ON         = 1;     // Timer is NOT gated by external pin

//-----------------------TMR3 Used for sound generation-------------------------------

  T3CON           = 0x01;
  TMR3IF_bit      = 0;
    TMR3H         = 0xF6;
    TMR3L         = 0x3C;
  TMR3IE_bit      = 1;

//------------------------TMR6 used for sound generation-----------------------------

  T6CON         = 0x3C;
  TMR6IE_bit    = 0;
  PR6           = 249;


//---------------------Turn on Interrupts-------------------------

  INTCON0         = 0xC0;      // Turn on GIE and GIEL

}

//----------RAM SAVER----------------

char * CopyConst2Ram(char * dest, const char * src){
  char * d ;
  d = dest;
  for(;*dest++ = *src++;)
    ;
  return d;
}

//----------------PCD8544 Display-----------------------------------

void LCD_ShiftOut(char dat2){
  int index3 = 0;
  PIN_SCLK = 0;
  PIN_SDIN = 0;
  //DELAY_US(10);
   for (index3 = 0; index3 < 8; index3++){      //index3 <= 8;        ****
    PIN_SCLK = 0;
    DELAY_US(10);
    PIN_SDIN = dat2.f7;
    dat2 = dat2 << 1;
    PIN_SCLK = 1;
    DELAY_US(10);
   }
  PIN_SCLK = 0;
}

void LcdWrite(char Data_not_command, char dat1){

  SPI1CON0.SPI1SPIEN = 0;
  //ssp2con1.sspen = 0;   //Disable SPI port while writing to screen.
  PIN_SCLK_DIR = 0;
  PIN_DC = Data_not_command.b0;
  PIN_LCD_CE = 0;
  LCD_shiftOut(dat1); //function as above
  //spi2_init();
  //spi2_write(dat1);
  PIN_LCD_CE = 1;
  SPI1CON0.SPI1SPIEN = 1;
  //ssp2con1.sspen = 1;
}

void LcdSetCursorPos(int x_pos, int y_pos){

  if(LCD_TYPE == 0){
   LcdWrite(0, (0x80 | (6*x_pos)));   //for Nokia
   LcdWrite(0, (0x40 | y_pos));
  }
  else if(LCD_TYPE == 1){
   LcdWrite(0,(((6*x_pos)+ LcdOffset >>4)&0x0f)+0x10); //Write upper 4 bits
   LcdWrite(0,(6*x_pos)+ LcdOffset &0x0f);             //Write Lower 4 bits
   LcdWrite(0, (0xb0 | y_pos ));
  }


}

void LcdCharacter(char character){
  int index1 = 0;
  LcdWrite(1, 0x00);
  for (index1 = 0; index1 < 5; index1++)
  {
    LcdWrite(1, ASCII[character - 0x20][index1]);     //k42error
  }
}

void LCDWritesymbol(int x_pos, int y_pos, char ch){
  int index2;
  LcdSetCursorPos(x_pos, y_pos);

  for (index2 = 0; index2 < 6; index2++)
  {
    LcdWrite(1, character[ch][index2]);
  }
}

void LcdClearLine(int x_pos, int y_pos, int spaces){
  int index2;
  LcdSetCursorPos(x_pos, y_pos);

  for (index2 = x_pos; index2 < (x_pos + spaces); index2++){
    LcdWrite(1, 0x00);
    LcdWrite(1, 0x00);
    LcdWrite(1, 0x00);
    LcdWrite(1, 0x00);
    LcdWrite(1, 0x00);
    LcdWrite(1, 0x00);
  }
}

void LcdClear(void){   //Uses Dimensions LCD_X and LCD_Y to clear full LCD
  int index3;
  LcdSetCursorPos(0,0);
  for (index3 = 0; index3 < LCD_Y / 8; index3++) //Assumes 8 pixels high
   {
     LcdClearLine(0, index3, (LCD_X/6));   //(x_pos, y_pos, number of characters (assumes 6px wide))
   }
}

void LcdInitialise(void){
SPI1CON0.SPI1SPIEN = 0;
//ssp2con1.sspen = 0;        //Turn off SPI interface (for SD card)
PIN_LCD_CE_DIR = 0;
PIN_DC_DIR     = 0;
PIN_SDIN_DIR   = 0;
PIN_SCLK_DIR   = 0;

if(LCD_TYPE == 0){

  LcdWrite(0, 0x21 );    // LCD Extended Commands.    1 = Data, 0 = CMD
  LcdWrite(0, contrast );// Set LCD Vop (Contrast).
  //LcdWrite(0, 0xb6 );  // Set LCD Vop (Contrast).
  LcdWrite(0, 0x04 );    // Set Temp coefficent. //0x04
  LcdWrite(0, 0x13 );    // LCD bias mode 1:48.  //0x13  0x14 is better
  LcdWrite(0, 0x20 );    // LCD Basic Commands
  LcdWrite(0, 0x0c );    // LCD in normal mode.
  //LcdWrite(0, 0x0D );  // LCD in Inverted mode.

  }

else if (LCD_TYPE == 1){
    LCD_X = 128;
    LCD_Y = 64;
    LcdWrite(0, 0xe2 );    //  Soft Reset.
    delay_ms(6);
    LcdWrite(0, 0xAF );    //  1 - Display ON
    LcdWrite(0, 0x40 );    //  2 - Start line 0 (0x40 + Line)
    LcdWrite(0, 0xB3 );    //  3 - Start Page 0 (0xB0 + page)
    LcdWrite(0, 0x00 );    //  4 - Column Addr High 4 set/Column Addr upper 4 Bits
    LcdWrite(0, 0x10 );    //  4 - Column Addr Low 4 set/Column Addr lower 4 Bits

    LcdWrite(0, 0xA1 );    //  8 - Normal Column scan order (L to R) not "ADC Select = 0" apparently (tested)
    LcdWrite(0, 0xA6 );    //  9 - Invert colours (A6 = Normal, A7 = invert)
    LcdWrite(0, 0xA4 );    //  10 - Display Test (A4 off, A5 on - displays all pixels)
    LcdWrite(0, 0xA2 );    //  11 - Bias 1/9  (A2 = 1/9, A3 = 1/7)
  //LcdWrite(0, 0xE0 );    //  12 - Read-Modify-Write (Not used on SPI version of display)
  //LcdWrite(0, 0xEE );    //  13 - Read-Modify-Write END (Not used on SPI version of display)
  //LcdWrite(0, 0xe2 );    //  14 - Soft Reset.
    LcdWrite(0, 0xC0 );    //  15 - Reverse Line Scan order (C0 = Normal, C8 = Bottom up)
    //LcdWrite(0, 0x2C );    //  16 - "Internal Rise Voltage" = on
    //delay_ms(5);
    //LcdWrite(0, 0x2E );    //  16 - "Voltage Regulation Circuit" = on
    //delay_ms(5);
    LcdWrite(0, 0x2F );    //  16 - "Voltage Follower" = on
    //delay_ms(5);
    LcdWrite(0, 0x23 );    //  17 - Coarse Contrast - 0x20 to 0x27 (Ra/Rb)
    LcdWrite(0, 0x81 );    //  18 - Fine Contrast - 0x00 to 0x3F
    LcdWrite(0, 0x28 );    //   Fine tune value of contrast(?) - Range 0x00 - 0x3F
    LcdWrite(0, 0xAC );    //  19 - Static Icon Display Switch (AC = off, AD = on)
    LcdWrite(0, 0xAF );    //  Display ON
  }

  //ssp2con1.sspen = 1;    // Turn on SPI interface (for SD card)
 SPI1CON0.SPI1SPIEN = 1;
}


void LcdString(int x_pos, int y_pos, char *characters){

  LcdSetCursorPos(x_pos, y_pos);

  while(*characters > 31 && *characters < 127 && x_pos < 14)  //Don't print control chars and less than LCD width
  {
    LcdCharacter(*characters++);    //increment position counter of Characters.
    x_pos++;
  }
}

//-----------------END OF LCD STUFF----------------------------------------------

void UART_CRLF(){
                    UART1_Write(13);
                    UART1_Write(10);
}

void UART_State(char state1){
                    UART1_Write('s');
                    UART1_Write('t');
                    UART1_Write('a');
                    UART1_Write('t');
                    UART1_Write('e');
                    UART1_Write('-');
                 UART1_Write(state1);
                 UART_CRLF();
}



void LcdCharacterWideTall(char character, int line){
  int index6;
  int length_of_char = 5;
  char ch2, ch3;
  LcdWrite(1, 0x00);
  if(character == ':'){
   length_of_char = 4;    //added to get rid of excessive 0x00 in ':' spaces for LCD optimisation
  }

  for (index6 = 0; index6 < length_of_char; index6++)
  {
    ch2 = ASCII[character - 0x20][index6];
    if (line == 0){
    ch3.B0 = ch2.b4;
    ch3.B1 = ch2.b4;
    ch3.B2 = ch2.b5;
    ch3.B3 = ch2.b5;
    ch3.B4 = ch2.b6;
    ch3.B5 = ch2.b6;
    ch3.B6 = ch2.b7;
    ch3.B7 = ch2.b7;
    }
    else{
    ch3.B0 = ch2.b0;
    ch3.B1 = ch2.b0;
    ch3.B2 = ch2.b1;
    ch3.B3 = ch2.b1;
    ch3.B4 = ch2.b2;
    ch3.B5 = ch2.b2;
    ch3.B6 = ch2.b3;
    ch3.B7 = ch2.b3;
    }

    LcdWrite(1, ch3);
    LcdWrite(1, ch3);
  }

}

 void LcdCharacterWide(char character){
  int index7;
  LcdWrite(1, 0x00);
  for (index7 = 0; index7 < 5; index7++)
  {
    LcdWrite(1, ASCII[character - 0x20][index7]);
    LcdWrite(1, ASCII[character - 0x20][index7]);
  }
}

void LcdStringWide(int x_pos, int y_pos, char *characters){
  LcdSetCursorPos(x_pos, y_pos);

  //while(*characters){
  while(*characters > 31 && *characters < 127 && x_pos < 14){
    LcdCharacterWide(*characters++);
    x_pos++;
  }

}

void LcdStringWideTall(int x_pos, int y_pos, char *characters){

  int chrcount = 0;
  //int nullcounter = 0;

  for(i=0;i<2;i++){
   chrcount = 0;
   //nullcounter = 0;
    //LcdWrite(1, 0xff);
   LcdSetCursorPos(x_pos, y_pos-i);

   while(*(characters + chrcount)){       //Runs until null char is found in array.

      LcdCharacterWideTall(*(characters + chrcount), i);
      LcdCharacterWideTall(*(characters + chrcount), i);
      chrcount++;

   }
  }
}

void LcdChar(int x_pos, int y_pos, char *character){
  LcdSetCursorPos(x_pos, y_pos);
  LcdCharacter(*character);

}

//------------------End of PCF8544 stuff-------------------------






void Display_Time(int row, int col, int tall) {


  //------------Separate Data and Send data to the LCD----------------------------------------
   time_string[0] =  ((((DS1302_CLOCK_DATA[2] & 0x30)  >> 4))+48);
   time_string[1] =  ((DS1302_CLOCK_DATA[2] & 0x0F)+48);
   time_string[2] =  ':';
   time_string[3] =  ((((DS1302_CLOCK_DATA[1] & 0x70) >> 4))+48);
   time_string[4] =  ((DS1302_CLOCK_DATA[1] & 0x0F)+48);
   time_string[5] =  ':';
   time_string[6] =  ((((DS1302_CLOCK_DATA[0] & 0x70)  >> 4))+48);
   time_string[7] =  ((DS1302_CLOCK_DATA[0] & 0x0F)+48);
   time_string[8] =  0x00;


   if(tall){
    time_string[5] =  0x00;
    row++;
    LcdClearLine(col,row-1,9);
    LcdClearLine(col,row,9);
    LCDstringWideTall(col,row,ltrim(time_string));
    time_string[5] =  ':';
   }
   else{
    LcdString(row,col,time_string);
   }
}


void Display_Date(int row, int col){     // Prepare and output static text on LCD

   date_string[0] = (((DS1302_CLOCK_DATA[4] >> 4) & 0x03) +48);    // Print tens digit of day variable
   date_string[1] = ((DS1302_CLOCK_DATA[4] & 0x0F ) +48);          // Print ones digit of day variable
   date_string[2] = '/';
   date_string[3] = (((DS1302_CLOCK_DATA[5] >> 4) & 0x01) +48);
   date_string[4] = ((DS1302_CLOCK_DATA[5] & 0x0F ) +48);
   date_string[5] = '/';
   date_string[6] = (((DS1302_CLOCK_DATA[6] >> 4) & 0x0F) +48);    // Print year variable  (start from year 2010)
   date_string[7] = ((DS1302_CLOCK_DATA[6] & 0x0F ) +48);          // Print year variable  (start from year 2010)
   date_string[8] = 0x00;

    LcdString(row,col,date_string);

}




/*void beep(){
      Buzzer = 1;   //Turn buzzer on
      Delay_ms(50); // 100 msecond delay sounds like beep
      Buzzer = 0;   //Turn buzzer off
      }*/



/*void Device_Default_config(int defaults){


                 Debug_sound_enable = 0;
                 contrast = 180;                         //1- Display Contrast
                 ContrastOffset = 185;                   //Contrast value Offset
                 ContrastMultiplier = 9;                 //Contrast value Multiplier, for Autocontrast
                 DemandVoltage = 400;                    //Tube Voltage
                 buzzer_enable = 0;                      //Clicker status
                 Timer_sync = 1;                         //Timer to Clock Sync enable
                 BT_enable = 0;                          //Bluetooth comms status
                 SD_Logging_Enable = 0;              //EEPROM recording status
                 EEPROM_Backlight_enable = 1;
                 autocontrast = 1;
                 Backlight_timeout = 5;
                 Screensaver_enable = 1;
                 Pos1 = 3;
                 Pos2 = 0;
                 SD_Logging_Enable = 0;
                 SD_Log_Timeout = 255;
                 Meters = 0;                   //13
                 Bigtime = 0;
                  Warning_alarm_enable = 0;
                  Timer_H = 179;
                  Timer_L = 39;
                  yf = 0.0056;


                 config_DATA[0] = contrast;
                 config_DATA[1] = (DemandVoltage >> 8);
                 config_DATA[2] = DemandVoltage;
                 Config_data[3] = Debug_sound_enable;
                 Config_data[4].b0 = Buzzer_enable.b0;
                 Config_data[4].b1 = BT_enable;
                 Config_data[4].b2 = SD_Logging_Enable;
                 Config_data[4].b3 = EEPROM_Backlight_enable;
                 Config_data[4].b4 = autocontrast;
                 Config_data[4].b5 = 0;               // Legacy Data from EEPROM Logging
                 Config_data[4].b6 = Buzzer_enable.b6;
                 Config_data[5] = Timer_sync;
                 Config_data[6] = 0;                  // Legacy Data from EEPROM Logging
                 Config_data[7] = 5;                   //Backlight_timeout seconds
                 Config_data[8] = 1;                   //Screensaver_enable
                 Config_data[9] = 3;                   //POS1 - LCD   (default 3 = uSv)
                 Config_data[10] = 0;                  //POS2 - LCD   (default 0 = Histogram)
                 Config_data[11] = 0;                  //GPS Logging Enable
                 Config_data[12] = 255;                //GPS Logging timeout  (255 = 0ff)
                 Config_data[13] = 0;                  //Meters - for GPS
                 Config_data[14] = 0;                  //Bigtime - for LCD
                 Config_data[15] = 0;                  //Alarm - for alarm levels
                 Config_data[16] = 179;                //Timer_H - for system clock
                 Config_data[17] = 39;                 //Timer_L - for system clock
                 yf = 0.0056;                          //uSv/h conversion factor.
                 Config_data[18] = yc[0];              //4 bytes...
                 Config_data[19] = yc[1];              //Extracted...
                 Config_data[20] = yc[2];              //Through...
                 Config_data[21] = yc[3];              //Union.

                 Config_data[22] = 5;                  //Default settings for GPS log on movement
                 Config_data[23] = 10;                 //Default settings for GPS log on movement
                 Config_data[24] = 30;                 //Default settings for GPS log on movement
                 Config_data[25] = 60;                 //Default settings for GPS log on movement
                 Config_data[26] = 200;                //Default settings for GPS log on movement
                 Config_data[27] = 9;                  //AutoContrast Gain.
                 Config_data[28] = 185;                //AutoContrast Offset.
                 Config_data[29] = 0;                  //Warnlevel High
                 Config_data[30] = 50;                 //Warnlevel Low.

                 Backlight = 1;
                 Backlight_flash = 0;
                 Pos1 = 3;
                 Pos2 = 0;

                 //------------------------------------------------------------


}*/


void DS3231_Clock_Write(){
/*char cc2 = 0;
                 I2c1_start();
                 if(!I2C1_Wr(Clock_Address_write)){
                  I2C1_Wr(0x00);
                  for(cc2=0;cc2<16;cc2++){
                   I2c1_wr(DS1302_CLOCK_DATA[cc2]);
                  }
                 }
                 I2c1_stop();
                 delay_us(10);*/

                I2C2_wr(Clock_Address_write,DS1302_CLOCK_DATA,16,_I2C_END_MODE_STOP);

}

void DS3231_Clock_Read(){
                //char cc2 = 0;

                 //if(I2C_clock_test(void)){

                  /*I2c2_start();
                  I2C2_Wr(Clock_address_write);
                  I2C2_Wr(0x00);
                  I2c2_repeated_start();
                  I2C2_Wr(Clock_address_read);
                  for(cc2=0;cc2<16;cc2++){  //cc2 counts the bytes in.
                   DS1302_CLOCK_DATA[cc2] = I2c1_rd(1);
                  }
                  I2c2_rd(0);              //Dummy read, no ACK to end transaction.
                  I2c2_stop();
                 //}
                   */

                 I2C2_WR(Seven_bit_Clock_Address,0x00,1,_I2C_END_MODE_RESTART);         //I2C Address, Data, #of bytes, end mode
                 I2C2_RD(Seven_bit_Clock_address,DS1302_CLOCK_DATA,16,_I2C_END_MODE_STOP);
                   

}


void UART1_Date_time(){
     UART1_Write_text(date_string);
     UART1_Write(',');
     UART1_Write(' ');
     UART1_Write_text(time_string);
     UART1_Write(',');
     UART1_Write(' ');
}

//------------------------------------------------------------------------------------------------------


void UART1_Write_CText(const char *txt){
   while (*txt)
      UART1_Write(*txt++);

 }

/*long StringToInt(char *BNumber, int Start, int chars){
  long Value = 0;
  i = Start;
  chars = i + chars;
  while(i < chars){
     if(BNumber[i] <= 57 && BNumber[i] >= 48){
      Value = Value * 10;
      Value += (BNumber[i]-48);
     }
     i++;
    }
  return Value;
}*/




void IOfunctions(){

                 if(Button1){
                 UART1_Write_ctext("Button1");
                 UART_CRLF();                   //Newline
                 }





                  //if(button2pressed){
                  if(button2){
                   UART1_Write_ctext("Button 2/PWR");
                   UART_CRLF();                   //Newline
                   button2Pressed = 0;

                  }

                  if(button3){
                   UART1_Write_ctext("Button 3");
                   UART_CRLF();                   //Newline


                  }
                  else{
                   Button3counter = 0;
                  }


                 if(reinitLCD){
                  LCDInitialise();
                  reinitLCD = 0;
                 }


}


void Main() {


                 Init_Main();               // Perform initialisations

                 Init_timers();             // Set up Timers

                 //Init_PWM();                // Start HV PWM    //PWM works on 47K42 but PIC Bootloops, Pin 36 ****
                 Clear_array(Counter_array_seconds, sizeof(counter_array_seconds));
                 Clear_array(Counter_array_minutes, sizeof(counter_array_minutes));
                 UART1_Init(9600);//(115200);        // UART1 (USB)
                 //UART2_Init(9600);          // UART2 (GPS)
                 delay_ms(200);
                 UART_state('0');

                 Display_pwr_DIR = 0;
                 Display_pwr = 1;

                 UART_state('1');
                 //Device_Save_config(1);      //This resets to defaults
                 //Device_Set_Config();  // Apply settings from EEPROM*/
                 Backlight_timer = Backlight_timeout;

                 CONTRAST = 190;


                 UART_state('2');

                 LCD_TYPE = 0;         // 0= Nokia, 1= JLX12864
                 LcdInitialise();      //
                 LcdClear();
                 //------Initialise I2C----------------------------

                 delay_ms(1000);
                 odconb = 0x06;             //Set I2C2 pins (RB1, RB2) as Open Collector, as per help file for I2C
                 I2C2_init();
                 //---------------------------------------------------------

                 UART_state('3');

                 delay_ms(20);

                  UART_state('4');
                  Lcdstring(0,1,"DM");
                  Lcdstring(0,2,"HW V1.2");
                  
                 UART_state('5');

                 //I2C2_WR(Seven_bit_Clock_Address,0x00,1,_I2C_END_MODE_RESTART);         //I2C Address, Data, #of bytes, end mode
                 //I2C2_RD(Seven_bit_Clock_address,DS1302_CLOCK_DATA,16,_I2C_END_MODE_STOP);

                 //DS3231_clock_read();

                  UART_state('6');
                 Display_time(3,3,0);
                 Display_date(3,4);

                  UART_state('7');

                 Delay_ms(1000);
                 lcdClear();
                 button2Pressed = 0;

                 UART1_Write_ctext("READY");
                 UART_CRLF();                   //Newline
                 intcon.gie = 1;              //****
                 intcon.giel = 1;              //****
while(1) {        // Endless loop (this is the main repeating loop)
                  asm CLRWDT;              // Clears the Watchdog timer (can only be done in assembly - 'asm')
                 UART1_Write_ctext("Main loop run");
                 UART_CRLF();                   //Newline
 //----------------------------------------------------------------------------------
               if (flag1 && !CRbit2){ //flag1 counts 10ms
                UART1_Write_ctext("Flag1 loop run");
                UART_CRLF();                   //Newline
                flag1 = 0;
               }
   //--------------1 second routines----------------------
               //if(1){                    //One_Sec counts 1second
               if(One_Sec && !CRbit2){   //One_Sec counts 1second
                 UART1_Write_ctext("1 sec loop run");
                 UART_CRLF();                   //Newline
                 One_Sec = 0;
                 //---------------------------------------------------------

                 DS3231_clock_read();      //Clock read and time always stays here

                 Display_time(0,0,0);

               }// end of Flag 2 loop (1 second).
//---------------60s Routines------------------------
                if(One_Min && !CRbit2){   //Runs every 60s
                  UART1_Write_ctext("1 Min loop run");
                  UART_CRLF();                   //Newline

                  One_Min = 0;



                }
//--------------Fast Routines-------------------------

                IOFunctions(); //All I/O functionality moved here
                                //Including buttons, backlight etc



 }     // Main Endless loop
}     // End of main program

davegsm82
Posts: 156
Joined: 29 Mar 2011 20:35

Re: Having trouble with Legacy interrupts (port from 26k22).

#4 Post by davegsm82 » 09 Apr 2019 23:57

Ok, so things get a little weirder.

I created a small function to check the status of intcon.gie

Code: Select all

void check_interrupts(){
                  if(intcon.gie){
                 UART1_Write_ctext("Interrupts ON");
                 }
                 else UART1_Write_ctext("Interrupts OFF");
                 UART_CRLF();                   //Newline
}
I littered this throughout the code and as previously none of the interrupt timer based functions were running, and in the main loop I have "Interrupts OFF" repeating out of the UART at all times.

I tried adding intcon.gie = 1 just before "While(1)" and also ran check_interrupts after it, sure enough, I got Interrupts ON once, but then it switches to Interrupts OFF inside the loop.

I added intcon.gie = 1; inside the loop, and suddenly the timers appear to be running, but obviously this isn't fixing the problem, just sidestepping it. So why does my General interrupt enable keep turning off?

Thanks, Dave.

davegsm82
Posts: 156
Joined: 29 Mar 2011 20:35

Re: Having trouble with Legacy interrupts (port from 26k22).

#5 Post by davegsm82 » 18 Apr 2019 22:33

Can anyone help?....

User avatar
filip
mikroElektronika team
Posts: 11874
Joined: 25 Jan 2008 09:56

Re: Having trouble with Legacy interrupts (port from 26k22).

#6 Post by filip » 24 Apr 2019 15:21

Hi,

I apologize for the late reply, I will look into this.

Regards,
Filip.

Dakta
Posts: 53
Joined: 07 Sep 2013 16:08

Re: Having trouble with Legacy interrupts (port from 26k22).

#7 Post by Dakta » 29 Apr 2019 14:42

experiencing something similar with these chips, I set INTCON1 to 0b10000000 then read it back via UART and get 0.

obviously not getting my ISR to run at all.

Can't see anything relevent in the chip errata :/

davegsm82
Posts: 156
Joined: 29 Mar 2011 20:35

Re: Having trouble with Legacy interrupts (port from 26k22).

#8 Post by davegsm82 » 18 Jul 2019 23:18

Filip, any ideas on this?

Why is the forum so quiet on this at the moment, is no-one bothering with the latest version of MikroC because of the problem?

User avatar
filip
mikroElektronika team
Posts: 11874
Joined: 25 Jan 2008 09:56

Re: Having trouble with Legacy interrupts (port from 26k22).

#9 Post by filip » 19 Jul 2019 09:30

Hi,

Have you tried running the code in 7.50 version ?

Regards,
Filip.

Post Reply

Return to “mikroC PRO for PIC Beta Testing”