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.

[SOLVED] Help checking my code, hex file only 1kb after compiling - MikroC for PIC

Status
Not open for further replies.
hello,


Code C - [expand]
1
if (button_up == 0) or  (button_down == 0) or (button_ok == 0)


mikroC :
if ( (button_up == 0) || (button_down == 0) || (button_ok == 0) )

or

dummy=(button_up == 0)+(button_Down== 0)+(button_ok == 0);
if (dummy>0) // No button ON;
if (dummy==3) // 3 button ON
 

Great think I got all that now found and ingested
It's just standard C language and any text book or tutorial can teach you the syntax
 

So this appears not to work - I'm trying to put the number value of 'current_temp' on the lcd


Code C - [expand]
1
Lcd_out (2,8,current_temp);



So I tried this with no success


Code C - [expand]
1
Lcd_chr (2,8,current_temp);



So i realise I need to convert the file to something but not sure what or how exactly,

I found this but unsure if i'm even heading in the right direction?


Code C - [expand]
1
2
3
4
5
int target_temp;
unsigned char tar[7];
 
intToStr(target_temp,tar);  // the part was token from book end here
Lcd_chr(1,8,tar);

 

The mikroC manual clarifies that Lcd_Out() or Lcd_out_Cp() has to be used to output text strings. Lcd_Chr() is for single characters.
 
  • Like
Reactions: ghead

    ghead

    Points: 2
    Helpful Answer Positive Rating
    V

    Points: 2
    Helpful Answer Positive Rating
Thanks got Lcd working properly now.

