Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

problem with time setting

Status
Not open for further replies.

ktkoota

New Member
Hi,
I am building a digital alarm clock using PIC18f2420 and I it is recommended from me to use C language. I wrote the code for dispalying the hours,minute and seconds and it works successfuly. Now I need to modify the code to set the time using switches in this way(using port B ):
if RB0(switch 0 in the circuit)=1 >>the second display will stop and I will use RB2(switch 2) to controle incrmenting and decremining the seconds.. the same is with minute and hours using another switches and RB..
I tried this code on my circuit but it didn't work.. ca any body help me please

#include <pic18.h>
#define Start_State 0
#define check_State 1
#define inc_State 2
#define dec_State 3

volatile unsigned char hours, mins, secs,State,int_flag ;
int counter;
unsigned char value1 ;
unsigned char a,y,x,x1,y1,b, v2;


void interrupt timer_isr(void) {
if (TMR2IF){
TMR2IF= 0;
counter = counter+ 1;
if ( counter == 800){

counter = 0;
secs++;
if (secs == 60){
secs =0;
mins++;
if (mins == 60){
mins =0;
hours++;
if ( hours == 24)
hours = 0;
}
}
}
}
}


void interrupt sw_isr(void){

if ( INT0IF){
INT0IF= 0;
int_flag= 1;

switch(State){

case Start_State:
if (RB0){
State= check_State;
}
break;

case check_State:
v2= RB2;
if(v2)
{
State= inc_State;
}
else
{
State= dec_State;
}
break;

case inc_State:
secs++;
State= Start_State;
break;

case dec_State:
secs--;
State= Start_State;
break;
}
}
}

void main(void){
// Configure timer2
TOUTPS3=1; TOUTPS2= 0; TOUTPS1=0; TOUTPS0= 1; // postscale values

T2CKPS1= 0; T2CKPS0= 1; // prescale values

PR2= 250;

// enable timer intrrupt
TMR2ON= 1; // turn on timer 2
PEIE=1; GIE= 1; IPEN=0;
TMR2IF= 0;// clear timer 2 intrrupt flag
TMR2IE= 1; // to allow timer 2 to intrrupt

// enable the intrrupt of the switch for sec INT0
RBPU= 0;
INTEDG0= 0;
INT0IF= 0;
INT0IE= 1;

// setting of port B as an output port
TRISB = 0x05; // set RB0 and RB2 as input others are output
PORTB = 0x00; // clear port B
TRISC=0X00;
PORTC=0X00;
RB5=0X0;
RB6=0X0;
RB7=0X00;

while (1)
{


a=secs;
x=a/10;
y=a%10;
b=mins;
x1=b/10;
y1=b%10;

value1=x;
PORTC=value1;
RB5=0X00;
RB6=0X00;
RB7=0X01;


value1=y;
RB7=0X00;
PORTC=value1;
RB5=0X01;
RB6=0X00;
RB7=0X01;

RB7=0X00;
value1=x1;
PORTC=value1;
RB5=0X00;
RB6=0X01;
RB7=0X01;

RB7=0X00;
value1=y1;
PORTC=value1;
RB5=0X01;
RB6=0X01;
RB7=0X01;
RB7=0X00;
}
}
 
Last edited:
not sure if this helps, but where to you initially initialize State to Start_State? (ie State = 0)
 
Last edited:
why don't you initialize it to a value when you initialize the variable?

Code:
volatile unsigned char hours, mins, secs,int_flag ;
volatile unsigned char State = Start_State;
 
well, the way I see it, if your "State" variable initially is something other than 0, 1, 2, 3 then your switch statement will never evaluate it and thus never change it to anything. This is why you want to initially set it to a known value to get predictable results. There may be other problems in the code, have you tested your interrupt routine with something simple like turning on an LED? I'm at work so don't have anything to test your code on.
 
yes,I used the code for led blinking and it works successfuly and then I modified this code for the cases and states for time setting but it didn't work :confused: .. I attached the pdf that I am using and you can see the led example on page (30-31)..
 

Attachments

  • chap10_interrupts.pdf
    664.2 KB · Views: 417
I'll take a look after putting my son to bed tonight at home unless someone helps you before then :)
 
does your code compile for you? I thought the problem was with it running, but is it a compile problem you're having?
 
think you're using Hi-Tech PICC18
I don't have a PIC18F2420 so I'm trying this on my PIC18F2550
For the it to compile, one of the interrupts has to be low priority, I'd suggest:
Code:
void interrupt low_priority sw_isr(void)
 
