Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[PIC] Serial Communication Interrupt Flag in PIC18f4520 and mikrocpro for PIC

Status
Not open for further replies.

djc

Advanced Member level 1
Joined
Jan 27, 2013
Messages
402
Helped
3
Reputation
6
Reaction score
2
Trophy points
1,298
Location
India
Activity points
4,554
Hi,
I wrote a code to send and receive the data serially. Application is such that, controller will send the data for particular received character. And will receive the string of characters and will update the 16 segment display. Now even if string of characters is received, interrupt will occur for every character received in string. I thought of taking a variable and increment it every time serial interrupt occurs. I have taken the serial interrupt in timer0 interrupt. Code is as follows,

Code:
if(PIR1.RCIF==1){

                         PIR1.RCIF=0;
                         index++;

                               input_string[index]=RCREG;

                                        MAX_CONTROL = 1;
                                        UART1_Write(index+48);
                                        Delay_ms(1);
                                        MAX_CONTROL = 0;
          RCREG=0;
         }
Index is the variable which should be incremented each time serial interrupt occurs. However it's been increasing randomly. Please tell me what could be the issue.
 

Remove the delay. Delays inside an ISR are bad news!

I'm not sure what you mean by "I have taken the serial interrupt in timer0 interrupt." If you are using interupts you should have an different routine for each of them. Nesting one ISR inside another will not work. I doubt you need the line "RCREG = 0;" as it gets overwritten by the next character arriving.

You are also likely to send almost random characters to the UART as 'index' is not initialized and if adding 48 is to make the value a numeric ascii character , it will only work with index values between 0 and 9.

Brian.
 

hi,
Remove delays... because it may cause overrun error. And don't change the index value by using UART_Write(index+48) this change the arrray pointer of input _string and no need to put RCREG=0; it will automatically 0 once data is received in input_string. hope this helps good luck...
 

This will causing changing the value of index. Also define index globally.
I can't see how that would happen. "UART1_Write(index+48);" just writes the value of (index+48) to the UART TXREG, it doesn't change the value of index.
The 'index' declaration isn't shown but ideally it should be declared 'volatile' if it's used elsewhere outside the ISR.

Brian.
 

Thanx all,
Let me post the complete interrupt routine,
Code:
void interrupt(){
      
      if(INTCON.TMR0IF){
      TMR0L = TIMER_START_VALUE;
      TMR0H = TIMER_START_VALUE_1;
      TMR0IF_bit = 0;
      }

          if(prg_key==1){
           blink++;
           if(blink>600) blink=0;
           last++;
         }
         if(PIR1.RCIF){

                         PIR1.RCIF=0;


                               input_string[index]=RCREG;
                               index++;
                                        MAX_CONTROL = 1;
                                        //UART1_Write(input_string[index]+48);
                                        UART1_Write(index+48);
                                        Delay_ms(1);
                                        MAX_CONTROL = 0;
          //RCREG=0;
         }
      
}

"I have taken Serial interrupt in timer interrupt routine " means Interrupt routine for timer0 and serial interrupt are in same interrupt occurrence. Please let me know if serial interrupt is written by any other name. 'Index' has been declared globally as 'char' and initialized in 'main' to '0' value. Statement 'UART1_Write(index+48);' means i wanted to know which value 'index' has been pointing after increment. I find that it is increasing randomly. 'MAX_CONTROL' is the pin of microcontroller to control the MAX485 while reading and writing. It is connected to pin 2 and 3 of max485. I haven't posted complete code, just interrupt routine where i am facing an issue. Do you people want me to post complete code???

- - - Updated - - -

I read somewhere on internet that we can't clear the RCIF flag by software, is it true???

- - - Updated - - -

New interrupt routine,
Code:
void interrupt(){
      
      char sdat;
      //index=0;
      if(INTCON.TMR0IF){
      TMR0L = TIMER_START_VALUE;
      TMR0H = TIMER_START_VALUE_1;
      TMR0IF_bit = 0;
      }

          if(prg_key==1){
           blink++;
           if(blink>600) blink=0;
           last++;
         }
         if(PIR1.RCIF){

                         PIR1.RCIF=0;
                         input_string[index]=RCREG;

                                        if(input_string[0] == 63){
                                                                read=1;
                                        }

                                        else{
                                              write=1;
                                        }

          //RCREG=0;
         }


      //display();
         //Test = ~Test;
        //TMR0L = TIMER_START_VALUE;
        //TMR0H = TIMER_START_VALUE_1;
}

And in main i did this,
Code:
if(read==1){
                                                                 MAX_CONTROL = 1;
                                                                 //UART1_Write(FND_2+48);
                                                                 UART1_Write(index+48);
                                                                 MAX_CONTROL = 0;
                                                                 index=0;
                                                                 RCREG=0;
                                                                 input_string[0]=0;
                                                                 read=0;
                                         }
                         
                                         if(write==1){
                                                      input_string[index]=RCREG;
                                                      MAX_CONTROL = 1;
                                                      UART1_Write(index+48);
                                                      UART1_Write(RCREG);
                                                      MAX_CONTROL = 0;
                                                      index++;
                                                              if(index>10) index=0;
                                                      write=0;
                                         }

- - - Updated - - -

Output on serial window
serial_window.png
 