Now when program is simulated everything seems to work fine as long as i comment out any one of the 3 'If' statements(with nested If's and while etc) that is detecting button presses for the menu. All 3 parts work when tested but cant have all 3 in my code at once otherwise it seems the 'Switch' statement is broken (simulator reports out of code) on the action of 'Break' at the completion of 'Case 0' or the first case executed.
Here is the 'case' that seems to be causing the issue, With one of the statements already commented out so that it will run

Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
case 7: //;button presses to alter target temperature/overshoot value
         if (button_up == 0) {
            Delay_ms(50);
            button_press_count = 0;
            while (button_up == 0) {
               //;wait for the button to be released
               button_press_count = button_press_count + 1;
               Delay_ms(100);
               if (button_press_count >= 5) {
                  if (a == 0) {
                     if (target_temp < 500) { target_temp = target_temp + 10; }
                     else target_temp = 500;
                     show_target_temp();
                  }
                  else {
                     if (overshoot < 500) { overshoot = overshoot + 10; }
                     else overshoot = 500;
                     show_overshoot();
                  }
                  Delay_ms(200);
                  //;stop the counter from rolling over
               button_press_count = 5;
               }
               if (button_press_count < 5) {
                  if (a==0) {
                     if (target_temp < 500) {Target_temp = target_temp + 1;}
                     else target_temp = 500;
                     show_target_temp();
                  }
                  if (a==1) {
                     if (overshoot < 500) {overshoot = overshoot + 1;}
                     else overshoot = 500;
                     show_overshoot();
                  }
               }
            state = return_state;
            }
         }
 
         if (button_down == 0) {
            Delay_ms(50);
            button_press_count = 0;
            while (button_down == 0) {
               //;wait for the button to be released
               button_press_count = button_press_count + 1;
               Delay_ms(100);
               if (button_press_count >= 5) {
                  if (a == 0) {
                     if (target_temp > 10) { target_temp = target_temp - 10; }
                     else target_temp = 0;
                     show_target_temp();
                  }
                  else {
                     if (overshoot > 10) { overshoot = overshoot - 10; }
                     else overshoot = 0;
                     show_overshoot();
                  }
                  Delay_ms(200);
                  //;stop the counter from rolling over
               button_press_count = 5;
               }
               if (button_press_count < 5) {
                  if (a==0) {
                     if (target_temp > 1) {Target_temp = target_temp - 1;}
                     else target_temp = 0;
                     show_target_temp();
                  }
                  if (a==1) {
                     if (overshoot > 1) {overshoot = overshoot - 1;}
                     else overshoot = 0;
                     show_overshoot();
                  }
               }
            state = return_state;
            }
         }
         /*
         if (button_ok == 0) {
            Delay_ms(50); //;simple debounce
            while (button_ok == 0) {Delay_ms(50);} //;wait for button to be released
            if (a == 0) {
               b = target_temp;     // Load target temp into write file
               eeprom_write (2,b); //;write the new target temp to eeprom
            }
            if (a == 1) {
               b = overshoot;      // Load target temp into write file
               eeprom_write (4,b); //;write the new overshoot value to eeprom
            }
            state = 0;
         } */
         break;



And here is full code:

Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
// LCD module connections
sbit LCD_RS at RD1_bit;
sbit LCD_RW at RD2_bit;
sbit LCD_EN at RD3_bit;
sbit LCD_D4 at RD4_bit;
sbit LCD_D5 at RD5_bit;
sbit LCD_D6 at RD6_bit;
sbit LCD_D7 at RD7_bit;
 
sbit LCD_RS_Direction at TRISD1_bit;
sbit LCD_RW_Direction at TRISD2_bit;
sbit LCD_EN_Direction at TRISD3_bit;
sbit LCD_D4_Direction at TRISD4_bit;
sbit LCD_D5_Direction at TRISD5_bit;
sbit LCD_D6_Direction at TRISD6_bit;
sbit LCD_D7_Direction at TRISD7_bit;
//Output Pins
sbit led_pin at RA0_bit;
sbit led_heater at RA1_bit;
sbit heater_relay at RA2_bit;
//Button Input Pins
sbit button_up at RB0_bit;
sbit button_down at RB1_bit;
sbit button_ok at RB2_bit;
sbit button_swop at RB3_bit;
//SPI pins
sbit spi_sck at RC0_bit;
sbit spi_cs at RC1_bit;
sbit spi_si at RC2_bit;
 
//Variables
unsigned int target_temp, button_press_count, return_state, state, case1, a, b;
unsigned int current_temp, state_, spi_out;
long overshoot, tmp_temp, last_temp;
unsigned short i, j, temp_direction;
unsigned char buffer, cur[7], tar[7], arrayFlow[7], temparray[7];
 
 
 
void get_current_temp(){
     //;read the value from MAX6675
     //;in some libraries, they suggest performing a "dummy read"
     //;to force the device to re-sample the temperature
     spi_cs = 0;
     Delay_ms(2);
     spi_cs = 1;
     Delay_ms(220);  //;the device should now have a new temperature in its buffer
     spi_cs = 0;  //;enable CS so we can read data back from the device
     Delay_ms(50); //;give the device time to settle
//     current_temp = spi1_read(buffer) <<8; // upper 8 bit from MAX6675
//     current_temp|= Spi1_Read(buffer);     // lower 8 bit
//     if (current_temp == 0x04);{current_temp = 999;}        //;bit 2 is normally low, and goes high when the thermistor is not connected
/*         current_temp = current_temp >> 3; //;bit-shift three places to the right
//         current_temp = current_temp * 0.25; //?the temperature reported has a resolution of 0.25 deg C so convert to actual degrees
         if (current_temp == 0); {          //;something has gone wrong here
         current_temp = 999;
         }
*/
 
}
 
void show_overshoot(){
     Lcd_cmd(_LCD_CLEAR); //Clear display
     Lcd_out (1,1,"Overshoot:");
     IntToStr(overshoot, arrayFlow);
     Lcd_out_cp(arrayFlow);
}
 
void show_target_temp(){
     Lcd_cmd(_LCD_CLEAR); //Clear display
     Lcd_out (1,1,"Target:");
     IntToStr(target_temp, arrayFlow);
     Lcd_out_cp(arrayFlow);
 
}
 
 
void IntMain() {
 
     TRISA = 0;
     ADCON1 = 6;
     TRISB = 0x0f; //Portb set button input pins
     TRISC = 0x04; //PortC set SPI pins I/O
     PORTA = 0;
     OPTION_REG.B7 = 0;  //enable pullups on portb (RBPU)
 
     SSPCON.B5 =1;       //Turn on SPI
//SPIPrepare       OSC / 16 = 1.25mhz clk  Sample data at end    Clk idle Low      SPI receive on clk edge High to Low
     SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV16, _SPI_DATA_SAMPLE_END, _SPI_CLK_IDLE_LOW, _SPI_HIGH_2_LOW);
     spi_cs = 1; //Set cs pin high  SPI device wait(sample)
     spi_sck = 0; //Set sck pin low SPI CLK idle
}
 
