[PIC] Help! PIC16F887+MikroC

Status
Not open for further replies.

01287534730

Newbie level 2
Joined
Dec 4, 2014
Messages
2
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Location
HÃ* Ná»™i, Vietnam
Visit site
Activity points
81
Thank you so much for your attention,
I am having a project to control speed of the dc motor using PID algorithm. I have finished my interface software but when building the code for PIC16f887 in MikroC, it cannot be successful with the "Not enough RAM for call stack" alert. I don't know how to solve it as I have just learnt to write code for microcontroller and hope that someone can help me.
Thank you again!
Here is my 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
//Ma lenh
#define cm_ON      0x01//BAT DONG CO
#define cm_OFF     0x02//TAT DONG CO
#define cm_FORWARD 0X03//QUAY THUAN
#define cm_REVERSE 0X04//QUAY NGUOC
#define cm_KP      0X05//THAY DOI KP
#define cm_KI      0X06//THAY DOI KI
#define cm_KD      0X07//THAY DOI KD
#define cm_SET     0X08//THAY DOI TOC DO DAT
#define cm_GET     0X09//LENH GOI TOC DO VE PC
#define cm_NAK     0xFF//ma lenh NAK
#define dir        portb.b1 //chieu quay dong co
//------------------------------------------------------------------------------
//Bien toan cuc
long int pulse,temp_pulse;//,duty;
char duty;
long int pv_speed,set_point;
float output,pre_out;// bien toc do
float pPart,iPart,dPart,Kd,Kp,Ki,pre_Err,Err,pre_speed;//cac bien trong ham PID
//long int output;
bit PID_flat;
//#difine speed2pwm_duty   255/2400;
#define inv_sampling 50 // 50Hz
#define sampling_time 20 //20ms thoi gian ngat timer 1
char txt[12];
char i_main;
//bien du lieu usart
bit tx_frame_flag;//co du lieu can phat
bit rx_frame_flag;//co du lieu vua nhan duoc
char rx_char;//character nhan duoc
char rx_array[5]={0,0,0,0,0};//luu khung du lieu nhan duoc
void inte_init();
void process_motor_pid(long int des_speed);
void EUSART_Init();//Khoi tao i/o khoi tao che do bat do
void transmit_byte(char n);//truyen mot byte ra cong noi tiep
void  tmr1_init();//Khoi tao timer1
//void tmr2_init();
//------------------------------------------------------------------------------
//Chuong trinh ngat
//------------------------------------------------------------------------------
void interrupt(){
static char rx_index=0;
static char alarm_cnt=0;
static unsigned int i=0;
static unsigned int k=0;
if(INTCON.INTF){
          INTCON.INTF=0;
          ++pulse;
     }
else if (PIR1.RCIF){//nhan du lieu noi tiep
     rx_char = RCREG;//doc du lieu ra bien tam
     //nhan du lieu EUSEART
           if (rx_char==cm_NAK){//neu la NAK nghia la ket thuc du lieu nhan
               rx_index = 0;//chuan bi nhan lenh tiep theo
               rx_frame_flag = 1;//bat co bao vua nhan frame
               }
           else {//nhan du lieu
                 rx_array[rx_index]=rx_char;
                 if (rx_index>=5) rx_index=0; else ++rx_index;// neu cau lenh khong ket thuc bang cm_NAK thì bo qua
                }
          }
else if(PIR1.TMR1IF){
         PIR1.TMR1IF=0;
         //T1CON.TMR1ON=0;
         temp_pulse=pulse;
         pulse=0;
         pv_speed=(temp_pulse*15)/2.0;
         //process_motor_pid(pv_speed);
         PID_flat=1;
         TMR1H=0X9E;//20ms
         TMR1L=0X57;
         portd.b1=~portd.b1;
         //T1CON.TMR1ON=1;
 
         };
 
 }