sorry for so many posts, you may also want to look at RBIF for your interrupt. I think instead of INT0IF but I'd have to read more
 
Last edited:
I didn't get it whats wrong with compiler,it showed me some syntax errors but I corrected the code..
why RBIF?where shall I add it? :confused:
 
Last edited:
Here's what I did to get your code to compile on my PIC18F2550
Code:
#include <pic18.h>
#define Start_State 0
#define check_State 1
#define inc_State 2
#define dec_State 3

__CONFIG(1,HS & FCMDIS & IESODIS);
__CONFIG(2,VREGDIS & PWRTEN & BORDIS & WDTDIS);
__CONFIG(3,CCP2RB3 & PBDIGITAL & LPT1DIS & MCLRDIS);
__CONFIG(4,LVPDIS & ICPORTDIS & DEBUGDIS);
__CONFIG(5,UNPROTECT);
__CONFIG(6,UNPROTECT);
__CONFIG(7,UNPROTECT);

volatile unsigned char hours,mins,secs,State,int_flag = 0;
int counter = 0;
unsigned char value1;
unsigned char a,y,x,x1,y1,b,v2;

void interrupt timer_isr(void)
{
  if(TMR2IF)
  {
    TMR2IF= 0;
    counter++;
    if(counter == 800)
    {
      counter = 0;
      secs++;
      if (secs == 60)
      {
        secs =0;
        mins++;
        if (mins == 60)
        {
          mins =0;
          hours++;
          if ( hours == 24)
            hours = 0;
        }
      }
    }
  }
}

void interrupt low_priority sw_isr(void)
{
  if(INT0IF)
  {
    INT0IF = 0;
    int_flag = 1;

    switch(State)
    {
      case Start_State:
        if(RB0)
        {
          State = check_State;
        }
        break;

      case check_State:
        v2 = RB2;
        if(v2)
        {
          State = inc_State;
        }
        else
        {
          State = dec_State;
        }
        break;

      case inc_State:
        secs++;
        State = Start_State;
        break;

      case dec_State:
        secs--;
        State = Start_State;
        break;
    }
  }
}

void main(void)
{
  // Configure timer2
  TOUTPS3 = 1;
  TOUTPS2 = 0;
  TOUTPS1 = 0;
  TOUTPS0 = 1; // postscale values

  T2CKPS1 = 0;
  T2CKPS0 = 1; // prescale values

  PR2     = 250;

  // setting of port B as an output port
  PORTB    = 0x00; // clear port B
  TRISB    = 0x05; // set RB0 and RB2 as input others are output
  PORTC    = 0x00;
  TRISC    = 0x00;

  // enable timer intrrupt
  TMR2ON  = 1; // turn on timer 2
  PEIE    = 1;
  GIE     = 1;
  IPEN    = 0;
  TMR2IF  = 0;// clear timer 2 intrrupt flag
  TMR2IE  = 1; // to allow timer 2 to intrrupt

  // enable the intrrupt of the switch for sec INT0
  RBPU     = 0;
  INTEDG0  = 0;
  INT0IF   = 0;
  INT0IE   = 1;

  RB5      = 0x00;
  RB6      = 0x00;
  RB7      = 0x00;

  while (1)
  {
    a      = secs;
    x      = a/10;
    y      = a%10;
    b      = mins;
    x1     = b/10;
    y1     = b%10;

    value1 = x;
    PORTC  = value1;
    RB5    = 0x00;
    RB6    = 0x00;
    RB7    = 0x01;

    value1 = y;
    RB7    = 0x00;
    PORTC  = value1;
    RB5    = 0x01;
    RB6    = 0x00;
    RB7    = 0x01;

    RB7    = 0x00;
    value1 = x1;
    PORTC  = value1;
    RB5    = 0x00;
    RB6    = 0x01;
    RB7    = 0x01;

    RB7    = 0x00;
    value1 = y1;
    PORTC  = value1;
    RB5    = 0x01;
    RB6    = 0x01;
    RB7    = 0x01;
    RB7    = 0x00;
  }
}

RBIF is to interrupt when there's a change to PORTB, which might be a problem since you're also using PORTB as outputs and not just inputs, I have to look at how you're trying to use your software interrupt, I feel it's not going to get triggered the way it's coded.
 
it didn't work!.. it seems that the code isn't reading the switch input there is no effect at all (as you expected it didn't trigger)..
what shall I do? is there another way
 
Last edited:
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top