void main() {
 
     IntMain();
     Lcd_init();  //Initialise LCD
     Lcd_Cmd(_LCD_CLEAR); // Clear display
     Lcd_Cmd(_LCD_CURSOR_OFF); //no cursor on the lcd display
     led_heater = 0; //make sure we boot up with the heater off
     heater_relay = 1; //heater indicator is off
 
     last_temp =0;
     state = 0;
     overshoot = 0;
     temp_direction = 0;
     current_temp = 10;
     target_temp = 20;
 
     Lcd_Cmd(_LCD_CLEAR); //Clear display
     Lcd_Out(1,1,"Temperature");
     Lcd_Out(2,1,"Controller");
     Delay_ms(1000);
     target_temp = eeprom_read (2); //Read target temp value from eeprom
     if (target_temp == 0x0ff) {target_temp = 50;}
     overshoot = eeprom_read (4); //Read overshoot value from eeprom
     if (overshoot == 0x0ff) {overshoot = 10;}
 
 
   while (1){
     
      switch (state) {
 
           
         case 0: //show the target and current temperature(s)
         get_current_temp();
         Lcd_cmd(_LCD_CLEAR); //Clear display
         Lcd_out (1,1,"Target:");
//         target_temp = 1234;
         IntToStr(target_temp, arrayFlow);
         Lcd_out_cp(arrayFlow);
         Lcd_out (2,1,"Actual:");
         current_temp = 40;
         IntToStr(current_temp, arrayFlow);
         Lcd_out_cp(arrayFlow);
         Delay_ms(1000);
         state = 1;
         break;
 
 
         case 1: //;monitor the current temp and the target temp
         get_current_temp();
         led_heater = 1;
 
         tmp_temp = target_temp - overshoot;
 
         if (current_temp == 999) {
            heater_relay = 0;          //;something has gone wrong
            led_heater = 0;
            Lcd_out (2,1,"**** ERROR! ****");
         }
           
 
         if (last_temp <= current_temp) {temp_direction = 1;}   //temperature is rising
         else  temp_direction = 0; //temperature is falling
 
         if (current_temp > target_temp) {
            heater_relay = 0; //we're over the target temperature so shut the heaters off
            led_heater = 0;
         }
 
         if (current_temp > tmp_temp) {
            led_heater = 0;     //;threshold exceeded, turn off the heater(s)
            heater_relay = 0;
         }                         //temperature is rising
         else  {
            led_heater = 1;
            heater_relay = 1;
         }                         //;still not quite there, keep the heaters on
 
         if (current_temp < tmp_temp) {
            heater_relay = 1;   //;weve cooled down too much, turn the heaters on again
            led_heater = 1;
         }
         else {
            heater_relay = 0;   //;were cooling down, but are still pretty close to the target
            led_heater = 0;     //;temperature, so allow a little more cooling
            last_temp = current_temp;
         }
         //;now while the temperature is being monitored, check for button presses
         //;(on a button press, turn off the heater(s) just for good measure, and
         //;go to a new state just for handling changing the settings
         
         if ((button_up == 0)||(button_down == 0)||(button_ok == 0)) {
            heater_relay = 0;
            led_heater  = 0;
            Delay_ms(50);
            while ((button_up == 0)||(button_down == 0)||(button_ok == 0)) {
               Delay_ms(50); //;wait f the button to be released
            }
         state = 2;
         }
         //Delay_ms(1000);
         break;
 
 
         case 2: //;press buttons to change menu option
         Lcd_cmd(_LCD_CLEAR); //Clear display
         Lcd_out (1,1,"> Change Target");
         Lcd_out (2,3,"Edit Overshoot");
         state = 3;
         break;
 
         case 3:
         if ((button_up == 0)||(button_down == 0)) {
            Delay_ms(50);
            while ((button_up == 0)||(button_down == 0)) {
               Delay_ms (50); //;wait f the button to be released
            }
         state = 4;
         }
 
         if (button_ok == 0) {
            Delay_ms(50);
            while (button_ok == 0) {
               Delay_ms(50); //;wait f the button to be released
            }
         a = 0;
         state = 6;
         }
         break;
 
 
         case 4: //;press buttons to change menu option
         Lcd_cmd(_LCD_CLEAR); //Clear display
         Lcd_out (1,3,"Change Target");
         Lcd_out (2,1,"> Edit Overshoot");
         state = 5;
         break;
 
 
         case 5:
         if ((button_up == 0)||(button_down == 0)) {
            Delay_ms(50);
            while (button_up == 0) (button_down == 0);{ Delay_ms(50); }//;wait for the button to be released
            state = 2;
         }
         if (button_ok == 0) {
            Delay_ms(50); //;debounce the button press
            while (button_ok == 0) {Delay_ms(50);}
            a = 1;
            state = 6;
         }
         break;
 
 
         case 6: //;change the target temperature value
         if (a == 0) {
            show_target_temp();
            return_state = 6;
            state = 7;
         }
         if (a == 1) {
            show_overshoot();
            return_state = 7;
            state = 7;
         }
         break;
 
 
         case 7: //;button presses to alter target temperature/overshoot value
         if (button_up == 0) {
            Delay_ms(50);
            button_press_count = 0;
            while (button_up == 0) {
               //;wait for the button to be released
               button_press_count = button_press_count + 1;
               Delay_ms(100);
               if (button_press_count >= 5) {
                  if (a == 0) {
                     if (target_temp < 500) { target_temp = target_temp + 10; }
                     else target_temp = 500;
                     show_target_temp();
                  }
                  else {
                     if (overshoot < 500) { overshoot = overshoot + 10; }
                     else overshoot = 500;
                     show_overshoot();
                  }
                  Delay_ms(200);
                  //;stop the counter from rolling over
               button_press_count = 5;
               }
               if (button_press_count < 5) {
                  if (a==0) {
                     if (target_temp < 500) {Target_temp = target_temp + 1;}
                     else target_temp = 500;
                     show_target_temp();
                  }
                  if (a==1) {
                     if (overshoot < 500) {overshoot = overshoot + 1;}
                     else overshoot = 500;
                     show_overshoot();
                  }
               }
            state = return_state;
            }
         }
 
         if (button_down == 0) {
            Delay_ms(50);
            button_press_count = 0;
            while (button_down == 0) {
               //;wait for the button to be released
               button_press_count = button_press_count + 1;
               Delay_ms(100);
               if (button_press_count >= 5) {
                  if (a == 0) {
                     if (target_temp > 10) { target_temp = target_temp - 10; }
                     else target_temp = 0;
                     show_target_temp();
                  }
                  else {
                     if (overshoot > 10) { overshoot = overshoot - 10; }
                     else overshoot = 0;
                     show_overshoot();
                  }
                  Delay_ms(200);
                  //;stop the counter from rolling over
               button_press_count = 5;
               }
               if (button_press_count < 5) {
                  if (a==0) {
                     if (target_temp > 1) {Target_temp = target_temp - 1;}
                     else target_temp = 0;
                     show_target_temp();
                  }
                  if (a==1) {
                     if (overshoot > 1) {overshoot = overshoot - 1;}
                     else overshoot = 0;
                     show_overshoot();
                  }
               }
            state = return_state;
            }
         }
         /*
         if (button_ok == 0) {
            Delay_ms(50); //;simple debounce
            while (button_ok == 0) {Delay_ms(50);} //;wait for button to be released
            if (a == 0) {
               b = target_temp;     // Load target temp into write file
               eeprom_write (2,b); //;write the new target temp to eeprom
            }
            if (a == 1) {
               b = overshoot;      // Load target temp into write file
               eeprom_write (4,b); //;write the new overshoot value to eeprom
            }
            state = 0;
         } */
         break;
      }
 
   }
}

 

