|
|
View previous topic :: View next topic |
Author |
Message |
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Wed Nov 30, 2016 6:01 am |
|
|
Repeat after me.
You must _never_ 'enable_interrupts(GLOBAL)' inside an interrupt on the PIC. A search here will find lots about this. |
|
|
mahatia
Joined: 14 Nov 2016 Posts: 23
|
|
Posted: Wed Nov 30, 2016 7:23 am |
|
|
So, I shouldn't use enable_interrupts(global)? |
|
|
mahatia
Joined: 14 Nov 2016 Posts: 23
|
|
Posted: Wed Nov 30, 2016 7:24 am |
|
|
Code: | #include <12F675.h>
#device *= 16
#fuses NOWDT, PROTECT, CPD, NOMCLR, INTRC_IO, BROWNOUT, PUT
#use delay (internal = 4MHz)
#byte GPIO = 0x00
#include "lcd.c"
#include "DS1307.c"
//global variables
int8 i = 0;
int8 cnt;
static int1 last2, last3; //single bits to record the 'last'' state of the pins
byte day;
byte mth;
byte year;
byte hr;
byte min;
byte sec;
//This will be called for _all_ enabled RA interrupts
#INT_RA
void change(void)
{
//Now first RA2
if (input(PIN_A2))
{
//pin is high
if (last2==0)
last2=1;
}
else
{
//pin is low
if (last2==1)
{
last2=0;
//code here for 'high to low' on RA2
// disable_interrupts(GLOBAL);
i++;
cnt=0;
//enable_interrupts(GLOBAL);
}
}
//Now RA3
if (input(PIN_A3))
{
//pin is high
if (last3==0)
last3=1;
}
else
{
//pin is low
if (last3==1)
{
last3=0;
//pour 'high to low' on RA3
if (i == 1)
{
if(min<59)min++;
else min = 0;
}
if (i == 2)
{
if(hr<24)hr++;
else hr = 0;
}
if (i == 3)
{
if(day<31)day++;
else day = 1;
}
if (i == 4)
{
if(mth<13)mth++;
{
if (mth ==13)
{
mth = 1;
year++;
}
}
}
}
}
// clear_interrupt(INT_RA); //vo napetaka
}
void main(void)
{
char txt3 = "M";
char txt4 = "O";
char txt5 = "D";
char txt6 = "V";
setup_adc(ADC_OFF); //ADC off
setup_adc_ports(NO_ANALOGS);
setup_comparator(NC_NC_NC_NC); //comparators off
set_tris_a(0b001100);
setup_counters(rtcc_internal,rtcc_div_2);
last3=input(PIN_A3); //latch must be read before starting
last2=input(PIN_A2); //and the same for A2
clear_interrupt(INT_RA);
enable_interrupts(INT_RA3 | INT_RA2); //enable on RA3 and RA2
//enable_interrupts(global);
LCD_init();
ds1307_init();
while(TRUE)
{
if((i == 0)||(i == 5))
{
ds1307_get_date(day,mth,year); // Read date
ds1307_get_time(hr,min,sec);
LCD_goto(4,0);
printf(LCD_putchar," %02d:\%02d:\%02d",hr,min,sec); // Display time
LCD_goto(5,1);
printf(LCD_putchar,"\%02d/\%02d/20\%02d",day,mth,year); // Display date
}
else
{
if(cnt==0)
{
LCD_command(clear_display);
cnt=1;
}
switch (i)
{
case 1:
LCD_goto(7,0);
LCD_putchar(txt3);
LCD_goto(7,1);
printf(LCD_putchar, "%02d",min);
break;
case 2:
LCD_goto(7,0);
LCD_putchar(txt4);
LCD_goto(7,1);
printf(LCD_putchar, "%02d",hr);
break;
case 3:
LCD_goto(7,0);
LCD_putchar(txt5);
LCD_goto(7,1);
printf(LCD_putchar, "%02d",day);
break;
case 4:
LCD_goto(7,0);
LCD_putchar(txt6);
LCD_goto(7,1);
printf(LCD_putchar, "%02d",mth);
break;
case 5:
i = 0;
break;
//! LCD_goto(7,0);
//! LCD_putchar(txt7);
//! LCD_goto(7,1);
//! printf(LCD_putchar, "%02d",year);
//! break;
} //end of switch
}
};
}
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Wed Nov 30, 2016 7:42 am |
|
|
mahatia wrote: | So, I shouldn't use enable_interrupts(global)? |
Never _inside_ an interrupt.
On the PIC, the hardware generates a disable_interrupt(GLOBAL) when the interrupt is serviced. It turns this back on just after the code leaves the interrupt routine. If it is turned on before this then the interrupt handler can be called inside itself (recursion). This will crash the chip or cause it to behave erratically. |
|
|
mahatia
Joined: 14 Nov 2016 Posts: 23
|
|
Posted: Wed Nov 30, 2016 8:32 am |
|
|
ok! thank you very much! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Nov 30, 2016 9:17 pm |
|
|
A few more bugs:
This is wrong. #byte tells the compiler the address of the register.
The address of GPIO is 0x05 in the 12F675. This is stated in the 12F675
data sheet in this section:
Quote: | 3.0 GPIO PORT
REGISTER 3-1: GPIO — GPIO REGISTER (ADDRESS: 05h)
|
So it should be:
This is wrong:
Quote: |
char txt3 = "M";
char txt4 = "O";
char txt5 = "D";
char txt6 = "V";
|
Double quotes means the text is a string. A string is text with a 0x00
on the end. The double quotes tells the compiler to put 0x00 on the end.
You don't need that here. In fact, the compiler ignores it and saves you.
It should be done like this, with single quotes:
Code: | char txt3 = 'M';
char txt4 = 'O';
char txt5 = 'D';
char txt6 = 'V'; |
This is wrong:
Quote: | //enable_interrupts(global); |
You misunderstood what Ttelmah said and removed enable_interrupts()
in your main(). Don't do that. Keep it enabled in main(). Just don't
enable it inside #int_ra. Change it to:
Code: | enable_interrupts(GLOBAL); |
|
|
|
mahatia
Joined: 14 Nov 2016 Posts: 23
|
|
Posted: Thu Dec 01, 2016 7:59 am |
|
|
ok! I have tried it and it works! thank you so much. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|