//------------------------------------------------------------------------------
void main() {
//-----------------------------------------------------------------------------
     ANSEL= 0;// tat tat ca analog la ngo digital i/o
     ANSELH=0;
     porta=0x00;trisa=0x00;
     portb=0x00;trisb=0x03;
     portc=0x00;trisc=0x80;//RX ngo vao,TX ngo ra
     portd=0x00;trisd=0x00;
     porte=0x00;trise=0x00;
     EUSART_Init();
     pwm1_init(5000);
     //duty=10;
    pulse = 0;
      tmr1_init();
     inte_init() ;
     set_point=0;
     //den bao khoi dong xong
     portd=0xff;
     delay_ms(2000);
     portd=0;
     Kp=0;
     Kd=0;
     Ki=0;
     iPart=pPart=dPart=0;
     PID_flat=0;
     pv_speed=0;
     output=0;
     pre_out=0;
//------------------------------------------------------------------------------
     while (1){
     //PWM1_Set_Duty(duty);
     // kiemr tra co ngat timer1, tinh PID
      if (PID_flat) {
        process_motor_pid(pv_speed);
         PID_flat=0;
         }
     //dieu khien dong co
       if (rx_frame_flag){
          if (rx_array[0]==cm_ON){//ON ?
             //BAT DONG CO
             pwm1_start();
             }
          else {
               if (rx_array[0]==cm_OFF){//OFF ?
                  //TAT DONG CO
                  pwm1_stop();
                  output=pre_out=0;// bien toc do
                  pPart=iPart=dPart=pre_speed=0;//cac bien trong ham PID
                  duty=0;
                  }
               else if (rx_array[0]==cm_FORWARD){//QUAY THUAN?
                       //QUAY THUAN
                       //transmit_byte('f');
                       portb.b1 = 0;
                       }
                    else if (rx_array[0]==cm_REVERSE){//QUAY NGHICH
                            //QUAY NGHICH
                            //transmit_byte('r');
                            portb.b1 = 1;
                            }
                         else if (rx_array[0]==cm_GET){//GOI TOC DO
                                 //GOI TOC DO VE PC
                                 longtostr(pv_speed,txt);
                                 transmit_byte(cm_GET);
                                 if (dir == 1)transmit_byte('+'); else transmit_byte('-');
                                 transmit_byte(txt[7]);
                                 transmit_byte(txt[8]);
                                 transmit_byte(txt[9]);
                                 transmit_byte(txt[10]);
                                 transmit_byte(txt[11]);
                                 }
                              else if (rx_array[0]==cm_SET){//DAT TOC DO MOI
                                       output=pre_out=0;// bien toc do
                                       pPart=iPart=dPart=pre_speed=0;//cac bien trong ham PID
 
                                       set_point = (rx_array[1]*1000)+(rx_array[2]*100)+(rx_array[3]*10)+(rx_array[4]);
 
                                       }
                                   else if (rx_array[0]==cm_KP){//DAT KP
 
                                           //dat lai KP;
                                           Kp = (rx_array[1]*100)+(rx_array[2]*10)+(rx_array[3]);
                                           Kp=Kp/100.0;
                                            }
                                        else if (rx_array[0]==cm_KI){//DAT KI
                                                //dat lai KI;
                                               Ki = (rx_array[1]*100)+(rx_array[2]*10)+(rx_array[3]);
                                               Ki=Ki/100.0;
                                                }
                                             else if (rx_array[0]==cm_KD){//DAT KD
                                                     //dat lai KD;
                                                     Kd = (rx_array[1]*100)+(rx_array[2]*10)+(rx_array[3]);
                                                     Kd = Kd / 100.0;
                                                     }
               }//else
       rx_frame_flag=0;//xoa co bao co du lieu
       }//end rx_frame_flag
     }//end while
}//end main
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//SUBroutines:
void tmr2_init(){//Khoi tao timer 2
  T2CON = 0;//tat timer2, pre =1:1; post=1:1
  TMR2 = 0;
  PR2 = 249;//5ms
  T2CON = 0b01110001;//post=15, off, pres=4
  PIR1.TMR2IF=0;//xoa ngat
  PIE1.TMR2IE=1;//cho ngat tmr2
  INTCON.PEIE = 1;//cho phep ngat ngoai vi
  INTCON.GIE=1;
  T2CON.TMR2ON=1;
  }
//------------------------------------------------------------------------------
void  tmr1_init(){//Khoi tao timer1
  T1CON = 0;//chon che do cho tmr1, prescaler 1:1, clock internal,stop
  PIR1.TMR1IF = 0;//xoa co ngat
  PIE1.TMR1IE = 0;//cam ngat timer1
  T1CON.T1CKPS1=1;
  T1CON.T1CKPS0=0;
  TMR1H = 0x9E;//dat gia tri timr1
  TMR1L = 0x57;//20ms
  PIE1.TMR1IE=1;//cho phep ngat timer1
  INTCON.PEIE = 1;//cho phep ngat ngoai vi
  T1CON.TMR1ON = 1;//bat lai timer1
  INTCON.GIE  = 1;
  }
//
//Chuong trinh EUSART
//------------------------------------------------------------------------------
void EUSART_Init(){//Khoi tao i/o khoi tao che do bat do
  BAUDCTL.BRG16=1;//high speed
  TXSTA.BRGH = 1;//Chon che do toc do cao baud 16bit: Fosc/[4(n+1)]
  SPBRGH = 0x02;//0x01
  SPBRG = 0x08;//0x37//Toc do 9600; (9638bps)
  TXSTA.SYNC = 0;//Che do bat dong bo
  RCSTA.SPEN = 1;//Configure tu dong chan TX/RX thanh ngo ra/ngo vao bat chap TRISC
  TXSTA.TX9 = 0;//phat 8bit, khong phat dia chi !!!!!!!!!!!!!!!!!!!!!!!!
  RCSTA.RX9 = 0;//Tat che do nhan 9bit
  RCSTA.ADDEN = 0;//Address autodetectin disable
  //BAUDCTL.ABDEN = 1;//Autodetection Baudrate
  TXSTA.TXEN = 1;//Bat bo phat
  RCSTA.CREN = 1;//Bat bo thu UART
  PIE1.RCIE = 1;//Cho phep ngat nhan du lieu
  INTCON.PEIE = 1;//Cho phep ngat ngoai vi
  INTCON.GIE = 1;//Cho phep ngat toan cuc
  delay_ms(100);//cho de module on dinh
  }
 