All 3 parts work when tested but cant have all 3 in my code at once otherwise it seems the 'Switch' statement is broken (simulator reports out of code) on the action of 'Break' at the completion of 'Case 0' or the first case executed.
It should be impossible to achieve a similar effect as long as the C compiler is doing his job correctly. I would check for basic problems like out of code or variable memory or stack overflow. I presume it's no trivial problem like exceeding the mikroC demo version code size? In any case, the code failure can be traced in assembly listing and simulator or hardware debugger.
 

No problem compiling much larger code in other projects, I've traced where code fails in the simulator to the first completion 'case 0' within switch, it completes the stuff within the case then on exiting it calls an address out of memory (doesn't exist within code). There's nothing that should cause an overflow etc that i'm aware of. Just strange how editing out part of another case allows the code to run fine. Traced same instructions back in asm file and they appear fine don't call any unknown address so it may be a simulator error. Will do some hardware test now and report back.
 

I'm not sure how MikroC deals with 'state' changing in the middle of a switch() statement that uses it as a parameter. You might be 'falling through' the whole switch statement by making 'state' a valid value for the next case: check.

If that is what happens, you need to advance the 'state' value outside the switch statement so the value is only used once.

Brian.
 

I just tested changing 'state' within the middle of a case and everything executes fine before and after and exits fine so pretty sure its not that. I had considered that and tried to only change value of 'state' at the end right before 'break'ing the case.
 

