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] C code is correct but it is defective in real and simulator.

Status
Not open for further replies.

lindodv

Junior Member level 1
Junior Member level 1
Joined
Jul 4, 2014
Messages
16
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Visit site
Activity points
121
I used Mikoc pro for PIC v6.4 software - and I used switch command for increasing size of C code.
if I decrease size of code(by deleting some switch commands ) everything is correct but...I don't know why! :-(
I add simulator-c code- and hex in new folder.


Code:
// LCD module connections
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RB0_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D7 at RB3_bit;

sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;
// End LCD module connections

char *texttimer = "00/00:00";
unsigned char *textworktimetimer = "00:00";
unsigned char *timer = "00/00:00:00";


unsigned int i=0,set=0,inter=0;
unsigned short count_m=0,count_h=0,count_d=0;
unsigned int count_twm=0 ,count_twh=0;
unsigned int Count=0 ,count_min=0 ,count_hour=0 ,count_day=0 ;

unsigned short timerON=0;

void setswitch () {

        if (PORTA.F0 == 0) {     // set push button
            delay_ms(10);
            if (PORTA.F0 == 0) {
                set ++; } }
                while (PORTA.F0 == 0);
        if (set >= 5) {
            set = 0; }

        switch(set){      //0-4
          case 0:
                PORTD = 0b00000001;
                break;
          case 1:
                PORTD = 0b00000010;
                switch(inter){   //0-5 taghvim - time
                       case 0:
                              break;
                       case 1:
                              break;
                       case 2:
                              break;
                       case 3:
                              break;
                       case 4:
                              break;
                       case 5:
                              break; }
                break;
          case 2: // timer   F3=inter push button
                if (PORTA.F3 == 0) {
                    delay_ms(100);
                    if (PORTA.F3 == 0) {
                        inter ++; } }
                    while (PORTA.F3 == 0);
                    if (inter >=7) {
                        inter =0; }
                switch(inter){  //0-6   timer-counter
                       case 0:
                              PORTD = 0b00000001;
                              Lcd_Out(2,1,"Timer is OFF");
                              timerON = 0;
                              break;
                       case 1: // inter minute
                              PORTD = 0b00000010;
                             Lcd_Out(2,1,"SET Timer  ");
                             if (PORTA.F2 == 0) {
                                  delay_ms(100);
                                 if (PORTA.F2 == 0) {
                                      count_m ++; } }
                             if (PORTA.F1 == 0) {
                                  delay_ms(100);
                                 if (PORTA.F1 == 0) {
                                     count_m --; } }
                              texttimer[6] = ((count_m/10)%10)+48;
                              texttimer[7] = ((count_m/1)%10)+48;
                              delay_us(10000);
                              Lcd_out(2,18,"  ");
                              delay_us(10000);
                              texttimer[0] = ((count_d/10)%10)+48;
                              texttimer[1] = ((count_d/1)%10)+48;
                              texttimer[3] = ((count_h/10)%10)+48;
                              texttimer[4] = ((count_h/1)%10)+48;
                              texttimer[6] = ((count_m/10)%10)+48;
                              texttimer[7] = ((count_m/1)%10)+48;
                              Lcd_Out(2,12,texttimer);
                              break;
                       case 2: // inter hour
                              PORTD = 0b00000011;
                             Lcd_Out(2,1,"SET Timer  ");
                             if (PORTA.F2 == 0) {
                                  delay_ms(100);
                                 if (PORTA.F2 == 0) {
                                      count_h ++; } }
                             if (PORTA.F1 == 0) {
                                  delay_ms(100);
                                 if (PORTA.F1 == 0) {
                                     count_h --; } }
                              texttimer[3] = ((count_h/10)%10)+48;
                              texttimer[4] = ((count_h/1)%10)+48;
                              delay_us(10000);
                              Lcd_out(2,15,"  ");
                              delay_us(10000);;
                              texttimer[0] = ((count_d/10)%10)+48;
                              texttimer[1] = ((count_d/1)%10)+48;
                              texttimer[3] = ((count_h/10)%10)+48;
                              texttimer[4] = ((count_h/1)%10)+48;
                              texttimer[6] = ((count_m/10)%10)+48;
                              texttimer[7] = ((count_m/1)%10)+48;
                              Lcd_Out(2,12,texttimer);
                              break;
                       case 3:  // inter day
                              PORTD = 0b00000100;
                             Lcd_Out(2,1,"SET Timer  ");
                             if (PORTA.F2 == 0) {
                                  delay_ms(100);
                                 if (PORTA.F2 == 0) {
                                      count_d ++; } }
                             if (PORTA.F1 == 0) {
                                  delay_ms(100);
                                 if (PORTA.F1 == 0) {
                                     count_d --; } }
                              texttimer[0] = ((count_d/10)%10)+48;
                              texttimer[1] = ((count_d/1)%10)+48;
                              delay_us(10000);
                              Lcd_out(2,12,"  ");
                              delay_us(10000);
                              texttimer[0] = ((count_d/10)%10)+48;
                              texttimer[1] = ((count_d/1)%10)+48;
                              texttimer[3] = ((count_h/10)%10)+48;
                              texttimer[4] = ((count_h/1)%10)+48;
                              texttimer[6] = ((count_m/10)%10)+48;
                              texttimer[7] = ((count_m/1)%10)+48;
                              Lcd_Out(2,12,texttimer);
                              break;
                       case 4:   // inter minute for work time
                              PORTD = 0b00000101;
                             Lcd_Out(2,1,"SET Work Time ");
                             if (PORTA.F2 == 0) {
                                  delay_ms(100);
                                 if (PORTA.F2 == 0) {
                                      count_twm ++; } }
                             if (PORTA.F1 == 0) {
                                  delay_ms(100);
                                 if (PORTA.F1 == 0) {
                                     count_twm --; } }
                              textworktimetimer[3] = ((count_twm/10)%10)+48;
                              textworktimetimer[4] = ((count_twm/1)%10)+48;
                              delay_ms(50);
                              Lcd_out(2,18,"  ");
                              delay_ms(50);
                              textworktimetimer[0] = ((count_twh/10)%10)+48;
                              textworktimetimer[1] = ((count_twh/1)%10)+48;
                              textworktimetimer[3] = ((count_twm/10)%10)+48;
                              textworktimetimer[4] = ((count_twm/1)%10)+48;
                              Lcd_Out(2,15,textworktimetimer);
                              break;

                       case 6:
                              Lcd_Out(2,1,"Timer  is  ON       ");
                              delay_ms(2000);
                              Lcd_Cmd(_LCD_CLEAR);
                              timerON = 1;
                              set =0;
                              break; }
                break;
          case 3:
                PORTD = 0b00001000;
                switch(inter){   //0-3
                       case 0:
                              break;
                       case 1:
                              break;
                       case 2:
                              break;
                       case 3:
                              break; }
                break;
          case 4:
                PORTD = 0b00010000;
                switch(inter){   //0-3
                       case 0:
                              Lcd_Out(2,1,"SET Work Time ");
                             if (PORTA.F2 == 0) {
                                  delay_ms(100);
                                 if (PORTA.F2 == 0) {
                                      count_twh ++; } }
                             if (PORTA.F1 == 0) {
                                  delay_ms(100);
                                 if (PORTA.F1 == 0) {
                                     count_twh --; } }
                              textworktimetimer[0] = ((count_twh/10)%10)+48;
                              textworktimetimer[1] = ((count_twh/1)%10)+48;
                              delay_ms(150);
                              Lcd_out(2,15,"  ");
                              delay_ms(150);
                              textworktimetimer[0] = ((count_twh/10)%10)+48;
                              textworktimetimer[1] = ((count_twh/1)%10)+48;
                              textworktimetimer[3] = ((count_twm/10)%10)+48;
                              textworktimetimer[4] = ((count_twm/1)%10)+48;
                              Lcd_Out(2,15,textworktimetimer);
                              break;
                       case 1:
                              break;
                       case 2:
                              break;
                       case 3:
                              break; }
                break; }

}

