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.
Having trouble with Legacy interrupts (port from 26k22).
Re: Having trouble with Legacy interrupts (port from 26k22).
Hi,
Can you please attach here the minimal project that represents this issue ?
Which version of the compiler are you using ?
Regards,
Filip.
Can you please attach here the minimal project that represents this issue ?
Which version of the compiler are you using ?
Regards,
Filip.
Re: Having trouble with Legacy interrupts (port from 26k22).
Hi Filip.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.
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
Re: Having trouble with Legacy interrupts (port from 26k22).
Ok, so things get a little weirder.
I created a small function to check the status of intcon.gie
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.
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 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.
Re: Having trouble with Legacy interrupts (port from 26k22).
Can anyone help?....
Re: Having trouble with Legacy interrupts (port from 26k22).
Hi,
I apologize for the late reply, I will look into this.
Regards,
Filip.
I apologize for the late reply, I will look into this.
Regards,
Filip.
Re: Having trouble with Legacy interrupts (port from 26k22).
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 :/
obviously not getting my ISR to run at all.
Can't see anything relevent in the chip errata :/
Re: Having trouble with Legacy interrupts (port from 26k22).
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?
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?
Re: Having trouble with Legacy interrupts (port from 26k22).
Hi,
Have you tried running the code in 7.50 version ?
Regards,
Filip.
Have you tried running the code in 7.50 version ?
Regards,
Filip.