By C language specification, a switch statement causes a jump to the respective label. The expression is evaluated once and only once.
 
  • Like
Reactions: ghead

    ghead

    Points: 2
    Helpful Answer Positive Rating
Aha found the problem just not sure how to deal with it. I get this warning now with everything enabled,
37 1511 IRP bit must be set manually for indirect access to 'arrayFlow' variable Temp Controller.c

So to fix do i need to set IRP bit and select right bank before trying to access 'arrayFlow' then after unset IRP bit?

- - - Updated - - -

Like this maybe? can't find much else i can understand


Code C - [expand]
1
2
3
4
5
6
7
8
void show_overshoot(){
     Lcd_cmd(_LCD_CLEAR); //Clear display
     Lcd_out (1,1,"Overshoot:");
     STATUS.B7 = 1;
     IntToStr(overshoot, arrayFlow);
     Lcd_out_cp(arrayFlow);
     STATUS.B7 = 0;
}

 

Yup found that and fixed problem by changing some variable types to take up less ram, Though did get it to work but with messed up lcd display(only displaying half the data and in the wrong place) by putting 'arrayFlow' on bank2 register.
Next problem is multiplying or dividing a value and returning and displaying fixed-point decimal value on lcd display while dealing with this lack of ram. Much learning :)
Any pointers most welcome.
 

I am not sure about your micro controller. But if it is constant memory and you have flash memory, then place the data in flash.
 

One 'pointer' is that you may be trying to do too much with an old and fairly small MCU. Microchip recommend that you move from the PIC16F877A to the PIC16F18877A but there are also many more devices that would do. It all depends on whether you have other projects that you want to do in the future.
If this is a commercial project then a pin-for-pin replacement might be in order (I suspect but don't know that the PIC16F18877A is suitable in this regard). If this is a personal learning project then perhaps an Explorer 8 Board (or even an Explorer 16/32 if you are really adventurous). These have on-board programmers, LCD displays, interchangeable MCUs (they call them PIMs or Plug In Modules) so you can learn about microcontrollers without worrying too much about the hardware building. You can also add your own peripherals for project s such as this one.
Susan
 
  • Like
Reactions: ghead

    ghead

    Points: 2
    Helpful Answer Positive Rating
I am only using PIC16F887A because I have another project (reflow oven controller) based on it so had a few spare and its doing similar job here as in reflow project just much less program going so its more about learning and building something (I enjoy the hardware side more usually) than having the exact tool for the job :) Much prefer building my own tools then get to learn along the way. I have looked at similar boards to Explorer 8 board maybe my next investment. Thanks for all the pointers.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top