It's fine and quite normal to check for several interrupt sources within one interrupt routine. I would urge caution about adding other routines such as your 'if(...' though because they slow down the return to the main program. The whole idea of interrupts is that they do just what their name says, they interrupt the normal flow of the program so you should move as much as possible to your main code flow and keep the ISR as short as possible. Adding any delay inside an ISR is asking for trouble because interrupts are non-reentrant, when you are inside the ISR, the GIE bits are used to prevent it being called again. That doesn't stop the interrupt flags working and any that are set will be respected as soon as the ISR exits - BUT - a second interrupt from any source will already have it's flag set and the first ocurrence will be ignored.

A better program flow would be like this:
void interrupt()
{
<check the timer interrupt bit> <set a global flag if you need a timed action> <reset the timer interrupt bit>
<check the UART interrupt bit> <read the UART data> <set a global flag to say data is ready> <reset the UART interrupt bit>
}

Then in your main code you check those global flags and do what is necessary to process them, then reset them. This gets you out of the ISR as fast as possible so no other interrupts are blocked. Note that the global flags (bits or chars) should be declared 'volatile' to warn the compiler that their values may change at any time.

Brian.
 

Thanx brian.
Now i have used flags only 'read' and 'write' setting them in interrupt routine and checking in main. Still PIR1.RCIF flag is not getting reset even after RCREG is read.
 

The RCIF flag should be reset by reading the RCREG. Is this being tested in real hardware or only in simulation? Possibly the simulator is wrong.

Brian.
 

it's tested in real hardware. Now RCREG register too not showing any value. I tried to read it using 'UART1_Write(RCREG)' moreover i stored RCREG in one variable and tested using 'UART1_Write(sdat)' sdat being a variable in which RCREG has been stored. But none of these seems to be working.
 

I think you will have to post the whole project so we can investigate. If nothing else, this shows you can't always trust a simulator to behave like real hardware!

Brian.
 

I will post whole code.It has 4*4 keypad interfacing, 16 seg display interfacing, logic to convert data to number to be displayed on 16 seg display, and send data through 74HC595.

- - - Updated - - -

Code:
\#include <math.h>
#define ROW0    PORTB.B1  //o/p
#define ROW1    PORTB.B3
#define ROW2    PORTB.B5
#define ROW3    PORTB.B7
#define COL0    RB0_bit   //i/p
#define COL1    RB2_bit
#define COL2    RB4_bit
#define COL3    RB6_bit
#define Select_DS     PORTD.B7
#define Select_Clk    PORTD.B6
#define Data_DS       PORTD.B5
#define Data_Clk      PORTD.B4
#define Test          PORTD.B0  //Pin 19
#define TIMER_START_VALUE   250   //230,200,255,500
#define TIMER_START_VALUE_1 250  //210,160,254,255
#define adjust 1000//500,1000
#define bright 1
#define MAX_CONTROL   PORTC.B5
//#define Transmit      PORTC.B6
//#define Receive       PORTC.B7
 signed char j_1=0,j_2=0,m_1=0,m_2=0,j_3=1,j_4,m_3=0,m_4=0,error=0;
 unsigned char   i=0,j=0,k=0,FND_0=0,FND_1=0,FND_2=0,FND_3=0,FND_4=0,FND_5=0,FND_6=0,FND_7=0,FND_8=0,FND_9=0;
 unsigned char bulb=0,disp_pre_0=0,disp_pre_1=0,disp_pre_2=0,disp_pre_3=0,disp_pre_4=0,disp_pre_5=0,disp_pre_6=0,disp_pre_7=0,disp_pre_8=0,disp_pre_9=0;
 unsigned char disp_cur_0=0,disp_cur_1=0,disp_cur_2=0,disp_cur_3=0,disp_cur_4=0,disp_cur_5=0,disp_cur_6=0,disp_cur_7=0,disp_cur_8=0,disp_cur_9=0;
 unsigned char prg_key,enter;
 bit last_FWD;
 int blink=0,COUNT=0;
 unsigned int quotient=0 ;
 char FWD=1,REV=1,key=0,blank_pre=0,blank_cur=0,last_blink=0,prg_key_count=1;
 unsigned char binaryNumber[20];
 unsigned int num[11] = {39578,65215,6939,23067,32318,23130,6746,65179,6682,23066,32639};   //For 7 =65178
 unsigned int alpha[26]= {15898,53779,39898,53907,7002,16218,39514,15934,54227,38867,15854,39934,48812,48316,
                         39578,16154,39066,15642,23130,63443,39614,45038,44222,60909,63469,52171};
 unsigned char num_2[17]= {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
 unsigned char input_string[12],*received_string;
 unsigned int blank[1] = {65535},finaldisp1=0,finaldisp2=0,last=0;
 char blink_pos[11]={0,1,0,0,0,0,0,0,0,0,0},sdat=0,read=0,write=0;

/*******************************************************/
void Key_Detect_2() {

                 for(i=0;i<17;i++){
                             Data_DS = num_2[i];
                             Data_Clk = 1;
                             //Delay_us(1);
                             Data_Clk = 0;
                           //Delay_us(2);
                             //i--;
                             //Delay_us(1);
                 }


}
/*******************************************************/
void Key_Detect(unsigned int quotient){

           //quotient = Data;
           i=1;
           //j=0;
                     while(quotient>0){
                             binaryNumber[i++]= quotient % 2;
                             quotient = quotient / 2;

                     }
                             for(i=i;i<17;i++)
                             {
                                 binaryNumber[i] = 0;
                             }
                             //i--;
                             //for(j = i-1;j>=0;j--){

                             while(i!=0){
                             Data_DS = binaryNumber[i];
                             Data_Clk = 1;
                             Delay_us(1);
                             Data_Clk = 0;
                           //Delay_us(2);
                             i--;
                             };

                 Data_Clk = 1;
                 Delay_us(1);
                 Data_Clk = 0;
                 //Delay_ms(1000);
         //}
}
//void Key_Detect_2(int Data) {
/*******************************************************/
void select_fun(){
                 Select_Clk = 1;
                 Delay_us(1);
                 Select_DS = 0;
                 Select_Clk = 0;
}
/*******************************************************/
void refresh(){
               Test=0;
               Delay_ms(bright);
               Test=1;
}
/*******************************************************/
void display_2(){

Select_DS = 1;
         Delay_us(1);
         for(k=0;k<7;k++){
             select_fun();
         }
         Test=1;
         select_fun();
                                   Key_Detect(alpha[FND_0]);
                                   Test=0;
                                   Delay_ms(bright);
         Test=1;
         select_fun();
                                   Key_Detect(alpha[FND_1]);
                                   Test=0;
                                   Delay_ms(bright);
         Test=1;
         select_fun();
                                   Key_Detect(num[FND_2]);
                                   Test=0;
                                   Delay_ms(bright);
         Test=1;
         select_fun();
                                   Key_Detect(num[FND_3]);
                                   Test=0;
                                   Delay_ms(bright);
         Test=1;
         select_fun();
                                   Key_Detect(alpha[FND_4]);
                                   Test=0;
                                   Delay_ms(bright);
         Test=1;
         select_fun();
                                   Key_Detect(alpha[FND_5]);
                                   Test=0;
                                   Delay_ms(bright);
         Test=1;
         select_fun();
                                   Key_Detect(num[FND_6]);
                                   Test=0;
                                   Delay_ms(bright);
         Test=1;
         select_fun();
                                   Key_Detect(num[FND_7]);
                                   Test=0;
                                   Delay_ms(bright);
         Test=1;
         select_fun();
                                   Key_Detect(num[FND_8]);
                                   Test=0;
                                   Delay_ms(bright);
         Test=1;
         select_fun();
                                   Key_Detect(num[FND_9]);
                                   Test=0;
                                   Delay_ms(bright);
         Test=1;
}

void display(){
Select_DS = 1;
         Delay_us(1);
         for(k=0;k<7;k++){
             select_fun();
         }
         Test=1;
         select_fun();
         if((blink_pos[1]==1) ){
                      if(blink<300){

                                   Key_Detect(alpha[FND_0]);
                                   refresh();
                      }
                      if((blink>300) && (blink<600)){
                                   Key_Detect_2();
                                   refresh();

                                  if((bulb==1)){

                                               Key_Detect(alpha[FND_0]);
                                               refresh();
                                               //enter=0;

                                  }

                      }

         }
        else {
                      Key_Detect(alpha[FND_0]);
                      refresh();
        }
/***************/
         Test=1;
         select_fun();
         if((blink_pos[2]==1) ){
                      if(blink<300){

                                   Key_Detect(alpha[FND_1]);
                                   refresh();

                      }
                      if((blink>300) && (blink<600)){
                                   Key_Detect_2();
                                   refresh();
                                   if((bulb==1)){

                                               Key_Detect(alpha[FND_1]);
                                               refresh();
                                               //enter==0;
                                  }


                      }


         }
        else {
                      Key_Detect(alpha[FND_1]);
                      refresh();
        }
/***************/
         Test=1;
         select_fun();
         if((blink_pos[3]==1) ){
                      if(blink<300){

                                   Key_Detect(num[FND_2]);
                                   refresh();

                      }
                      if((blink>300) && (blink<600)){
                                    Key_Detect_2();
                                    refresh();

                                    if((bulb==1)){

                                               Key_Detect(num[FND_2]);
                                               refresh();
                                               //enter=0;
                                    }


                      }

         }
        else {
                      Key_Detect(num[FND_2]);
                      refresh();
        }
/***************/
         Test=1;
         select_fun();
         if((blink_pos[4]==1) ){
                      if(blink<300){

                                   Key_Detect(num[FND_3]);
                                   refresh();
                      }
                      if((blink>300) && (blink<600)){
                                   Key_Detect_2();
                                   refresh();

                                   if((bulb==1)){
                                               Key_Detect(num[FND_3]);
                                               refresh();
                                               //enter=0;
                                  }

                      }
         }

        else {
                      Key_Detect(num[FND_3]);
                      refresh();
        }
/**************/
        Test=1;
        select_fun();
        if((blink_pos[5] == 1) ){
                      if(blink<250){

                                   Key_Detect(alpha[FND_4]);
                                   refresh();
                      }
                      if((blink>250) && (blink<500)){

                                   Key_Detect_2();
                                   refresh();

                                   if((bulb==1)){
                                   Key_Detect(alpha[FND_4]);
                                   refresh();
                                   //enter=0;
                                   }

                      }
              }
         else {

                      Key_Detect(alpha[FND_4]);
                      refresh();
        }
/****************/
         Test=1;
         select_fun();
         if((blink_pos[6] == 1) ){
                      if(blink<250){

                                   Key_Detect(alpha[FND_5]);
                                   refresh();

                      }
                      if((blink>250) && (blink<500)){
                                   Key_Detect_2();
                                   refresh();

                                   if(bulb==1){
                                   Key_Detect(alpha[FND_5]);
                                   refresh();
                                   //enter=0;
                                   }
                      }
              }
         else {
                      Key_Detect(alpha[FND_5]);
                      refresh();

        }
/**************/
         Test=1;
         select_fun();
         if((blink_pos[7] == 1) ){
                      if(blink<250){

                                   Key_Detect(num[FND_6]);
                                   refresh();

                      }
                      if((blink>250) && (blink<500)){
                                   Key_Detect_2();
                                   refresh();

                                   if((bulb==1)){
                                   Key_Detect(num[FND_6]);
                                   refresh();
                                   //enter=0;
                                   }
                      }
              }
        else {
                      Key_Detect(num[FND_6]);
                      refresh();
        }
/**********/
         Test=1;
         select_fun();
         if((blink_pos[8] == 1) ){
                      if(blink<250){

                                   Key_Detect(num[FND_7]);
                                   refresh();

                      }
                      if((blink>250) && (blink<500)){
                                   Key_Detect_2();
                                   refresh();

                                   if((bulb==1)){
                                   Key_Detect(num[FND_7]);
                                   refresh();
                                   //enter=0;
                                   }
                      }
              }
         else {
                      Key_Detect(num[FND_7]);
                      refresh();
        }
/****************/
         Test=1;
         select_fun();
         if((blink_pos[9] == 1) ){
                      if(blink<250){

                                   Key_Detect(num[FND_8]);
                                   refresh();
                                   //Key_Detect_2();

                      }
                      if((blink>250) && (blink<500)){

                                   Key_Detect_2();
                                   refresh();

                                   if((bulb==1)){
                                   Key_Detect(num[FND_8]);
                                   refresh();
                                   //enter=0;
                                   }
                      }
              }
        else {
                      Key_Detect(num[FND_8]);
                      refresh();
        }
/***********/
         Test=1;
         select_fun();
         if((blink_pos[10] == 1) ){
                      if(blink<250){

                                   Key_Detect(num[FND_9]);
                                   refresh();
                                   //Key_Detect_2();


                      }
                      if((blink>250) && (blink<500)){

                                   Key_Detect_2();
                                   refresh();

                                   if((bulb==1)){
                                   Key_Detect(num[FND_9]);
                                   refresh();
                                   //enter=0;
                                   }
                      }
              }
         else {
                      Key_Detect(num[FND_9]);
                      refresh();
        }
        Test=1;
}
/*******************************************************/
void key_confirm(){
 do{
 COUNT++;
 if((COUNT==20) ||(COUNT==40)||(COUNT==60) ||(COUNT==80) ||(COUNT==100) ||(COUNT==120)||(COUNT==140)||(COUNT==160)||(COUNT==180)||(COUNT==200)||(COUNT==220)||(COUNT==240)
   ||(COUNT==260)||(COUNT==280)||(COUNT==300)||(COUNT==320)||(COUNT==340)||(COUNT==360)||(COUNT==380)||(COUNT==400)||(COUNT==420)||(COUNT==440)||(COUNT==460)||(COUNT==480)||(COUNT==500)
   )
 display();
 }while(COUNT<700);
}
/*********************************************************/
void interrupt(){

      if(INTCON.TMR0IF){
      TMR0L = TIMER_START_VALUE;
      TMR0H = TIMER_START_VALUE_1;
      TMR0IF_bit = 0;
      }

          if(prg_key==1){
           blink++;
           if(blink>600) blink=0;
           last++;
         }
         
         if(PIR1.RCIF){
                                 if(RCREG==63){              //Ascii value for ?         
						
					read=1;
                                 }
                                  else {                       //if '@' Receive the data
                                       	sdat = RCREG;
					write=1;
                                 }
                                       

                        PIR1.RCIF=0;
          }
                        

         //Test = ~Test;
        //TMR0L = TIMER_START_VALUE;
        //TMR0H = TIMER_START_VALUE_1;
}


void main() {

     TRISD = 0x00;            /*//PortD as output*/
     PORTD = 0x00;            /*//Initial value*/
     TRISC = 0b11000000;
     TRISB = 0x55;             //0 as o/p, 1 as i/p
     PORTB = 0x00;
     INTCON =0b11100000 ;           /*//0xc0;0xa0*/

     TMR0ON_bit = 0;          /*//Stop timer 0 during set up*/
     T08BIT_bit = 0;      /*// Enable 16 bit timer*/
     T0CS_bit = 0;        /*// use internal clock to trigger timer to count*/
     PSA_bit = 0;         /*// Use the prescaler to slow the timer down*/

     /*// prescaler
     // 111 = 1:256 Prescale value
     // 110 = 1:128 Prescale value
     // 101 = 1:64 Prescale value
     // 100 = 1:32 Prescale value
     // 011 = 1:16 Prescale value
     // 010 = 1:8 Prescale value
     // 001 = 1:4 Prescale value
     // 000 = 1:2 Prescale value*/
     T0PS0_bit = 0; //1             /*//for 16 bit timer 1/4 of clock freq   001*/
     T0PS1_bit = 1; //0
     T0PS2_bit = 0; //0

     TMR0L = TIMER_START_VALUE;
     TMR0H = TIMER_START_VALUE_1;

     TMR0ON_bit = 1;       //start the timer
     
     //BRG16_bit = 0;
     //SPBRGH = 12;

     UART1_Init(9600);
     PIE1 = 0b00100000;  //RCIE bit enabled
     //TXSTA  = 0b00100010;
     //RCSTA = 0b10010000;

     Delay_ms(100);
     MAX_CONTROL=0;
     //RS485Master_Init();                  // initialize MCU as Master


     //blink_pos[1] = 1;
     //prg_key=1;
         while(1){

            display();
            ROW0 = 0;
            ROW1 = 1;
            ROW2 = 1;
            ROW3 = 1;
            //Delay_ms(5);
                        COUNT=0;
                         if(COL0==0){
                         Delay_ms(1);
                           if(COL0==0){
                                       key_confirm();
                                       //FND_1=1;
                                       key=1;
                                       if(FWD==3) FND_2=key;
                                       if(FWD==4) FND_3=key;
                                       if(FWD==7) FND_6=key;
                                       if(FWD==8) FND_7=key;
                                       if(FWD==9) FND_8=key;
                                       if(FWD==10) FND_9=key;

                                       disp_cur_2 = FND_2;
                                       disp_cur_3 = FND_3;
                                       disp_cur_6 = FND_6;
                                       disp_cur_7 = FND_7;
                                       disp_cur_8 = FND_8;
                                       disp_cur_9 = FND_9;
                           }
                         }

                         COUNT=0;

                         if(COL1==0){
                         Delay_ms(1);
                           if(COL1==0){
                                       key_confirm();
                                       key=2;
                                       if(FWD==3)FND_2=key;
                                       if(FWD==4)FND_3=key;
                                       if(FWD==7) FND_6=key;
                                       if(FWD==8) FND_7=key;
                                       if(FWD==9) FND_8=key;
                                       if(FWD==10) FND_9=key;

                                       disp_cur_2 = FND_2;
                                       disp_cur_3 = FND_3;
                                       disp_cur_6 = FND_6;
                                       disp_cur_7 = FND_7;
                                       disp_cur_8 = FND_8;
                                       disp_cur_9 = FND_9;
                           }
                         }
                         COUNT=0;

                         if(COL2==0){
                         Delay_ms(1);
                           if(COL2==0){
                                       key_confirm();
                                       key=3;
                                       if(FWD==3)FND_2=key;
                                       if(FWD==4)FND_3=key;
                                       if(FWD==7) FND_6=key;
                                       if(FWD==8) FND_7=key;
                                       if(FWD==9) FND_8=key;
                                       if(FWD==10) FND_9=key;

                                       disp_cur_2 = FND_2;
                                       disp_cur_3 = FND_3;
                                       disp_cur_6 = FND_6;
                                       disp_cur_7 = FND_7;
                                       disp_cur_8 = FND_8;
                                       disp_cur_9 = FND_9;
                           }
                         }

                         COUNT=0;

                         if(COL3==0){                          //UP KEY
                         Delay_ms(1);
                           key_confirm();
                               if(COL3==0){
                                      j_1=m_1,j_2=m_2,j_3=m_3,j_4=m_4;
                                      key_confirm();

                                      if(FWD==1){
                                                 Delay_ms(5);
                                                 FND_0=j_1;
                                                 m_1++;
                                                 if(m_1>25)
                                                 m_1=25;
                                                 disp_cur_0 = FND_0;
                                       }
                                       if(FWD==2){
                                                  Delay_ms(5);
                                                  FND_1=j_2;
                                                  m_2++;
                                                  if(m_2>25)
                                                  m_2=25;
                                                  disp_cur_1 = FND_1;
                                       }
                                       if(FWD==5){
                                                  Delay_ms(5);
                                                  FND_4=j_3;
                                                  m_3++;
                                                  if(m_3>25)
                                                  m_3=25;
                                                  disp_cur_4 = FND_4;
                                       }
                                       if(FWD==6){
                                                  Delay_ms(5);
                                                  FND_5=j_4;
                                                  m_4++;
                                                  if(m_4>25)
                                                  m_4=25;
                                                  disp_cur_5 = FND_5;
                                       }
                                }
                         }

                         COUNT=0;
           ROW0 = 1;
           ROW1 = 0;
           ROW2 = 1;
           ROW3 = 1;
                         if(COL0==0){
                         Delay_ms(1);
                           if(COL0==0){
                                       key_confirm();
                                       key=4;
                                       if(FWD==3)FND_2=key;
                                       if(FWD==4)FND_3=key;
                                       if(FWD==7) FND_6=key;
                                       if(FWD==8) FND_7=key;
                                       if(FWD==9) FND_8=key;
                                       if(FWD==10) FND_9=key;

                                       disp_cur_2 = FND_2;
                                       disp_cur_3 = FND_3;
                                       disp_cur_6 = FND_6;
                                       disp_cur_7 = FND_7;
                                       disp_cur_8 = FND_8;
                                       disp_cur_9 = FND_9;
                           }
                         }

                         COUNT=0;

                         if(COL1==0){
                         Delay_ms(1);
                           if(COL1==0){
                                       key_confirm();
                                       key=5;
                                       if(FWD==3)FND_2=key;
                                       if(FWD==4)FND_3=key;
                                       if(FWD==7) FND_6=key;
                                       if(FWD==8) FND_7=key;
                                       if(FWD==9) FND_8=key;
                                       if(FWD==10) FND_9=key;

                                       disp_cur_2 = FND_2;
                                       disp_cur_3 = FND_3;
                                       disp_cur_6 = FND_6;
                                       disp_cur_7 = FND_7;
                                       disp_cur_8 = FND_8;
                                       disp_cur_9 = FND_9;
                           }
                         }

                         COUNT=0;

                         if(COL2==0){
                         Delay_ms(1);
                           if(COL2==0){
                                       key_confirm();
                                       key=6;
                                       if(FWD==3)FND_2=key;
                                       if(FWD==4)FND_3=key;
                                       if(FWD==7) FND_6=key;
                                       if(FWD==8) FND_7=key;
                                       if(FWD==9) FND_8=key;
                                       if(FWD==10) FND_9=key;

                                       disp_cur_2 = FND_2;
                                       disp_cur_3 = FND_3;
                                       disp_cur_6 = FND_6;
                                       disp_cur_7 = FND_7;
                                       disp_cur_8 = FND_8;
                                       disp_cur_9 = FND_9;
                           }
                         }
                         COUNT=0;

                         if(COL3==0){                             //DOWN KEY
                         Delay_ms(1);

                         /*if((j_1==0) || (j_2==0) || (j_3==0) || (j_4==0)){
                            if(j_1==0) j_1=27; if(j_2==0) j_2=27;
                            if(j_3==0) j_3=27; if(j_4==0) j_4=27;
                         }
                           m_1=j_1,m_2=j_2,m_3=j_3,m_4=j_4;*/
                           //--j_1,--j_2,--j_3,--j_4;
                           if(COL3==0){
                                       key_confirm();
                                       m_1=0,m_2=0,m_3=0,m_4=0;
                                       if(FWD==1){
                                                  //if(j_1==0) j_1=26;
                                                  key_confirm();
                                                  FND_0=j_1;
                                                  j_1--;
                                                  if(j_1<0)
                                                  j_1=0;
                                                  disp_cur_0 = FND_0;
                                       }
                                       if(FWD==2){
                                                  //if(j_2==0) j_2=26;
                                                  key_confirm();
                                                  FND_1=j_2;
                                                  j_2--;
                                                  if(j_2<0)
                                                  j_2=0;
                                                  disp_cur_1 = FND_1;
                                        }
                                        if(FWD==5){
                                                  //if(j_3==0) j_3=26;
                                                  key_confirm();
                                                  FND_4=j_3;
                                                  j_3--;
                                                  if(j_3<0)
                                                  j_3=0;
                                                  disp_cur_4 = FND_4;
                                       }
                                       if(FWD==6){
                                                  //if(j_4==0) j_4=26;
                                                  key_confirm();
                                                  FND_5=j_4;
                                                  j_4--;
                                                  if(j_4<0)
                                                  j_4=0;
                                                  disp_cur_5 = FND_5;
                                       }


                           }

                         }
                         COUNT=0;
           ROW0 = 1;
           ROW1 = 1;
           ROW2 = 0;
           ROW3 = 1;

                         if(COL0==0){
                         Delay_ms(1);
                           if(COL0==0){
                                       key_confirm();
                                       key=7;
                                       if(FWD==3)FND_2=key;
                                       if(FWD==4)FND_3=key;
                                       if(FWD==7) FND_6=key;
                                       if(FWD==8) FND_7=key;
                                       if(FWD==9) FND_8=key;
                                       if(FWD==10) FND_9=key;

                                       disp_cur_2 = FND_2;
                                       disp_cur_3 = FND_3;
                                       disp_cur_6 = FND_6;
                                       disp_cur_7 = FND_7;
                                       disp_cur_8 = FND_8;
                                       disp_cur_9 = FND_9;
                           }
                         }

                         COUNT=0;

                         if(COL1==0){
                         Delay_ms(1);
                           if(COL1==0){
                                       key_confirm();
                                       key=8;
                                       if(FWD==3)FND_2=key;
                                       if(FWD==4)FND_3=key;
                                       if(FWD==7) FND_6=key;
                                       if(FWD==8) FND_7=key;
                                       if(FWD==9) FND_8=key;
                                       if(FWD==10) FND_9=key;

                                       disp_cur_2 = FND_2;
                                       disp_cur_3 = FND_3;
                                       disp_cur_6 = FND_6;
                                       disp_cur_7 = FND_7;
                                       disp_cur_8 = FND_8;
                                       disp_cur_9 = FND_9;
                           }
                         }

                         COUNT=0;

                         if(COL2==0){
                         Delay_ms(1);
                           if(COL2==0){
                                       key_confirm();
                                       key=9;
                                       if(FWD==3)FND_2=key;
                                       if(FWD==4)FND_3=key;
                                       if(FWD==7) FND_6=key;
                                       if(FWD==8) FND_7=key;
                                       if(FWD==9) FND_8=key;
                                       if(FWD==10) FND_9=key;

                                       disp_cur_2 = FND_2;
                                       disp_cur_3 = FND_3;
                                       disp_cur_6 = FND_6;
                                       disp_cur_7 = FND_7;
                                       disp_cur_8 = FND_8;
                                       disp_cur_9 = FND_9;
                           }
                         }
                         COUNT=0;

                         if(COL3==0){                         //Forward Key
                         Delay_ms(1);
                           if(COL3==0){

                                       key_confirm();       //initially FWD=1
                                       COUNT=0;
                                       FWD++;

                                       if(FWD>=10) FWD=10;
                                       j=FWD;
                                       blink_pos[j] = 1;
                                       blink_pos[j-1] = 0;
                                       //if(FWD==10) last_FWD=1;
                                       //blink_pos[10] = 0,blink_pos[1] = 1, ,last_FWD=1;

                                       last_blink=0;

                           }
                         }
                         COUNT=0;
               ROW0 = 1;
               ROW1 = 1;
               ROW2 = 1;
               ROW3 = 0;

                         if(COL0==0){                        //Program Key
                         Delay_ms(1);
                           if(COL0==0){
                                       key_confirm();
                                       prg_key=1;
                                       if(prg_key_count==1){
                                       disp_pre_0=FND_0;disp_pre_1=FND_1;disp_pre_2=FND_2;disp_pre_3=FND_3;disp_pre_4=FND_4;
                                       disp_pre_5=FND_5;disp_pre_6=FND_6;disp_pre_7=FND_7;disp_pre_8=FND_8;disp_pre_9=FND_9;
                                       }

                                       FND_0=0,FND_1=0,FND_2=10,FND_3=10,FND_4=0,FND_5=0,FND_6=10,FND_7=10,FND_8=10,FND_9=10;
                                       prg_key_count=prg_key_count+1;

                                       bulb=0;
                                       m_1=0,m_2=0,m_3=0,m_4=0;
                                       FWD=1;
                                       blink_pos[0]=0;blink_pos[1]=1;blink_pos[2]=0;blink_pos[3]=0;blink_pos[4]=0;blink_pos[5]=0;blink_pos[6]=0;blink_pos[7]=0;blink_pos[8]=0;blink_pos[9]=0;blink_pos[10]=0;

                           }
                         }
                         COUNT=0;

                         if(COL1==0){
                         Delay_ms(1);
                           if(COL1==0){
                                       key_confirm();
                                       key=0;
                                       if(FWD==3) FND_2=key;
                                       if(FWD==4) FND_3=key;
                                       if(FWD==7) FND_6=key;
                                       if(FWD==8) FND_7=key;
                                       if(FWD==9) FND_8=key;
                                       if(FWD==10) FND_9=key;

                                       disp_cur_2 = FND_2;
                                       disp_cur_3 = FND_3;
                                       disp_cur_6 = FND_6;
                                       disp_cur_7 = FND_7;
                                       disp_cur_8 = FND_8;
                                       disp_cur_9 = FND_9;

                           }
                         }

                         COUNT=0;

                         if(COL2==0){                         //Enter Key
                         Delay_ms(1);
                           if(COL2==0){
                                       key_confirm();
                                       bulb=1;
                                       //enter=1;
                                       //prg_key=0;
                           }
                         }
                         COUNT=0;

                         if(COL3==0){                              //Reverse Key
                           Delay_ms(1);

                           //if(last_FWD==1) REV=10,blink_pos[10]=0,last_FWD=0;
                           if(COL3==0){
                                       key_confirm();
                                       if(FWD<=1) FWD=2;
                                       FWD--;
                                       k=FWD;
                                       blink_pos[k]=1;
                                       blink_pos[k+1]=0;


                           }
                         }
                         COUNT=0;
                         if(prg_key_count==3){
                         last=16000;
                         }

                         if((last>15000) && (bulb==0)){
                         FND_0=disp_pre_0;FND_1=disp_pre_1;FND_2=disp_pre_2;FND_3=disp_pre_3;FND_4=disp_pre_4;
                         FND_5=disp_pre_5;FND_6=disp_pre_6;FND_7=disp_pre_7;FND_8=disp_pre_8;FND_9=disp_pre_9;

                         blink_pos[0]=0;blink_pos[0]=0;blink_pos[2]=0;blink_pos[3]=0;blink_pos[4]=0;blink_pos[5]=0;blink_pos[6]=0;blink_pos[7]=0;blink_pos[8]=0;blink_pos[9]=0;blink_pos[10]=0;
                         prg_key_count=1;
                         prg_key=0;
                         last=0;
                         FWD=0;
                          m_1=0,m_2=0,m_3=0,m_4=0;
                         bulb=1;
                         }

                         if((last<15000) && (bulb==1)){

                                         if((FND_2==10)||(FND_3==10)||(FND_6==10) || (FND_7==10) || (FND_8==10)|| (FND_9==10)){
                                         FND_0=4;FND_1=17;FND_2=0;FND_3=0;FND_4=17;
                                         FND_5=17;FND_6=10;FND_7=10;FND_8=10;FND_9=10;
                                         FWD=0;
                                         prg_key_count=1;
                                         prg_key=0;
                                         last=0;
                                         m_1=0,m_2=0,m_3=0,m_4=0;
                                         //Test=1;
                                         blink_pos[0]=0;blink_pos[0]=0;blink_pos[2]=0;blink_pos[3]=0;blink_pos[4]=0;blink_pos[5]=0;blink_pos[6]=0;blink_pos[7]=0;blink_pos[8]=0;blink_pos[9]=0;blink_pos[10]=0;
                                         error=1;
                                         }
                                         else if((FND_2==0)&&(FND_3==0)&&(FND_6==0) && (FND_7==0) && (FND_8==0)&& (FND_9==0)){
                                         FND_0=4;FND_1=17;FND_2=0;FND_3=0;FND_4=17;
                                         FND_5=17;FND_6=10;FND_7=10;FND_8=10;FND_9=10;
                                         FWD=0;
                                         prg_key_count=1;
                                         prg_key=0;
                                         last=0;
                                         m_1=0,m_2=0,m_3=0,m_4=0;
                                         blink_pos[0]=0;blink_pos[0]=0;blink_pos[2]=0;blink_pos[3]=0;blink_pos[4]=0;blink_pos[5]=0;blink_pos[6]=0;blink_pos[7]=0;blink_pos[8]=0;blink_pos[9]=0;blink_pos[10]=0;
                                         error=1;
                                         }
                                         
                                         else{
                                         FND_0=disp_cur_0;FND_1=disp_cur_1;FND_2=disp_cur_2;FND_3=disp_cur_3;FND_4=disp_cur_4;
                                         FND_5=disp_cur_5;FND_6=disp_cur_6;FND_7=disp_cur_7;FND_8=disp_cur_8;FND_9=disp_cur_9;
                                         FWD=0;
                                         prg_key_count=1;
                                         prg_key=0;
                                         last=0;
                                         m_1=0,m_2=0,m_3=0,m_4=0;
                                         //Test=1;
                                         blink_pos[0]=0;blink_pos[0]=0;blink_pos[2]=0;blink_pos[3]=0;blink_pos[4]=0;blink_pos[5]=0;blink_pos[6]=0;blink_pos[7]=0;blink_pos[8]=0;blink_pos[9]=0;blink_pos[10]=0;
                                         error=0;
                                         }
                         }
					if(read==1){

								//if '?' Send the data
                                               MAX_CONTROL = 1;
                                               UART1_Write(38);
                                               UART1_Write(FND_0+65); // and send data via UART
                                               UART1_Write(FND_1+65);
                                               UART1_Write(FND_2+48);
                                               UART1_Write(FND_3+48);
                                               UART1_Write(FND_4+65);
                                               UART1_Write(FND_5+65);
                                               UART1_Write(FND_6+48);
                                               UART1_Write(FND_7+48);
                                               UART1_Write(FND_8+48);
                                               UART1_Write(FND_9+48);
                                               UART1_Write(155);
                                               Delay_ms(1);
                                               MAX_CONTROL = 0;
					read=0;	

					}

					if(write==1){
						input_string[index]=sdat;
						index++;
							if(index==13) index=0;
					write=0;
					}
				
                                              
                        
                         if(bulb==1){
                         display_2();
                         }
                         else{
                         display();
                         }


         
         };

}

- - - Updated - - -

Simulator is not wrong. Because same simulator and hardware has been tasted with other code, which is working fine.
 

Simulator is not wrong. Because same simulator and hardware has been tasted with other code, which is working fine.
My experience with MikroC teaches me it's simulation is not as good as claimed, that's one of the reasons I don't use it myself. When I work on a project I need to know, as best as is possible, it will work before building hardware.

Your code is poorly commented and to be honest, quite difficult to follow. I'm not actually sure what it's purpose is and the variable names don't give many clues. Why such a long and complicated keypad routine? Write a routine to scan the keypad, then if it returns a value do the processing according to the key being pressed, doing everything 'in-line' with the key scan make the code long and confusing.

Looking at your routine 'key_confirm()', and I do not know what it's supposed to do, why not write as:
Code:
void key_confirm()
{
  do
  {
    COUNT++;
    if((COUNT <= 500) && (COUNT % 20 == 0)) display();
  }while(COUNT < 700);
}

What does Timer 0 do? You initialize it, start it and process the interrupts it generates but do nothing else with it. If the intention is to make the 'blink' and 'last' variables change, they will also do so if the UART receives a character. It would be a good idea to add some protection against framing and overrun errors too!

Brian.
 

Thanx brian.
I knew that whole code will confuse you. Let me explain a bit. Timer0 interrupt is to increment the variables blink and last. As i told i have 10 of 16 segment numeric display. When Program key on keypad is pressed, particular data will be displayed. It's alphabet on 1'st, 2'nd, 5'th and 6'th position and dash'-' on 3,4,7,8,9 and 10th position. Now when program key is pressed, 1st character will blink. Now for blinking, it's necessary that character will appear for some time and rest of the time it will show nothing. Now applying delay won't do as it will hamper whole operation of the display. So what i did is incremented the variable 'blink'. For half of it's increment data which has to be displayed, will appear and for rest of the increment data for blank will be displayed.As sending 1 will ground the segments it won't glow. So that serve my purpose of blinking for some time. When forward key is pressed, character at 2nd position will start blink. For alphabets, increment and decrements keys are there for A-Z and back from Z-A. At digits position directly numbers are there on key pad. As keys for increment and decrement are there, same is for forward and reverse keys. I have only one variable 'key' to detect the pressed key. Now i had to display the detected key according to position according to forward and reverse key. So i had to do all the jugglery in the keypad routine itself. Because what was happening is as reversed or forward key is used to press, key variable was regaining its current value. So it used to change the displayed character at it's current and forward or backward position. I solved that issue in doing all the things in keypad routine itself. There could be some other logic too. But what came in my mind is this. Now about 'last' variable. Purpose of this is, if somebody pressed Program key and didn't enter any value,(last variable will start incrementing when program key is pressed), so when last variable will cross particular value, last values will be retained and will be displayed. Otherwise last variable has to cross the particular value and 'Enter' key is pressed, so new values will be displayed. So if i increment the blink and last values on serial interrupt, it won't serve my purpose. Now about 'key_confirm()'. When this function is called, it will run until 'count' variable is '<700', and at every 20th incremented step function 'display display will be called. This serves purpose of key debouncing and maintains the speed of displaying the character when increment or decrement key is pressed. Otherwise character will display very rapidly and get displayed at single press.
Thats all about main routine.Timer 0 interrupt is working fine. Now issue is with serial interrupt. It keeps on appearing without sending any character. I know this because my display will get stuck and won't work. So why this is happening with serial interrupt. I am not getting reason behind this. Do anything in main routine hampering the serial interrupt. This code is not finalize yet, thats why some unused variables could be there.
Thanx for your time brian.
 

Thank you. Each person has their own programming style but to be honest, I would have structured it in a completely different way. I loaded a copy of MikroeC 6.6.2 and passed it your source code but it wouldn't compile for me and not being familiar with it I didn't change anything to make it work.

Here are a few suggestions:
In 'interrupt()'
1. swap the two lines that reload TMR0. Loading the high (H) register first will minimize the chance of another interrupt occurring straight away.
2. Try swapping the UART interrupt so it is checked before the timer interrupt instead of after it.
3. declare all variables that are used both inside and outside the ISR as 'volatile'.

4. Make sure the RCON register is configured so you are disabling interrupt priority control.

Brian.
 

OK brian, i will implement your suggestion and will let you know if any progress is there.
 

hello,
i tried wt u told. But no result. RCIF is always high and RCREG showing garbage values.
 

Can you create a small program that simply does the UART part of your project that still shows the problem. (Basically the last code you posted had so much other code in there that it is hard to see what is really going on with the UART.)
For example, write some code that simply sends a character and has it echoed back and check that you are receiving the character you send. Perhaps extend it to communicate with a PC so you can check that the key you type is what is received and perhaps sent back to the PC.
Once you have all of that working then you can add back in the rest of the code until something breaks in which case you wil have some idea where to look for the problem.
Susan
 

Thanx susan,

i will try it.
 

I wrote another program, having only serial interrupt routine. But still RCIF flag is continuously high and RCREG showing garbage value.
Code:
#include <math.h>
#define adjust 1000//500,1000
#define bright 1
#define MAX_CONTROL   PORTC.B5
#define TIMER_START_VALUE   250   //230,200,255,500
#define TIMER_START_VALUE_1 250  //210,160,254,255

unsigned char index,sdat=0,read=0,write=0;
volatile unsigned char input_string[12];
char FND_0=1,FND_1=2;

/*********************************************************/
void interrupt(){

     if(PIR1.RCIF==1){
            Test=~Test;

                   if(RCSTA.OERR){
                   RCSTA.CREN=0;
                   Nop();
                   Nop();
                   RCSTA.CREN=1;
                   }
                   if(RCSTA.FERR){
                   RCSTA.SPEN=0;
                   Nop();
                   Nop();
                   RCSTA.SPEN=1;
                   }
                        MAX_CONTROL =1;
                        UART1_Write(RCREG);
                        MAX_CONTROL =0;
                                
                                if(RCREG==64){
                                read=1;
                                MAX_CONTROL =1;
                                UART1_Write(FND_0);
                                MAX_CONTROL =0;
                                }
                                else{
                                     sdat=RCREG;
                                     write=1;
                                     MAX_CONTROL =1;
                                     UART1_Write(FND_1);
                                     MAX_CONTROL =0;
                                }

     PIR1.RCIF=0;
     }
           if(INTCON.TMR0IF){
                    TMR0L = TIMER_START_VALUE;
                    TMR0H = TIMER_START_VALUE_1;
                    TMR0IF_bit = 0;
                    }


}


void main() {

     TRISD = 0x00;            /*//PortD as output*/
     PORTD = 0x00;            /*//Initial value*/
     TRISC = 0b10000000;
     TRISB = 0x55;             //0 as o/p, 1 as i/p
     PORTB = 0x00;
     INTCON =0b11100000 ;           /*//0xc0;0xa0*/

     TMR0ON_bit = 0;          /*//Stop timer 0 during set up*/
     T08BIT_bit = 0;      /*// Enable 16 bit timer*/
     T0CS_bit = 0;        /*// use internal clock to trigger timer to count*/
     PSA_bit = 0;         /*// Use the prescaler to slow the timer down*/

     // prescaler
     
     T0PS0_bit = 0; //1             /*//for 16 bit timer 1/4 of clock freq   001*/
     T0PS1_bit = 1; //0
     T0PS2_bit = 0; //0

     TMR0L = TIMER_START_VALUE;
     TMR0H = TIMER_START_VALUE_1;

    /*TXSTA  = 0b00100000;
     RCSTA = 0b10010000;

     BAUDCON.BRG16 = 0;
     TXSTA.BRGH    = 0;
     //SPBRGH:SPBRG = 129;   //for 20MHz crystal
     SPBRG = 25;   //for 20MHz crystal*/


     UART1_Init(9600);
     Delay_ms(200);
     PIR1.RCIF=0;
     RCREG=0;
     PIE1 = 0b00100000;  //RCIE bit enabled
     MAX_CONTROL=0;
     TMR0ON_bit = 1;       //start the timer

         while(1){
                  
         };

}
 

What clock frequency are you using?

With a 20MHz clock, BRG16 = 0 and BRGH = 0, my calculation is SPBRG should be 32 (decimal) to get 9600 Bauds. I would expect the line "UART1_init(9600)" to overwrite the setting you gave it anyway.

What is 'Test' ? If it is the port being used by the UART it will cause you problems.

Brian.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top