void main() {

  Lcd_Init();                                    // Initialize LCD
  Lcd_Cmd(_LCD_CLEAR);                           // Clear LCD
  Lcd_Cmd(_LCD_CURSOR_OFF);                      // Turn cursor off

   OPTION_REG = 0b00000111;       //RBPU=0 INTEDG=0 T0CS=0(internal) T0SE=0(Reaction on low2high) PSA=0(work with prescaler) PS2,PS1,PS0=111(1:256)

   TRISA = 0xFF;
   ADCON1 = 0x07;
   CMCON = 0x07;

   TRISD = 0;
   PORTD = 0;
   timerON =0;


   while (1)
 {
    if (timerON==1) {
     setswitch ();
    }
 
         if (timerON==0) {
             while (! TMR0);
                     TMR0 = 0;
                     Count ++;

                  timer[0] = ((Count/100000000)%10)+48;
                  timer[1] = ((Count/10000000)%10)+48;
                  timer[3] = ((Count/1000000)%10)+48;
                  timer[4] = ((Count/100000)%10)+48;
                  timer[6] = ((Count/10000)%10)+48;
                  timer[7] = ((Count/1000)%10)+48;
                  timer[9] = ((Count/100)%10)+48;
                  timer[10] = ((Count/10)%10)+48;
            Lcd_Out(2, 1,"timer");
            Lcd_Out(2, 10,timer);

           }

  }
}
 

Attachments

  • New folder.rar
    26.8 KB · Views: 147

