CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

PIC12F675+PCF8574+LCD 16x2+ RTC DS1307
Goto page Previous  1, 2, 3
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Ttelmah



Joined: 11 Mar 2010
Posts: 19550

View user's profile Send private message

PostPosted: Wed Nov 30, 2016 6:01 am     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Nov 30, 2016 7:23 am     Reply with quote

So, I shouldn't use enable_interrupts(global)?
mahatia



Joined: 14 Nov 2016
Posts: 23

View user's profile Send private message

PostPosted: Wed Nov 30, 2016 7:24 am     Reply with quote

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: 19550

View user's profile Send private message

PostPosted: Wed Nov 30, 2016 7:42 am     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Nov 30, 2016 8:32 am     Reply with quote

ok! thank you very much!
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Nov 30, 2016 9:17 pm     Reply with quote

A few more bugs:
Quote:
#byte GPIO = 0x00

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:
Code:
#byte GPIO = 0x05



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

View user's profile Send private message

PostPosted: Thu Dec 01, 2016 7:59 am     Reply with quote

ok! I have tried it and it works! thank you so much.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page Previous  1, 2, 3
Page 3 of 3

 
Jump to:  
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