//------------------------------------------------------------------------------
void transmit_byte(char n){//truyen mot byte ra cong noi tiep
     while (!PIR1.TXIF);
     TXREG=n;
     }
 
//------------------------------------------------------------------------------
void process_motor_pid(long int des_speed){//ham xu li PID
     Err=des_speed-set_point;
     //pre_speed=des_speed;
     pPart=(Kp*Err);
     dPart=(Kd*(Err-pre_Err)*inv_sampling);
     iPart+=Ki*(Err+pre_Err)*0.01;
     output=Pre_out+pPart+dPart+iPart;
     pre_Err=Err;
     pre_out=output;
     duty =(unsigned char)(output*0.0643);
     //saturation
     if (duty >=255)duty =254 ;
     else if (duty <=0)duty=0;
     PWM1_Set_Duty(duty);
     }
                                                                                       t
void inte_init(){//khai bao ngat ngoai
     INTCON.INTF=0;
     OPTION_REG.B7=0;//cho phep keo len PortB
     OPTION_REG.B6=1;//ngat canh len
     WPUB.B0=1;  //keo len PortB0
     WPUB.B1=1; //keo len PortB1
     INTCON.INTE=1;
     INTCON.PEIE = 1;//Cho phep ngat ngoai vi
     INTCON.GIE = 1;//Cho phep ngat toan cuc
   }

 
Last edited by a moderator:

This part is causing the problem. Zip and post you complete mikroC project files so that it can be modified a little and make it work.


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
if (rx_frame_flag){
          if (rx_array[0]==cm_ON){//ON ?
             //BAT DONG CO
             pwm1_start();
             }
          else {
               if (rx_array[0]==cm_OFF){//OFF ?
                  //TAT DONG CO
                  pwm1_stop();
                  output=pre_out=0;// bien toc do
                  pPart=iPart=dPart=pre_speed=0;//cac bien trong ham PID
                  duty=0;
                  }
               else if (rx_array[0]==cm_FORWARD){//QUAY THUAN?
                       //QUAY THUAN
                       //transmit_byte('f');
                       portb.b1 = 0;
                       }
                    else if (rx_array[0]==cm_REVERSE){//QUAY NGHICH
                            //QUAY NGHICH
                            //transmit_byte('r');
                            portb.b1 = 1;
                            }
                         else if (rx_array[0]==cm_GET){//GOI TOC DO
                                 //GOI TOC DO VE PC
                                 longtostr(pv_speed,txt);
                                 transmit_byte(cm_GET);
                                 if (dir == 1)transmit_byte('+'); else transmit_byte('-');
                                 transmit_byte(txt[7]);
                                 transmit_byte(txt[8]);
                                 transmit_byte(txt[9]);
                                 transmit_byte(txt[10]);
                                 transmit_byte(txt[11]);
                                 }
                              else if (rx_array[0]==cm_SET){//DAT TOC DO MOI
                                       output=pre_out=0;// bien toc do
                                       pPart=iPart=dPart=pre_speed=0;//cac bien trong ham PID
 
                                       set_point = (rx_array[1]*1000)+(rx_array[2]*100)+(rx_array[3]*10)+(rx_array[4]);
 
                                       }
                                   else if (rx_array[0]==cm_KP){//DAT KP
 
                                           //dat lai KP;
                                           Kp = (rx_array[1]*100)+(rx_array[2]*10)+(rx_array[3]);
                                           Kp=Kp/100.0;
                                            }
                                        else if (rx_array[0]==cm_KI){//DAT KI
                                                //dat lai KI;
                                               Ki = (rx_array[1]*100)+(rx_array[2]*10)+(rx_array[3]);
                                               Ki=Ki/100.0;
                                                }
                                             else if (rx_array[0]==cm_KD){//DAT KD
                                                     //dat lai KD;
                                                     Kd = (rx_array[1]*100)+(rx_array[2]*10)+(rx_array[3]);
                                                     Kd = Kd / 100.0;
                                                     }
               }//else
       rx_frame_flag=0;//xoa co bao co du lieu
       }//end rx_frame_flag
     }//end while

 

Without looking at the assembly listing or stack contents I would guess your problem is simply that you have exceeded the maximum number of nested calls you are allowed for that device. Each call requires stack space to hold the return address so if the compiled code makes too many calls without returning first, all the stack space is used up. Some compilers switch to using a software stack which overcomes the hardware limitiation but at the expense of running slower and needing more program space.

You can often work around the problem by rearranging instructions so fewer nested calls occur.

Brian.
 
It is an error with internal __Lib_MathDouble.c library that work with float values. I think it is too much float calculations for 356 bytes RAM of this MCU.
 

Hi guys,
Thank you so much for your advices I removed my old version of MikroC and install the 6.4 version and this alert disappeared but i still get one other with "finished(with errors)". Consequently, I couldn't have my HEX file.
 

You might be getting "demo limit" error. It means the code size exceeds 2KB demo limit. So, buy Compiler or use XC8 Lite version from Microchip with MPLAB X IDE.
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…