I haven't got a compiler here at the moment but maybe it is objecting to the break statement at the end of the switch() function. You don't need one right at the end but it is wise to add a 'default' case to cater for unexpected values being used which may not be intercepted by individual case checks.

Brian.
 

thanks
@betwixt, switch() function should not work at all, look at the void main()function. is this code a simply for Defects in design compilers? or other compilers work fine!? or all that problems occur only for me!
 

And what is the problem ? Display is garbage ? I am sure you are getting "IRP_bit must be set manually..." warning while Compiling if you are using PIC16F device. Switch to PIC18F.

The below code can be eliminated as it does nothing.


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
case 1:
               
                switch(inter){   //0-5 taghvim - time
                       case 0:
                              break;
                       case 1:
                              break;
                       case 2:
                              break;
                       case 3:
                              break;
                       case 4:
                              break;
                       case 5:
                              break; }

 

    V

    Points: 2
    Helpful Answer Positive Rating
@milan.rajik
the problem is some non-logical problems. why ( if (timerON==1) { ) would work in the PIC memory and Caused an error!
 

Hi, I found the problem. Your setswitch() function is too big and stack will over flow.


Explain how the system has to work. I will write a code.
 
Last edited:

and can you format it so each level of testing is indented, I find the '}}' lines quite difficult to follow, it's difficult to find the matching '{'.

Remember that the { and } are used to enclose a block containing several lines of code. If there is only one line, you can omit them. For example:
Code:
                 if (PORTA.F2 == 0) {
                                      count_m ++; } }

can be written as
Code:
if(PORTA.F2 == 0) count_m++;

Brian.
 

    V

    Points: 2
    Helpful Answer Positive Rating
thanks guys. when I delete all Lcd_out( ) inside switch {} functions, every thing work fine. I have no logical answer for this kind of problems! Mikroc should work with library for avoiding collisions(an event of two or more records being assigned the same identifier or location in memory.) and in the real Hardware I notice my chip uses High mA current (more than usual),for 3K information every thing shakes and start to falling...
 

Your code does not compiled in mikroC pro v6.40, due to the inefficient coding: the setswitch function is too large.
Study the help file, it says this:
PIC16 Specifics
Breaking Through Pages
In applications targeted at PIC16, no single routine should exceed one page (2,000 asm instructions). If a routine does not fit within one page, linker will report an error. When confront with this problem, maybe you should rethink the design of your application – try breaking the particular routine into several chunks, etc.


The code contains a logical error also:

Code:
.........
timerON = 1; // line 172, inside of 'setswitch' function (only here !!)
.........
timerON = 0; // line 236 in the 'main' function, it stays ever zero !!!
.....
if (timerON==1) {     //  never occuring !!!
     setswitch ();    //  so it will not run 
 }
.....
 
Last edited:
thanks zuisti,
you said "linker will report an error" but I don't get any error at all!
" setswitch (); // so it will not run " I don't want setswitch to run, when I delete " viod setswitch" every thing is working fine, then I disabled "setswitch" with a "never occuring If" but it seems "void setswitch" is not disable!
 

Hi;
Please post the entire mikroC project (the rar-ed folder), I'll try it compile on my PC. Using mikroc v6.40 and your unchanged 'MyProject.c' it is failed to me (linker errors due to a too large function).

Your setswitch function can run ONLY if the timerON==1 (line 241) but this is never occuring now because (as I wrote above) this variable stays zero, only the (never running) setswitch function set it to one (line 172). This is a little (but fatal) logical error ...
 

Hi;
Please post the entire mikroC project (the rar-ed folder), I'll try it compile on my PC. Using mikroc v6.40 and your unchanged 'MyProject.c' it is failed to me (linker errors due to a too large function).

Your setswitch function can run ONLY if the timerON==1 (line 241) but this is never occuring now because (as I wrote above) this variable stays zero, only the (never running) setswitch function set it to one (line 172). This is a little (but fatal) logical error ...

thanks. :-|
 

Attachments

  • New folder.rar
    26.8 KB · Views: 152

This is the same RAR as in your first post and does not contain the important project files. As I wrote please post the ENTIRE project folder after compiled (with c, cfg, mcpp1 and log, asm, lst ... files created by the compiler).
 
Last edited:

here is ENTIRE project folder.
 

Attachments

  • New.rar
    72.7 KB · Views: 126

This my last post in this thread ...

Your lastly provided c file is different from the first, here are missing a lot of codes (line 192 to 210 in the originally posted). So it is now compilable, as you can see in the lst file that the size of the setswitch function is 1475 words (ie smaller than 2k).

Study the above answers, there's the solution.

Tips:
- proceed step by step (eg, manage first only one button)
- you can debug the program at source-level in Proteus (use the COF file instead of the HEX: see the compiler output settings).

Good luck
 

    V

    Points: 2
    Helpful Answer Positive Rating
Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top